Skip to content

Cannot borrow from generic Copy types in a const context #120119

Closed
@kupiakos

Description

@kupiakos

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

No one assigned

    Labels

    A-const-evalArea: Constant evaluation, covers all const contexts (static, const fn, ...)C-bugCategory: This is a bug.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-langRelevant to the language team

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions