Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
kupiakos opened this issue Jan 19, 2024 · 3 comments
Closed

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

kupiakos opened this issue Jan 19, 2024 · 3 comments
Labels
A-const-eval Area: constant evaluation (mir interpretation) C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-lang Relevant to the language team, which will review and decide on the PR/issue.

Comments

@kupiakos
Copy link
Contributor

kupiakos commented Jan 19, 2024

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)
@kupiakos kupiakos added the C-bug Category: This is a bug. label Jan 19, 2024
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Jan 19, 2024
@jieyouxu jieyouxu added the T-lang Relevant to the language team, which will review and decide on the PR/issue. label Feb 16, 2024
@fmease fmease added A-const-eval Area: constant evaluation (mir interpretation) T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. and removed needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels Mar 1, 2024
@fmease
Copy link
Member

fmease commented Mar 1, 2024

cc #121675, #121840

@oli-obk
Copy link
Contributor

oli-obk commented Mar 1, 2024

Duplicate of #60715

@oli-obk oli-obk marked this as a duplicate of #60715 Mar 1, 2024
@oli-obk oli-obk closed this as completed Mar 1, 2024
@RalfJung
Copy link
Member

Copy is an imperfect analog for a lack of interior mutability

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 have Freeze + Copy types.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-const-eval Area: constant evaluation (mir interpretation) C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-lang Relevant to the language team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

6 participants