From 7b9ddbdcf261c0010b24f53281bf2f27d02eb6f2 Mon Sep 17 00:00:00 2001 From: rhysd Date: Fri, 8 Oct 2021 01:00:15 +0900 Subject: [PATCH 1/2] Show detailed expected/found types in error message when trait paths are the same --- .../src/infer/error_reporting/mod.rs | 14 ++++++- src/test/ui/error-codes/E0308-2.stderr | 4 +- .../ui/issues/issue-20831-debruijn.stderr | 4 +- src/test/ui/issues/issue-65230.rs | 19 ++++++++++ src/test/ui/issues/issue-65230.stderr | 38 +++++++++++++++++++ src/test/ui/nll/issue-50716.stderr | 4 +- ...ance-contravariant-self-trait-match.stderr | 8 ++-- ...variance-covariant-self-trait-match.stderr | 8 ++-- ...variance-invariant-self-trait-match.stderr | 8 ++-- 9 files changed, 87 insertions(+), 20 deletions(-) create mode 100644 src/test/ui/issues/issue-65230.rs create mode 100644 src/test/ui/issues/issue-65230.stderr diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index c44d4361f037..056709cd314d 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -2060,14 +2060,24 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { expected: exp_found.expected.print_only_trait_path(), found: exp_found.found.print_only_trait_path(), }; - self.expected_found_str(pretty_exp_found) + match self.expected_found_str(pretty_exp_found) { + Some((expected, found)) if expected == found => { + self.expected_found_str(exp_found) + } + ret => ret, + } } infer::PolyTraitRefs(exp_found) => { let pretty_exp_found = ty::error::ExpectedFound { expected: exp_found.expected.print_only_trait_path(), found: exp_found.found.print_only_trait_path(), }; - self.expected_found_str(pretty_exp_found) + match self.expected_found_str(pretty_exp_found) { + Some((expected, found)) if expected == found => { + self.expected_found_str(exp_found) + } + ret => ret, + } } } } diff --git a/src/test/ui/error-codes/E0308-2.stderr b/src/test/ui/error-codes/E0308-2.stderr index 47fea5a23a78..0ac03195fa34 100644 --- a/src/test/ui/error-codes/E0308-2.stderr +++ b/src/test/ui/error-codes/E0308-2.stderr @@ -4,8 +4,8 @@ error[E0308]: mismatched types LL | impl Eq for &dyn DynEq {} | ^^ lifetime mismatch | - = note: expected trait `PartialEq` - found trait `PartialEq` + = note: expected trait `<&dyn DynEq as PartialEq>` + found trait `<&(dyn DynEq + 'static) as PartialEq>` note: the lifetime `'_` as defined on the impl at 9:13... --> $DIR/E0308-2.rs:9:13 | diff --git a/src/test/ui/issues/issue-20831-debruijn.stderr b/src/test/ui/issues/issue-20831-debruijn.stderr index 03e3311e0f39..02c80c294082 100644 --- a/src/test/ui/issues/issue-20831-debruijn.stderr +++ b/src/test/ui/issues/issue-20831-debruijn.stderr @@ -19,8 +19,8 @@ note: ...so that the types are compatible | LL | fn subscribe(&mut self, t : Box::Output> + 'a>) { | ^^^^^^^^^ - = note: expected `Publisher<'_>` - found `Publisher<'_>` + = note: expected ` as Publisher<'_>>` + found ` as Publisher<'_>>` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-65230.rs b/src/test/ui/issues/issue-65230.rs new file mode 100644 index 000000000000..10d9e8109969 --- /dev/null +++ b/src/test/ui/issues/issue-65230.rs @@ -0,0 +1,19 @@ +trait T { + type U; + fn f(&self) -> Self::U; +} + +struct X<'a>(&'a mut i32); + +impl<'a> T for X<'a> { + type U = &'a i32; + fn f(&self) -> Self::U { + self.0 + } + //~^^^ ERROR cannot infer an appropriate lifetime for lifetime parameter `'a` + // + // Return type of `f` has lifetime `'a` but it tries to return `self.0` which + // has lifetime `'_`. +} + +fn main() {} diff --git a/src/test/ui/issues/issue-65230.stderr b/src/test/ui/issues/issue-65230.stderr new file mode 100644 index 000000000000..21e3f6b1ebb9 --- /dev/null +++ b/src/test/ui/issues/issue-65230.stderr @@ -0,0 +1,38 @@ +error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements + --> $DIR/issue-65230.rs:10:28 + | +LL | fn f(&self) -> Self::U { + | ____________________________^ +LL | | self.0 +LL | | } + | |_____^ + | +note: first, the lifetime cannot outlive the anonymous lifetime defined on the method body at 10:10... + --> $DIR/issue-65230.rs:10:10 + | +LL | fn f(&self) -> Self::U { + | ^^^^^ +note: ...so that reference does not outlive borrowed content + --> $DIR/issue-65230.rs:11:9 + | +LL | self.0 + | ^^^^^^ +note: but, the lifetime must be valid for the lifetime `'a` as defined on the impl at 8:6... + --> $DIR/issue-65230.rs:8:6 + | +LL | impl<'a> T for X<'a> { + | ^^ +note: ...so that the types are compatible + --> $DIR/issue-65230.rs:10:28 + | +LL | fn f(&self) -> Self::U { + | ____________________________^ +LL | | self.0 +LL | | } + | |_____^ + = note: expected ` as T>` + found ` as T>` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0495`. diff --git a/src/test/ui/nll/issue-50716.stderr b/src/test/ui/nll/issue-50716.stderr index 3dee3345db64..4e69dda8721d 100644 --- a/src/test/ui/nll/issue-50716.stderr +++ b/src/test/ui/nll/issue-50716.stderr @@ -4,8 +4,8 @@ error[E0308]: mismatched types LL | let _x = *s; | ^^ lifetime mismatch | - = note: expected type `Sized` - found type `Sized` + = note: expected type `<<&'a T as A>::X as Sized>` + found type `<<&'static T as A>::X as Sized>` note: the lifetime `'a` as defined on the function body at 9:8... --> $DIR/issue-50716.rs:9:8 | diff --git a/src/test/ui/variance/variance-contravariant-self-trait-match.stderr b/src/test/ui/variance/variance-contravariant-self-trait-match.stderr index e35aec4c0ce2..9455162732b7 100644 --- a/src/test/ui/variance/variance-contravariant-self-trait-match.stderr +++ b/src/test/ui/variance/variance-contravariant-self-trait-match.stderr @@ -4,8 +4,8 @@ error[E0308]: mismatched types LL | impls_get::<&'min G>(); | ^^^^^^^^^^^^^^^^^^^^ lifetime mismatch | - = note: expected type `Get` - found type `Get` + = note: expected type `<&'min G as Get>` + found type `<&'max G as Get>` note: the lifetime `'min` as defined on the function body at 10:21... --> $DIR/variance-contravariant-self-trait-match.rs:10:21 | @@ -23,8 +23,8 @@ error[E0308]: mismatched types LL | impls_get::<&'max G>(); | ^^^^^^^^^^^^^^^^^^^^ lifetime mismatch | - = note: expected type `Get` - found type `Get` + = note: expected type `<&'max G as Get>` + found type `<&'min G as Get>` note: the lifetime `'min` as defined on the function body at 16:21... --> $DIR/variance-contravariant-self-trait-match.rs:16:21 | diff --git a/src/test/ui/variance/variance-covariant-self-trait-match.stderr b/src/test/ui/variance/variance-covariant-self-trait-match.stderr index a25d1044d425..3f3a69dde521 100644 --- a/src/test/ui/variance/variance-covariant-self-trait-match.stderr +++ b/src/test/ui/variance/variance-covariant-self-trait-match.stderr @@ -4,8 +4,8 @@ error[E0308]: mismatched types LL | impls_get::<&'min G>(); | ^^^^^^^^^^^^^^^^^^^^ lifetime mismatch | - = note: expected type `Get` - found type `Get` + = note: expected type `<&'min G as Get>` + found type `<&'max G as Get>` note: the lifetime `'min` as defined on the function body at 10:21... --> $DIR/variance-covariant-self-trait-match.rs:10:21 | @@ -23,8 +23,8 @@ error[E0308]: mismatched types LL | impls_get::<&'max G>(); | ^^^^^^^^^^^^^^^^^^^^ lifetime mismatch | - = note: expected type `Get` - found type `Get` + = note: expected type `<&'max G as Get>` + found type `<&'min G as Get>` note: the lifetime `'min` as defined on the function body at 17:21... --> $DIR/variance-covariant-self-trait-match.rs:17:21 | diff --git a/src/test/ui/variance/variance-invariant-self-trait-match.stderr b/src/test/ui/variance/variance-invariant-self-trait-match.stderr index 4a1d4d28b480..a80a5e41d031 100644 --- a/src/test/ui/variance/variance-invariant-self-trait-match.stderr +++ b/src/test/ui/variance/variance-invariant-self-trait-match.stderr @@ -4,8 +4,8 @@ error[E0308]: mismatched types LL | impls_get::<&'min G>(); | ^^^^^^^^^^^^^^^^^^^^ lifetime mismatch | - = note: expected type `Get` - found type `Get` + = note: expected type `<&'min G as Get>` + found type `<&'max G as Get>` note: the lifetime `'min` as defined on the function body at 7:21... --> $DIR/variance-invariant-self-trait-match.rs:7:21 | @@ -23,8 +23,8 @@ error[E0308]: mismatched types LL | impls_get::<&'max G>(); | ^^^^^^^^^^^^^^^^^^^^ lifetime mismatch | - = note: expected type `Get` - found type `Get` + = note: expected type `<&'max G as Get>` + found type `<&'min G as Get>` note: the lifetime `'min` as defined on the function body at 13:21... --> $DIR/variance-invariant-self-trait-match.rs:13:21 | From 9211beef087b1c87bb0335cac0c3b0676af7f54a Mon Sep 17 00:00:00 2001 From: rhysd Date: Sun, 10 Oct 2021 00:23:35 +0900 Subject: [PATCH 2/2] Use E0308 instead of E0495 for checking the error message improvement because previous test does not cause the expected error message when `-Z borrowck=mir`. --- src/test/ui/issues/issue-65230.rs | 22 +++++--------- src/test/ui/issues/issue-65230.stderr | 44 ++++++++------------------- 2 files changed, 19 insertions(+), 47 deletions(-) diff --git a/src/test/ui/issues/issue-65230.rs b/src/test/ui/issues/issue-65230.rs index 10d9e8109969..54141d2214cd 100644 --- a/src/test/ui/issues/issue-65230.rs +++ b/src/test/ui/issues/issue-65230.rs @@ -1,19 +1,11 @@ -trait T { - type U; - fn f(&self) -> Self::U; -} +trait T0 {} +trait T1: T0 {} -struct X<'a>(&'a mut i32); +trait T2 {} -impl<'a> T for X<'a> { - type U = &'a i32; - fn f(&self) -> Self::U { - self.0 - } - //~^^^ ERROR cannot infer an appropriate lifetime for lifetime parameter `'a` - // - // Return type of `f` has lifetime `'a` but it tries to return `self.0` which - // has lifetime `'_`. -} +impl<'a> T0 for &'a (dyn T2 + 'static) {} + +impl T1 for &dyn T2 {} +//~^ ERROR mismatched types fn main() {} diff --git a/src/test/ui/issues/issue-65230.stderr b/src/test/ui/issues/issue-65230.stderr index 21e3f6b1ebb9..d75428f3d531 100644 --- a/src/test/ui/issues/issue-65230.stderr +++ b/src/test/ui/issues/issue-65230.stderr @@ -1,38 +1,18 @@ -error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements - --> $DIR/issue-65230.rs:10:28 - | -LL | fn f(&self) -> Self::U { - | ____________________________^ -LL | | self.0 -LL | | } - | |_____^ - | -note: first, the lifetime cannot outlive the anonymous lifetime defined on the method body at 10:10... - --> $DIR/issue-65230.rs:10:10 - | -LL | fn f(&self) -> Self::U { - | ^^^^^ -note: ...so that reference does not outlive borrowed content - --> $DIR/issue-65230.rs:11:9 - | -LL | self.0 - | ^^^^^^ -note: but, the lifetime must be valid for the lifetime `'a` as defined on the impl at 8:6... +error[E0308]: mismatched types --> $DIR/issue-65230.rs:8:6 | -LL | impl<'a> T for X<'a> { - | ^^ -note: ...so that the types are compatible - --> $DIR/issue-65230.rs:10:28 +LL | impl T1 for &dyn T2 {} + | ^^ lifetime mismatch + | + = note: expected trait `<&dyn T2 as T0>` + found trait `<&(dyn T2 + 'static) as T0>` +note: the lifetime `'_` as defined on the impl at 8:13... + --> $DIR/issue-65230.rs:8:13 | -LL | fn f(&self) -> Self::U { - | ____________________________^ -LL | | self.0 -LL | | } - | |_____^ - = note: expected ` as T>` - found ` as T>` +LL | impl T1 for &dyn T2 {} + | ^ + = note: ...does not necessarily outlive the static lifetime error: aborting due to previous error -For more information about this error, try `rustc --explain E0495`. +For more information about this error, try `rustc --explain E0308`.