When mentioning lifetimes, put either the trait ref or the self type closer to the lifetimes

When mentioning lifetimes, only invert wording between the expected trait and the self type when the self type has the vid.
This way, the lifetimes always stay close to the self type or trait ref that actually contains them.
This commit is contained in:
Rémy Rakic 2019-01-26 20:25:36 +01:00
parent 1730ad4d1c
commit 489bc4a2c6
8 changed files with 81 additions and 44 deletions

View file

@ -251,10 +251,16 @@ impl NiceRegionError<'me, 'gcx, 'tcx> {
}
});
let self_ty_has_vid = self
let actual_self_ty_has_vid = self
.tcx()
.any_free_region_meets(&actual_trait_ref.self_ty(), |r| Some(r) == vid);
let expected_self_ty_has_vid = self
.tcx()
.any_free_region_meets(&expected_trait_ref.self_ty(), |r| Some(r) == vid);
let self_ty_has_vid = actual_self_ty_has_vid || expected_self_ty_has_vid;
debug!(
"try_report_placeholders_trait: actual_has_vid={:?}",
actual_has_vid
@ -266,8 +272,12 @@ impl NiceRegionError<'me, 'gcx, 'tcx> {
debug!("try_report_placeholders_trait: has_sub={:?}", has_sub);
debug!("try_report_placeholders_trait: has_sup={:?}", has_sup);
debug!(
"try_report_placeholders_trait: self_ty_has_vid={:?}",
self_ty_has_vid
"try_report_placeholders_trait: actual_self_ty_has_vid={:?}",
actual_self_ty_has_vid
);
debug!(
"try_report_placeholders_trait: expected_self_ty_has_vid={:?}",
expected_self_ty_has_vid
);
// The weird thing here with the `maybe_highlighting_region` calls and the
@ -289,23 +299,43 @@ impl NiceRegionError<'me, 'gcx, 'tcx> {
RegionHighlightMode::maybe_highlighting_region(sup_placeholder, has_sup, || {
match (has_sub, has_sup) {
(Some(n1), Some(n2)) => {
err.note(&format!(
"`{}` would have to be implemented for the type `{}`, \
for any two lifetimes `'{}` and `'{}`",
expected_trait_ref,
expected_trait_ref.self_ty(),
std::cmp::min(n1, n2),
std::cmp::max(n1, n2),
));
if self_ty_has_vid {
err.note(&format!(
"`{}` would have to be implemented for the type `{}`, \
for any two lifetimes `'{}` and `'{}`",
expected_trait_ref,
expected_trait_ref.self_ty(),
std::cmp::min(n1, n2),
std::cmp::max(n1, n2),
));
} else {
err.note(&format!(
"`{}` must implement `{}`, \
for any two lifetimes `'{}` and `'{}`",
expected_trait_ref.self_ty(),
expected_trait_ref,
std::cmp::min(n1, n2),
std::cmp::max(n1, n2),
));
}
}
(Some(n), _) | (_, Some(n)) => {
err.note(&format!(
"`{}` would have to be implemented for the type `{}`, \
for any lifetime `'{}`",
expected_trait_ref,
expected_trait_ref.self_ty(),
n,
));
if self_ty_has_vid {
err.note(&format!(
"`{}` would have to be implemented for the type `{}`, \
for any lifetime `'{}`",
expected_trait_ref,
expected_trait_ref.self_ty(),
n,
));
} else {
err.note(&format!(
"`{}` must implement `{}`, for any lifetime `'{}`",
expected_trait_ref.self_ty(),
expected_trait_ref,
n,
));
}
}
(None, None) => RegionHighlightMode::maybe_highlighting_region(
vid,
@ -320,11 +350,19 @@ impl NiceRegionError<'me, 'gcx, 'tcx> {
n,
));
} else {
err.note(&format!(
"`{}` would have to be implemented for the type `{}`",
expected_trait_ref,
expected_trait_ref.self_ty(),
));
if self_ty_has_vid {
err.note(&format!(
"`{}` would have to be implemented for the type `{}`",
expected_trait_ref,
expected_trait_ref.self_ty(),
));
} else {
err.note(&format!(
"`{}` must implement `{}`",
expected_trait_ref.self_ty(),
expected_trait_ref,
));
}
}
},
),
@ -347,10 +385,9 @@ impl NiceRegionError<'me, 'gcx, 'tcx> {
));
} else {
err.note(&format!(
"but `{}` is actually implemented for the type `{}`, \
for some lifetime `'{}`",
actual_trait_ref,
"but `{}` actually implements `{}`, for some lifetime `'{}`",
actual_trait_ref.self_ty(),
actual_trait_ref,
n
));
}

View file

