Skip to content

Incorrect explicit_outlives_requirements error #119228

Closed
@Nadrieril

Description

@Nadrieril

Code

playground link

#![warn(explicit_outlives_requirements)]
pub trait TypeCx {
    type Ty;
}

pub struct Pat<Cx: TypeCx> {
    pub ty: Cx::Ty,
}

pub struct MyTypeContext<'thir, 'tcx: 'thir> {
    pub pat: Pat<MyTypeContext<'thir, 'tcx>>,
}

impl<'thir, 'tcx: 'thir> TypeCx for MyTypeContext<'thir, 'tcx> {
    type Ty = ();
}

Current output

warning: outlives requirements can be inferred
 --> compiler/rustc_pattern_analysis/src/lib.rs:9:37
  |
9 | pub struct MyTypeContext<'thir, 'tcx: 'thir> {
  |                                     ^^^^^^^ help: remove this bound
  |
  = note: `-W explicit-outlives-requirements` implied by `-W rust-2018-idioms`
  = help: to override `-W rust-2018-idioms` add `#[allow(explicit_outlives_requirements)]`

Desired output

This warning should not be emitted.

Rationale and extra context

If I remove the outlives bound like the warning suggests, I then get:

error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'tcx` due to conflicting requirements
  --> compiler/rustc_pattern_analysis/src/lib.rs:10:14
   |
10 |     pub pat: Pat<MyTypeContext<'thir, 'tcx>>,
   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
note: first, the lifetime cannot outlive the lifetime `'tcx` as defined here...
  --> compiler/rustc_pattern_analysis/src/lib.rs:9:33
   |
9  | pub struct MyTypeContext<'thir, 'tcx> {
   |                                 ^^^^
note: ...but the lifetime must also be valid for the lifetime `'thir` as defined here...
  --> compiler/rustc_pattern_analysis/src/lib.rs:9:26
   |
9  | pub struct MyTypeContext<'thir, 'tcx> {
   |                          ^^^^^
note: ...so that the types are compatible
  --> compiler/rustc_pattern_analysis/src/lib.rs:10:14
   |
10 |     pub pat: Pat<MyTypeContext<'thir, 'tcx>>,
   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   = note: expected `<MyTypeContext<'thir, 'tcx> as TypeCx>`
              found `<MyTypeContext<'_, '_> as TypeCx>`

For more information about this error, try `rustc --explain E0495`.

So the outlives bound not only couldn't be inferred, but was required.

Other cases

If I don't make MyTypeContext recursive, then the bound is not warned as inferrable. This compiles without warnings (playground):

#![warn(explicit_outlives_requirements)]
pub trait TypeCx {
    type Ty;
}

pub struct Pat<Cx: TypeCx> {
    pub ty: Cx::Ty,
}

pub struct MyTypeContext<'thir, 'tcx: 'thir> {
    pub tcx: &'tcx (),
    pub thir: &'thir (),
}

impl<'thir, 'tcx: 'thir> TypeCx for MyTypeContext<'thir, 'tcx> {
    type Ty = ();
}

pub struct OtherContext<'thir, 'tcx> {
    pub pat: Pat<MyTypeContext<'thir, 'tcx>>,
}

And weirdly OtherContext does not require 'tcx: 'thir to compile, whereas the recursive MyTypeContext did. I'm not sure what the correct behavior is but that seems inconsistent.

I just realized that this requires #![warn(explicit_outlives_requirements)] which is turned on when working on rustc but is actually allow-by-default for other rust users.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsD-incorrectDiagnostics: A diagnostic that is giving misleading or incorrect information.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions