Open
Description
I was going to leave this as a remark on #80384, but you're apparently supposed to make separate issues instead of leaving comments on tracking issues, so here goes:
I was just playing around and couldn't even get past this simple code before getting yelled at:
const fn foo<T, const N: usize>(values: [T; N]) -> [T; N] {
let slice = values.as_slice();
let len = slice.len();
values
}
Both as_slice()
and len()
are declared as const fn
, so you'd think they'd be fine to use in another const fn
, but no:
error[E0658]: cannot borrow here, since the borrowed element may contain interior mutability
--> src/lib.rs:2:17
|
2 | let slice = values.as_slice();
| ^^^^^^^^^^^^^^^^^
|
= note: see issue #80384 <https://github.com/rust-lang/rust/issues/80384> for more information
I don't even understand what this is trying to tell me. Issue #80384, which is the one linked, does not at all explain the source/cause of this error. I'm not working with UnsafeCell
or interior mutability here. I'm attempting to make a &[T]
from a [T; N]
.
Metadata
Metadata
Assignees
Labels
Type
Projects
Milestone
Relationships
Development
No branches or pull requests
Activity
asquared31415 commentedon Oct 2, 2023
Consider the following code:
your code would then have
T = UnsafeCell<u32>
, then make a&[UnsafeCell<u32>]
which is rejected because that could potentially be used as interior mutability, which is rejected inconst
.ilyvion commentedon Oct 3, 2023
If
UnsafeCell
can't be used inconst
, why are some of its methodsconst fn
s? This all seems like a rather bad series of choices.Cerber-Ursi commentedon Oct 3, 2023
UnsafeCell
can't be used inconst
, but can be (indirectly, with someSync
wrapper, likeMutex
) used instatic
:And
static
initializers can't call non-const
functions.workingjubilee commentedon Oct 4, 2023
We actually intend to make mutability in const fn possible, and that will probably include
UnsafeCell<T>
(eventually). This is (mostly) theconst_mut_ref
feature.ilyvion commentedon Oct 4, 2023
I don't suppose it'd be possible for the compiler to detect the presence of
UnsafeCell
in the specific monomorphization ofT
inconst fn foo<T, const N: usize>(values: [T; N]) -> [T; N]
rather than just blanket disallow usage of all generics/mutability inconst
?For instance,
compiles just fine while
does not -- clearly the compiler knows that
String
doesn't have interior mutability and thatFoo
does; couldn't this same "test" be done on a per-T
basis rather than as on a blanket for-all-T
basis?workingjubilee commentedon Oct 4, 2023
What you are describing (sometimes called a "post-monomorphization error") is both absurdly controversial (Rust allows them to happen, but it's still controversial in terms of API design), and also will become unnecessary the moment
const_mut_refs
stabilizes, so, uh,Probably not?
ilyvion commentedon Oct 4, 2023
Not to put too fine a point on it, but "when feature X stabilizes" in Rust can mean "by the next version" or "in over a decade," so that doesn't mean much and could leave a huge class of useful generic const functions unwritable for a very long time for the sake of making something unnecessary later.
But if it's basically a policy (or at least the uncontroversial approach) that it's better to error out on the basis of "any given
T
can violate something" rather than on the basis of "a specificT
can violate something," there's not much to do about it I suppose.workingjubilee commentedon Oct 4, 2023
Oh, I agree. I'm basically always pushing for more const stuff reaching anywhere near stable precisely because of things like this. There's... currently a lot of "huge class(es) of useful generic const functions (that are) unwritable".
I think the hardest problem here is that even if you PRed the changes necessary to the compiler to make this happen, you'd mostly be trying to convince all the people who are trying to fix the exact problems to simply make this work take a look at your code which may make their work take longer as they now have to work around it as well.
Also it would prooobably be another feature with gating, and probably work to test and stabilize it even if accepted, not just a "hey let's do this" and then in it goes into 1.75? So!