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

anonymous constants are overly restrictive wrt variance #90629

Closed
lcnr opened this issue Nov 5, 2021 · 3 comments
Closed

anonymous constants are overly restrictive wrt variance #90629

lcnr opened this issue Nov 5, 2021 · 3 comments
Labels
A-const-generics Area: const generics (parameters and arguments) A-variance Area: Variance (https://doc.rust-lang.org/nomicon/subtyping.html) C-bug Category: This is a bug. F-generic_const_exprs `#![feature(generic_const_exprs)]`

Comments

@lcnr
Copy link
Contributor

lcnr commented Nov 5, 2021

cc #89829 (comment)

this currently causes an error as 'a is considered invariant because it is used in an anonymous constant.

#![feature(generic_const_exprs)]
struct Foo<'a>([&'a u32; std::mem::size_of::<&'a u32>()]);
fn covariant<'a>(v: &'a Foo<'static>) -> &'a Foo<'a> {
    v //~ERROR mismatched types
}

This shouldn't actually be needed for std::mem::size_of as it doesn't care about variance.

Once stuff like the following causes an error (instead of a future imcompat lint, cc #56105), subtyping should not be able to influence const eval, so we could allow lifetimes used in constants to remain bivariant. It is not clear that we should do that, as this restriction on subtyping is definitely not obvious or even necessarily desirable.

trait SadBee {
    const ASSOC: usize;
}
// fn(&'static ())` is a supertype of `for<'a> fn(&'a ())` while
// we allow two different impls for these types, leading
// to different const eval results.
impl SadBee for for<'a> fn(&'a ()) {
    const ASSOC: usize = 0;
}
impl SadBee for fn(&'static ()) {
    const ASSOC: usize = 100;
}
@lcnr lcnr added C-bug Category: This is a bug. A-const-generics Area: const generics (parameters and arguments) F-generic_const_exprs `#![feature(generic_const_exprs)]` labels Nov 5, 2021
@BGR360
Copy link
Contributor

BGR360 commented Dec 27, 2021

@rustbot label +A-variance

@rustbot rustbot added the A-variance Area: Variance (https://doc.rust-lang.org/nomicon/subtyping.html) label Dec 27, 2021
@QuineDot
Copy link

The current plan as I understand it is for these to continue to be allowed:

impl SadBee for for<'a> fn(&'a ()) {
    const ASSOC: usize = 0;
}
// This `impl` is more generic than your but still covers fn(`&'static ()`)
// (and any other `fn(&'concrete_lifetime U)`)
impl<T> SadBee for fn(T) {
    const ASSOC: usize = 100;
}

But I'm unsure if that's a problem for you or not.

@lcnr
Copy link
Contributor Author

lcnr commented May 30, 2022

yeah, subtyping also impacts TypeId, so we won't be able to just use bivariance once TypeId::of is const. We can still allow variance by looking into the constant, e.g. for

struct UsesRef<'a> {
    actual_ref: &'a (),
    in_anon_const: [u8; std::mem::size_of::<&'a ()>()],
}

but that requires a bunch of additional design so I will only track that in rust-lang/project-const-generics#32

Thanks for reminding me that this issue exists 😅

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-const-generics Area: const generics (parameters and arguments) A-variance Area: Variance (https://doc.rust-lang.org/nomicon/subtyping.html) C-bug Category: This is a bug. F-generic_const_exprs `#![feature(generic_const_exprs)]`
Projects
None yet
Development

No branches or pull requests

4 participants