@ -41,8 +41,8 @@ LL | tuple_one::<Tuple>();
| ^^^^^^^^^^^^^^^^^^
|
= note: Due to a where-clause on `tuple_one`,
= note: `TheTrait<(&'0 isize, &'1 isize)>` would have to be implemented for the type `Tuple`, for any two lifetimes `'0` and `'1`
= note: but `TheTrait<(&'2 isize, &'2 isize)>` is actually implemented for the type `Tuple`, for some lifetime `'2`
= note: `Tuple` must implement `TheTrait<(&'0 isize, &'1 isize)>`, for any two lifetimes `'0` and `'1`
= note: but `Tuple` actually implements `TheTrait<(&'2 isize, &'2 isize)>`, for some lifetime `'2`
error: implementation of `TheTrait` is not general enough
--> $DIR/associated-types-eq-hr.rs:96:5
@ -51,8 +51,8 @@ LL | tuple_two::<Tuple>();
| ^^^^^^^^^^^^^^^^^^
|
= note: Due to a where-clause on `tuple_two`,
= note: `TheTrait<(&'0 isize, &'1 isize)>` would have to be implemented for the type `Tuple`, for any two lifetimes `'0` and `'1`
= note: but `TheTrait<(&'2 isize, &'2 isize)>` is actually implemented for the type `Tuple`, for some lifetime `'2`
= note: `Tuple` must implement `TheTrait<(&'0 isize, &'1 isize)>`, for any two lifetimes `'0` and `'1`
= note: but `Tuple` actually implements `TheTrait<(&'2 isize, &'2 isize)>`, for some lifetime `'2`
error: implementation of `TheTrait` is not general enough
--> $DIR/associated-types-eq-hr.rs:105:5
@ -61,8 +61,8 @@ LL | tuple_four::<Tuple>();
| ^^^^^^^^^^^^^^^^^^^
|
= note: Due to a where-clause on `tuple_four`,
= note: `TheTrait<(&'0 isize, &'1 isize)>` would have to be implemented for the type `Tuple`, for any two lifetimes `'0` and `'1`
= note: but `TheTrait<(&'2 isize, &'2 isize)>` is actually implemented for the type `Tuple`, for some lifetime `'2`
= note: `Tuple` must implement `TheTrait<(&'0 isize, &'1 isize)>`, for any two lifetimes `'0` and `'1`
= note: but `Tuple` actually implements `TheTrait<(&'2 isize, &'2 isize)>`, for some lifetime `'2`
error: aborting due to 5 previous errors

View file

@ -4,8 +4,8 @@ error: implementation of `Deserialize` is not general enough
LL | assert_deserialize_owned::<&'static str>(); //~ ERROR
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `Deserialize<'0>` would have to be implemented for the type `&'static str`, for any lifetime `'0`
= note: but `Deserialize<'1>` is actually implemented for the type `&str`, for some lifetime `'1`
= note: `&'static str` must implement `Deserialize<'0>`, for any lifetime `'0`
= note: but `&str` actually implements `Deserialize<'1>`, for some lifetime `'1`
error: aborting due to previous error

View file

@ -5,8 +5,8 @@ LL | fn b() { want_foo2::<SomeStruct>(); } //~ ERROR
| ^^^^^^^^^^^^^^^^^^^^^^^
|
= note: Due to a where-clause on `want_foo2`,
= note: `Foo<(&'0 isize, &'1 isize)>` would have to be implemented for the type `SomeStruct`, for any two lifetimes `'0` and `'1`
= note: but `Foo<(&'2 isize, &'2 isize)>` is actually implemented for the type `SomeStruct`, for some lifetime `'2`
= note: `SomeStruct` must implement `Foo<(&'0 isize, &'1 isize)>`, for any two lifetimes `'0` and `'1`
= note: but `SomeStruct` actually implements `Foo<(&'2 isize, &'2 isize)>`, for some lifetime `'2`
error: aborting due to previous error

View file

@ -5,8 +5,8 @@ LL | foo::<()>(); //~ ERROR not general enough
| ^^^^^^^^^
|
= note: Due to a where-clause on `foo`,
= note: `Trait<for<'b> fn(std::cell::Cell<&'b u32>)>` would have to be implemented for the type `()`
= note: but `Trait<fn(std::cell::Cell<&'0 u32>)>` is actually implemented for the type `()`, for some lifetime `'0`
= note: `()` must implement `Trait<for<'b> fn(std::cell::Cell<&'b u32>)>`
= note: but `()` actually implements `Trait<fn(std::cell::Cell<&'0 u32>)>`, for some lifetime `'0`
error: aborting due to previous error

View file

@ -5,8 +5,8 @@ LL | want_hrtb::<StaticInt>() //~ ERROR
| ^^^^^^^^^^^^^^^^^^^^^^
|
= note: Due to a where-clause on `want_hrtb`,
= note: `Foo<&'0 isize>` would have to be implemented for the type `StaticInt`, for any lifetime `'0`
= note: but `Foo<&'1 isize>` is actually implemented for the type `StaticInt`, for some lifetime `'1`
= note: `StaticInt` must implement `Foo<&'0 isize>`, for any lifetime `'0`
= note: but `StaticInt` actually implements `Foo<&'1 isize>`, for some lifetime `'1`
error: implementation of `Foo` is not general enough
--> $DIR/hrtb-just-for-static.rs:30:5

View file

@ -5,8 +5,8 @@ LL | foo_hrtb_bar_not(&mut t); //~ ERROR not general enough
| ^^^^^^^^^^^^^^^^
|
= note: Due to a where-clause on `foo_hrtb_bar_not`,
= note: `Foo<&'0 isize>` would have to be implemented for the type `&mut T`, for any lifetime `'0`
= note: but `Foo<&'1 isize>` is actually implemented for the type `&mut T`, for some lifetime `'1`
= note: `&mut T` must implement `Foo<&'0 isize>`, for any lifetime `'0`
= note: but `&mut T` actually implements `Foo<&'1 isize>`, for some lifetime `'1`
error: aborting due to previous error

View file

@ -4,8 +4,8 @@ error: implementation of `Deserialize` is not general enough
LL | assert_deserialize_owned::<&'static str>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `Deserialize<'0>` would have to be implemented for the type `&'static str`, for any lifetime `'0`
= note: but `Deserialize<'1>` is actually implemented for the type `&str`, for some lifetime `'1`
= note: `&'static str` must implement `Deserialize<'0>`, for any lifetime `'0`
= note: but `&str` actually implements `Deserialize<'1>`, for some lifetime `'1`
error: aborting due to previous error