- 
                Notifications
    
You must be signed in to change notification settings  - Fork 13.9k
 
Closed
Labels
A-diagnosticsArea: Messages for errors, warnings, and lintsArea: Messages for errors, warnings, and lintsD-incorrectDiagnostics: A diagnostic that is giving misleading or incorrect information.Diagnostics: A diagnostic that is giving misleading or incorrect information.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.
Description
Code
#![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
Labels
A-diagnosticsArea: Messages for errors, warnings, and lintsArea: Messages for errors, warnings, and lintsD-incorrectDiagnostics: A diagnostic that is giving misleading or incorrect information.Diagnostics: A diagnostic that is giving misleading or incorrect information.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.