Confusing error[E0492]: constants cannot refer to interior mutable data

See the following example code:

trait Trait1 {
    type AssociatedType: 'static;
    const VALUE: Self::AssociatedType;
}

trait Trait2 {
    type AssociatedType;
    const VALUE: Self::AssociatedType;
}

struct Struct<T>(core::marker::PhantomData<T>);

impl<T: Trait1> Trait2 for Struct<T> {
    type AssociatedType = &'static T::AssociatedType;
    const VALUE: &'static T::AssociatedType = &T::VALUE;
}

Compiling fails with

error[E0492]: constants cannot refer to interior mutable data
  --> src/lib.rs:18:41
   |
15 |     const VALUE: &'static T::AssociatedType = &T::VALUE;
   |                                               ^^^^^^^^^ this borrow of an interior mutable value may end up in the final value

I'm somewhat confused by that error message. I assume that the error is displayed since it is possible that T::AssociatedType has interior mutability.

If that's correct I was wondering if it is possible to restrict Trait1::AssociatedType to types without interior mutability to prevent this error.
Also, I think the error message could be a little more clear.

The linked error code has a good explanation. It's not only about interior mutability, but the combination of interior mutability and const.

I agree that the error message could be improved, but clarifying it is just one click away.

As for having bounds to signal the compiler that there should be no interior mutability, it seems that it's a no-no.

If you control the trait, make implementors of Trait1 provide the &'static Self::AssociatedType themselves.

I've read the linked error code, but as there are no types that have interior mutable in my example, in my opinion the error explanation is not particularly clarifying
(at least at first glance, until you come to the idea that the generic could of course have interior mutability). But maybe that's just me.

Thanks for linking the discussion, even though it is about a different use case.
However, there the compiler-internal Freeze trait is mentioned which seems to indicate that the type does not have interior mutability and - if it would be public - might be used to make my example compile..?

Yeah thank you, that is the solution i have come to as well.
Nevertheless I still wonder whether there are fundamental reasons that prevent the generic solution from working (maybe using an appropriate, yet to be implemented, trait).

I believe it would, but the lang team has officially declined making it public at least once already.

1 Like