about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2021-07-20 10:56:08 +0000
committerbors <bors@rust-lang.org>2021-07-20 10:56:08 +0000
commitda7d405357600a76f2b93b8aa41fe5ee5da7885d (patch)
tree9763cf30603b2489abef4a9fefe570465c287b29 /src
parent718d53b0cb7dde93499cb92950d60b412f5a3d05 (diff)
parentae024919845a44473c22b8c3f1dfa075c9c5c75d (diff)
downloadrust-da7d405357600a76f2b93b8aa41fe5ee5da7885d.tar.gz
rust-da7d405357600a76f2b93b8aa41fe5ee5da7885d.zip
Auto merge of #87244 - jackh726:issue-71883, r=estebank
Better diagnostics with mismatched types due to implicit static lifetime

Fixes #78113

I think this is my first diagnostics PR...definitely happy to hear thoughts on the direction/implementation here.

I was originally just trying to solve the error above, where the lifetime on a GAT was causing a cryptic "mismatched types" error. But as I was writing this, I realized that this (unintentionally) also applied to a different case: `wf-in-foreign-fn-decls-issue-80468.rs`. I'm not sure if this diagnostic should get a new error code, or even reuse an existing one. And, there might be some ways to make this even more generalized. Also, the error is a bit more lengthy and verbose than probably needed. So thoughts there are welcome too.

This PR essentially ended up adding a new nice region error pass that triggers if a type doesn't match the self type of an impl which is selected because of a predicate because of an implicit static bound on that self type.

