Closed
Description
I tried this code:
trait C: Copy + 'static {
type Val: Copy + 'static;
const VAL: Self::Val;
const S: Self;
}
#[derive(Clone, Copy)]
struct FooGen<T: C>(T);
impl<T: C> FooGen<T> {
const VAL: &'static Self = &FooGen(T::S);
}
struct FooAssoc<T: C>(T::Val);
impl<T: C> Clone for FooAssoc<T> { fn clone(&self) -> Self { *self } }
impl<T: C> Copy for FooAssoc<T> {}
impl<T: C> FooAssoc<T> {
const VAL: &'static Self = &FooAssoc(T::VAL);
}
I expected the Copy
bounds to be sufficient to allow this to compile. Copy
is an imperfect analog for a lack of interior mutability, much like it is an imperfect analog for !Drop
.
Instead, this happened:
error[E0492]: constants cannot refer to interior mutable data
--> src/lib.rs:10:32
|
10 | const VAL: &'static Self = &FooGen(T::S);
| ^^^^^^^^^^^^^ this borrow of an interior mutable value may end up in the final value
error[E0492]: constants cannot refer to interior mutable data
--> src/lib.rs:21:32
|
21 | const VAL: &'static Self = &FooAssoc(T::VAL);
| ^^^^^^^^^^^^^^^^^ this borrow of an interior mutable value may end up in the final value
Ideally, stable code would be able to bound on a lack of interior mutability (like a NoCell
/Freeze
trait) to allow this sort of generic code to work without needing const_refs_to_cell
stabilized, as it's a useful property to be able to bound on for unsafe
code.
Meta
1.7.0-stable (2023-12-21 82e1608)
Metadata
Metadata
Assignees
Labels
Type
Projects
Milestone
Relationships
Development
No branches or pull requests
Activity
fmease commentedon Mar 1, 2024
cc #121675, #121840
oli-obk commentedon Mar 1, 2024
Duplicate of #60715
std::marker::Freeze
pub again #60715RalfJung commentedon Jun 17, 2024
It is not, and anyone relying on this is risking breakage in future versions of Rust. It is quite probable that we will eventually allow people to do something like
unsafe impl Copy for
, at which point one can easily haveFreeze + Copy
types.