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`
This commit is contained in:
bors 2021-07-20 10:56:08 +00:00
commit da7d405357
16 changed files with 299 additions and 38 deletions

View file

@ -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

View file

@ -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() {}

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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
}

View file

@ -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: expected trait `Trait`
found trait `Trait`
note: because this has an unmet lifetime requirement
--> $DIR/wf-in-foreign-fn-decls-issue-80468.rs:8:23
|
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`.