Closed
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.