Inference disrupted by trait bound that is redundant with a HRTB

4d69ee8
Opened by David Tolnay at 2024-12-21 05:02:43

This compiles:

trait Trait<'a> {}

struct S<T>(T);

impl<'a, T> Trait<'a> for S<T> where T: for<'b> Trait<'b> {}

fn main() {}

This following does not. It seems like the impl already has T: for<'b> Trait<'b> so adding T: Trait<'a> should not affect the behavior.

trait Trait<'a> {}

struct S<T>(T);

// Added T: Trait<'a>
impl<'a, T> Trait<'a> for S<T> where T: for<'b> Trait<'b>, T: Trait<'a> {}

fn main() {}
error[E0283]: type annotations required: cannot resolve `T: Trait<'a>`
 --> src/main.rs:6:1
  |
6 | impl<'a, T> Trait<'a> for S<T> where T: for<'b> Trait<'b>, T: Trait<'a> {}
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |
  = note: required by `Trait`

This currently affects the following and many people have run into it. The workaround is to remove the bound (https://github.com/Manishearth/rust-clippy/issues/1689).

#[derive(Deserialize)]
struct S<T: serde::de::DeserializeOwned>(T);
  1. This compiles:

    trait Trait<'a> {}
    
    struct S<T>(T);
    
    impl<'a, T> Trait<'a> for S<T> where T: for<'b> Trait<'b> {}
    
    fn main() {}
    

    This following does not. It seems like the impl already has T: for<'b> Trait<'b> so adding T: Trait<'a> should not affect the behavior.

    trait Trait<'a> {}
    
    struct S<T>(T);
    
    // Added T: Trait<'a>
    impl<'a, T> Trait<'a> for S<T> where T: for<'b> Trait<'b>, T: Trait<'a> {}
    
    fn main() {}
    
    error[E0283]: type annotations required: cannot resolve `T: Trait<'a>`
     --> src/main.rs:6:1
      |
    6 | impl<'a, T> Trait<'a> for S<T> where T: for<'b> Trait<'b>, T: Trait<'a> {}
      | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      |
      = note: required by `Trait`
    

    This currently affects the following and many people have run into it. The workaround is to remove the bound (https://github.com/rust-lang/rust-clippy/issues/1689).

    #[derive(Deserialize)]
    struct S<T: serde::de::DeserializeOwned>(T);
    

    David Tolnay at 2020-06-07 01:35:38

  2. cc @nikomatsakis @eddyb @arielb1

    Aaron Turon at 2017-05-04 05:10:39

  3. This may be a consequence of #21974.

    David Tolnay at 2017-05-04 06:53:36

  4. add search keywords: higher ranked lifetime bound

    jethrogb at 2017-09-20 01:01:12

  5. If this is unlikely to be fixed soon, can we at least make the error message better? It's unclear what type annotations could be added and where, and as @dtolnay writes, the fix is actually to be less restrictive.

    jethrogb at 2017-09-20 01:06:07