diff options
| author | Rémy Rakic <remy.rakic@gmail.com> | 2019-01-26 20:25:36 +0100 |
|---|---|---|
| committer | Rémy Rakic <remy.rakic@gmail.com> | 2019-01-27 10:52:45 +0100 |
| commit | 489bc4a2c6ec47eb35dc066247e11f335b278333 (patch) | |
| tree | 99d718a35e3ef113f0905033ebe1f1e748f2a4c3 | |
| parent | 1730ad4d1cbb703be970f8494ec349bf2c38e3f4 (diff) | |
| download | rust-489bc4a2c6ec47eb35dc066247e11f335b278333.tar.gz rust-489bc4a2c6ec47eb35dc066247e11f335b278333.zip | |
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.
8 files changed, 81 insertions, 44 deletions
diff --git a/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs b/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs index a0ce250d7e9..391539b77bc 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs @@ -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 )); } diff --git a/src/test/ui/associated-types/associated-types-eq-hr.stderr b/src/test/ui/associated-types/associated-types-eq-hr.stderr index 0e471a78d9e..5a074fe3457 100644 --- a/src/test/ui/associated-types/associated-types-eq-hr.stderr +++ b/src/test/ui/associated-types/associated-types-eq-hr.stderr @@ -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 diff --git a/src/test/ui/hrtb/hrtb-cache-issue-54302.stderr b/src/test/ui/hrtb/hrtb-cache-issue-54302.stderr index 1aa0a7ca32b..d0bcebeac4f 100644 --- a/src/test/ui/hrtb/hrtb-cache-issue-54302.stderr +++ b/src/test/ui/hrtb/hrtb-cache-issue-54302.stderr @@ -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 diff --git a/src/test/ui/hrtb/hrtb-conflate-regions.stderr b/src/test/ui/hrtb/hrtb-conflate-regions.stderr index 4c4f7979880..aa91314b350 100644 --- a/src/test/ui/hrtb/hrtb-conflate-regions.stderr +++ b/src/test/ui/hrtb/hrtb-conflate-regions.stderr @@ -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 diff --git a/src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.stderr b/src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.stderr index 916a524939b..91b5db6cd66 100644 --- a/src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.stderr +++ b/src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.stderr @@ -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 diff --git a/src/test/ui/hrtb/hrtb-just-for-static.stderr b/src/test/ui/hrtb/hrtb-just-for-static.stderr index bd6e3dbebd2..24edcd91076 100644 --- a/src/test/ui/hrtb/hrtb-just-for-static.stderr +++ b/src/test/ui/hrtb/hrtb-just-for-static.stderr @@ -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 diff --git a/src/test/ui/hrtb/hrtb-perfect-forwarding.stderr b/src/test/ui/hrtb/hrtb-perfect-forwarding.stderr index 8b71a8a800e..a87fa6d3012 100644 --- a/src/test/ui/hrtb/hrtb-perfect-forwarding.stderr +++ b/src/test/ui/hrtb/hrtb-perfect-forwarding.stderr @@ -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 diff --git a/src/test/ui/issues/issue-54302.stderr b/src/test/ui/issues/issue-54302.stderr index ddf0414faf6..442d32eb9f1 100644 --- a/src/test/ui/issues/issue-54302.stderr +++ b/src/test/ui/issues/issue-54302.stderr @@ -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 |
