Skip to content

Variance should perhaps take into account 'static bounds. #59875

@eddyb

Description

@eddyb

For example, when trying to build something resembling a pointer w/ optional metadata:

struct Ptr<T: ?Sized + Pointee> {
    addr: usize,
    meta: T::Meta,
}

trait Pointee {
    type Meta: 'static + Copy;
}
impl<T> Pointee for T {
    type Meta = ();
}
impl<T> Pointee for [T] {
    type Meta = usize;
}

Ptr<T> ends up invariant over T even though lifetimes in T cannot possibly affect T::Meta (which has a 'static bound), and that results in errors like these:

error[E0308]: mismatched types
  --> src/lib.rs:16:56
   |
16 | fn covariant<'a>(p: Ptr<&'static ()>) -> Ptr<&'a ()> { p }
   |                                                        ^ lifetime mismatch
   |
   = note: expected type `Ptr<&'a ()>`
              found type `Ptr<&'static ()>`
note: the lifetime 'a as defined on the function body at 16:14...
  --> src/lib.rs:16:14
   |
16 | fn covariant<'a>(p: Ptr<&'static ()>) -> Ptr<&'a ()> { p }
   |              ^^
   = note: ...does not necessarily outlive the static lifetime

cc @rust-lang/wg-traits

Metadata

Metadata

Assignees

No one assigned

    Labels

    T-langRelevant to the language team

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions