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)