"Type annotations needed" with mixed lifetimes in trait bounds

747c96b
Opened by arcnmx at 2024-12-21 05:05:19

This was encountered from a derive plugin that created where bounds for all member types. Occurs on stable, beta, and nightly.

struct S<'a>(&'a ());

trait Tr { }
impl<T> Tr for Option<T> { }
impl<'a> Tr for S<'a> where Option<&'a str>: Tr, Option<&'static str>: Tr { }
error: mismatched types [--explain E0308]
 --> <anon>:5:1
  |>
5 |> impl<'a> Tr for S<'a> where Option<&'a str>: Tr, Option<&'static str>: Tr { }
  |> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime mismatch
note: expected type `Tr`
note:    found type `Tr`
note: the lifetime 'a as defined on the impl at 5:0...
 --> <anon>:5:1
  |>
5 |> impl<'a> Tr for S<'a> where Option<&'a str>: Tr, Option<&'static str>: Tr { }
  |> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...does not necessarily outlive the static lifetime

error: aborting due to previous error

playpen repro

  1. Doesn't repro anymore with the linked code.

    Esteban Kuber at 2018-03-19 06:17:18

  2. Error on latest stable:

    error[E0283]: type annotations required: cannot resolve `std::option::Option<&'a str>: Tr`
     --> src/main.rs:5:1
      |
    5 | impl<'a> Tr for S<'a> where Option<&'a str>: Tr, Option<&'static str>: Tr { }
      | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      |
    note: required by `Tr`
     --> src/main.rs:3:1
      |
    3 | trait Tr { }
      | ^^^^^^^^
    

    Jack Huey at 2019-08-08 15:37:52

  3. Minimal repro:

    trait Foo {}
    impl<'a, T> Foo for &'a T {}
    
    // we need `'a _` and `'static _` in the same
    // `where` bound afaict.
    struct Ctx<'a>(&'a ()) where
        &'a (): Foo,
        &'static (): Foo;
    

    While this is a quite rare edge case, the error is very unhelpful rn :sweat_smile:

    lcnr at 2020-04-26 08:01:11

  4. This behavior is still a bug, this code snippet should compile afaict.

    Removing either the &'a (): Foo or &'static (): Foo bound removes this error, so there is probably some weird interaction here.

    lcnr at 2020-05-07 19:46:52

  5. This only occurs if bounds have different lifetimes. Completely identical bounds work fine:

    trait Foo {}
    impl<'a, T> Foo for &'a T {}
    
    // we need `'a _` and `'static _` in the same
    // `where` bound afaict.
    struct Ctx<'a>(&'a ()) where
        &'a (): Foo,
        &'a (): Foo;
    

    lcnr at 2020-05-07 19:55:01

  6. @lcnr Ahh, I missed that!

    So, if someone fixes this issue, then please also tweak the test (I'll add a FIXME to it later if needed).

    Yuki Okushi at 2020-05-07 21:07:22

  7. Ran into this issue in https://github.com/rust-lang/rust/issues/77052

    Jonas Schievink at 2020-09-23 17:11:41

  8. I am retitling the issue to reflect the diagnostic from newer compilers.

    • 1.7.0 through 1.20: "mismatched types"
    • 1.21 through 1.27: no error (!?)
    • 1.28 through 1.39: "type annotations required"
    • 1.40 through present (1.68) : "type annotations needed"

    David Tolnay at 2023-03-27 17:10:08

  9. I think the examples here will be solved by the -Ztrait-solver=next stabilization[^1] (cases where the obligation is exactly equal to the param env candidate). The more general issue of param env candidates which are equal up to regions will require OR bounds for regions which I would like to add in the long term but that will still take a while.

    [^1]: depending on how we canonicalize regions

    lcnr at 2023-03-31 07:54:29