r? `@estebank`
Diffstat (limited to 'src')
-rw-r--r--src/test/ui/async-await/async-fn-path-elision.stderr2
-rw-r--r--src/test/ui/generic-associated-types/issue-78113-lifetime-mismatch-dyn-trait-box.rs40
-rw-r--r--src/test/ui/generic-associated-types/issue-78113-lifetime-mismatch-dyn-trait-box.stderr87
-rw-r--r--src/test/ui/impl-header-lifetime-elision/path-elided.stderr2
-rw-r--r--src/test/ui/impl-header-lifetime-elision/trait-elided.stderr2
-rw-r--r--src/test/ui/issues/issue-10412.stderr2
-rw-r--r--src/test/ui/wf/wf-in-foreign-fn-decls-issue-80468.rs2
-rw-r--r--src/test/ui/wf/wf-in-foreign-fn-decls-issue-80468.stderr20
8 files changed, 150 insertions, 7 deletions
diff --git a/src/test/ui/async-await/async-fn-path-elision.stderr b/src/test/ui/async-await/async-fn-path-elision.stderr
index 9694742200e..36fb73a8dde 100644
--- a/src/test/ui/async-await/async-fn-path-elision.stderr
+++ b/src/test/ui/async-await/async-fn-path-elision.stderr
@@ -3,6 +3,8 @@ error[E0726]: implicit elided lifetime not allowed here
    |
 LL | async fn error(lt: HasLifetime) {
    |                    ^^^^^^^^^^^- help: indicate the anonymous lifetime: `<'_>`
+   |
+   = note: assuming a `'static` lifetime...
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/generic-associated-types/issue-78113-lifetime-mismatch-dyn-trait-box.rs b/src/test/ui/generic-associated-types/issue-78113-lifetime-mismatch-dyn-trait-box.rs
new file mode 100644
index 00000000000..850d83be684
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-78113-lifetime-mismatch-dyn-trait-box.rs
@@ -0,0 +1,40 @@
+// Test for diagnostics when we have mismatched lifetime due to implict 'static lifetime in GATs
+
+// check-fail
+
+#![feature(generic_associated_types)]
+
+pub trait A {}
+impl A for &dyn A {}
+impl A for Box<dyn A> {}
+
+pub trait B {
+    type T<'a>: A;
+}
+
+impl B for () {
+    // `'a` doesn't match implicit `'static`: suggest `'_`
+    type T<'a> = Box<dyn A + 'a>; //~ incompatible lifetime on type
+}
+
+trait C {}
+impl C for Box<dyn A + 'static> {}
+pub trait D {
+    type T<'a>: C;
+}
+impl D for () {
+    // `'a` doesn't match explicit `'static`: we *should* suggest removing `'static`
+    type T<'a> = Box<dyn A + 'a>; //~ incompatible lifetime on type
+}
+
+trait E {}
+impl E for (Box<dyn A>, Box<dyn A>) {}
+pub trait F {
+    type T<'a>: E;
+}
+impl F for () {
+    // `'a` doesn't match explicit `'static`: suggest `'_`
+    type T<'a> = (Box<dyn A + 'a>, Box<dyn A + 'a>); //~ incompatible lifetime on type
+}
+
+fn main() {}
diff --git a/src/test/ui/generic-associated-types/issue-78113-lifetime-mismatch-dyn-trait-box.stderr b/src/test/ui/generic-associated-types/issue-78113-lifetime-mismatch-dyn-trait-box.stderr
new file mode 100644
index 00000000000..fedc6a341ca
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-78113-lifetime-mismatch-dyn-trait-box.stderr
@@ -0,0 +1,87 @@
+error: incompatible lifetime on type
+  --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:17:5
+   |
+LL |     type T<'a> = Box<dyn A + 'a>;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: because this has an unmet lifetime requirement
+  --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:12:17
+   |
+LL |     type T<'a>: A;
+   |                 ^ introduces a `'static` lifetime requirement
+note: the lifetime `'a` as defined on the associated item at 17:12...
+  --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:17:12
+   |
+LL |     type T<'a> = Box<dyn A + 'a>;
+   |            ^^
+   = note: ...does not necessarily outlive the static lifetime introduced by the compatible `impl`
+note: this has an implicit `'static` lifetime requirement
+  --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:9:20
+   |
+LL | impl A for Box<dyn A> {}
+   |                    ^
+help: consider relaxing the implicit `'static` requirement
+   |
+LL | impl A for Box<dyn A + '_> {}
+   |                      ^^^^
+
+error: incompatible lifetime on type
+  --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:27:5
+   |
+LL |     type T<'a> = Box<dyn A + 'a>;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: because this has an unmet lifetime requirement
+  --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:23:17
+   |
+LL |     type T<'a>: C;
+   |                 ^ introduces a `'static` lifetime requirement
+note: the lifetime `'a` as defined on the associated item at 27:12...
+  --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:27:12
+   |
+LL |     type T<'a> = Box<dyn A + 'a>;
+   |            ^^
+note: ...does not necessarily outlive the static lifetime introduced by the compatible `impl`
+  --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:21:1
+   |
+LL | impl C for Box<dyn A + 'static> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: incompatible lifetime on type
+  --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:37:5
+   |
+LL |     type T<'a> = (Box<dyn A + 'a>, Box<dyn A + 'a>);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: because this has an unmet lifetime requirement
+  --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:33:17
+   |
+LL |     type T<'a>: E;
+   |                 ^ introduces a `'static` lifetime requirement
+note: the lifetime `'a` as defined on the associated item at 37:12...
+  --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:37:12
+   |
+LL |     type T<'a> = (Box<dyn A + 'a>, Box<dyn A + 'a>);
+   |            ^^
+   = note: ...does not necessarily outlive the static lifetime introduced by the compatible `impl`
+note: this has an implicit `'static` lifetime requirement
+  --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:31:21
+   |
+LL | impl E for (Box<dyn A>, Box<dyn A>) {}
+   |                     ^
+note: this has an implicit `'static` lifetime requirement
+  --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:31:33
+   |
+LL | impl E for (Box<dyn A>, Box<dyn A>) {}
+   |                                 ^
+help: consider relaxing the implicit `'static` requirement
+   |
+LL | impl E for (Box<dyn A + '_>, Box<dyn A>) {}
+   |                       ^^^^
+help: consider relaxing the implicit `'static` requirement
+   |
+LL | impl E for (Box<dyn A>, Box<dyn A + '_>) {}
+   |                                   ^^^^
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/impl-header-lifetime-elision/path-elided.stderr b/src/test/ui/impl-header-lifetime-elision/path-elided.stderr
index 6500a2a55f6..1c81c696201 100644
--- a/src/test/ui/impl-header-lifetime-elision/path-elided.stderr
+++ b/src/test/ui/impl-header-lifetime-elision/path-elided.stderr
@@ -3,6 +3,8 @@ error[E0726]: implicit elided lifetime not allowed here
    |
 LL | impl MyTrait for Foo {
    |                  ^^^- help: indicate the anonymous lifetime: `<'_>`
+   |
+   = note: assuming a `'static` lifetime...
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/impl-header-lifetime-elision/trait-elided.stderr b/src/test/ui/impl-header-lifetime-elision/trait-elided.stderr
index ad97cb0abd6..735f01379f0 100644
--- a/src/test/ui/impl-header-lifetime-elision/trait-elided.stderr
+++ b/src/test/ui/impl-header-lifetime-elision/trait-elided.stderr
@@ -3,6 +3,8 @@ error[E0726]: implicit elided lifetime not allowed here
    |
 LL | impl MyTrait for u32 {
    |      ^^^^^^^- help: indicate the anonymous lifetime: `<'_>`
+   |
+   = note: assuming a `'static` lifetime...
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-10412.stderr b/src/test/ui/issues/issue-10412.stderr
index 2a6e2414593..9d181eab7fb 100644
--- a/src/test/ui/issues/issue-10412.stderr
+++ b/src/test/ui/issues/issue-10412.stderr
@@ -45,6 +45,8 @@ error[E0726]: implicit elided lifetime not allowed here
    |
 LL | impl<'self> Serializable<str> for &'self str {
    |             ^^^^^^^^^^^^^^^^^ help: indicate the anonymous lifetime: `Serializable<'_, str>`
+   |
+   = note: assuming a `'static` lifetime...
 
 error[E0277]: the size for values of type `str` cannot be known at compilation time
   --> $DIR/issue-10412.rs:6:13
diff --git a/src/test/ui/wf/wf-in-foreign-fn-decls-issue-80468.rs b/src/test/ui/wf/wf-in-foreign-fn-decls-issue-80468.rs
index 8386959cfb3..4fcf8f403bb 100644
--- a/src/test/ui/wf/wf-in-foreign-fn-decls-issue-80468.rs
+++ b/src/test/ui/wf/wf-in-foreign-fn-decls-issue-80468.rs
@@ -13,5 +13,5 @@ pub struct Ref<'a>(&'a u8);
 impl Trait for Ref {} //~ ERROR:  implicit elided lifetime not allowed here
 
 extern "C" {
-    pub fn repro(_: Wrapper<Ref>); //~ ERROR: mismatched types
+    pub fn repro(_: Wrapper<Ref>); //~ ERROR: incompatible lifetime on type
 }
diff --git a/src/test/ui/wf/wf-in-foreign-fn-decls-issue-80468.stderr b/src/test/ui/wf/wf-in-foreign-fn-decls-issue-80468.stderr
index bb839d0a5ec..4e927cd983d 100644
--- a/src/test/ui/wf/wf-in-foreign-fn-decls-issue-80468.stderr
+++ b/src/test/ui/wf/wf-in-foreign-fn-decls-issue-80468.stderr
@@ -3,22 +3,30 @@ error[E0726]: implicit elided lifetime not allowed here
    |
 LL | impl Trait for Ref {}
    |                ^^^- help: indicate the anonymous lifetime: `<'_>`
+   |
+   = note: assuming a `'static` lifetime...
 
-error[E0308]: mismatched types
+error: incompatible lifetime on type
   --> $DIR/wf-in-foreign-fn-decls-issue-80468.rs:16:21
    |
 LL |     pub fn repro(_: Wrapper<Ref>);
-   |                     ^^^^^^^^^^^^ lifetime mismatch
+   |                     ^^^^^^^^^^^^
+   |
+note: because this has an unmet lifetime requirement
+  --> $DIR/wf-in-foreign-fn-decls-issue-80468.rs:8:23
    |
-   = note: expected trait `Trait`
-              found trait `Trait`
+LL | pub struct Wrapper<T: Trait>(T);
+   |                       ^^^^^ introduces a `'static` lifetime requirement
 note: the anonymous lifetime #1 defined on the method body at 16:5...
   --> $DIR/wf-in-foreign-fn-decls-issue-80468.rs:16:5
    |
 LL |     pub fn repro(_: Wrapper<Ref>);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: ...does not necessarily outlive the static lifetime
+note: ...does not necessarily outlive the static lifetime introduced by the compatible `impl`
+  --> $DIR/wf-in-foreign-fn-decls-issue-80468.rs:13:1
+   |
+LL | impl Trait for Ref {}
+   | ^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0308`.