Skip to content

Commit

Permalink
Detect when 'static obligation might come from an impl
Browse files Browse the repository at this point in the history
  • Loading branch information
estebank committed Jun 28, 2020
1 parent 2f517ce commit e6599ad
Show file tree
Hide file tree
Showing 13 changed files with 431 additions and 302 deletions.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ fn baz<'a,'b>(x: &'a u32, y: &'b u32) -> (&'a u32, &'b u32) {

#[cfg(transmute)] // one instantiations: BAD
fn baz<'a,'b>(x: &'a u32) -> &'static u32 {
bar(foo, x) //[transmute]~ ERROR E0495
bar(foo, x) //[transmute]~ ERROR E0759
}

#[cfg(krisskross)] // two instantiations, mixing and matching: BAD
Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,11 @@
error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
error[E0759]: cannot infer an appropriate lifetime
--> $DIR/project-fn-ret-contravariant.rs:38:8
|
LL | bar(foo, x)
| ^^^
|
note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 37:8...
--> $DIR/project-fn-ret-contravariant.rs:37:8
|
LL | fn baz<'a,'b>(x: &'a u32) -> &'static u32 {
| ^^
note: ...so that reference does not outlive borrowed content
--> $DIR/project-fn-ret-contravariant.rs:38:13
|
LL | bar(foo, x)
| ^
= note: but, the lifetime must be valid for the static lifetime...
note: ...so that reference does not outlive borrowed content
--> $DIR/project-fn-ret-contravariant.rs:38:4
|
| ------- this data with lifetime `'a`...
LL | bar(foo, x)
| ^^^^^^^^^^^
| ----^^^---- ...is captured and required to live as long as `'static` here

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 E0759`.
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ fn baz<'a, 'b>(x: Type<'a>) -> Type<'static> {
// Cannot instantiate `foo` with any lifetime other than `'a`,
// since it is provided as input.

bar(foo, x) //[transmute]~ ERROR E0495
bar(foo, x) //[transmute]~ ERROR E0759
}

#[cfg(krisskross)] // two instantiations, mixing and matching: BAD
Expand Down
Original file line number Diff line number Diff line change
@@ -1,30 +1,12 @@
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements
error[E0759]: cannot infer an appropriate lifetime
--> $DIR/project-fn-ret-invariant.rs:49:9
|
LL | bar(foo, x)
| ^^^
|
note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 45:8...
--> $DIR/project-fn-ret-invariant.rs:45:8
|
LL | fn baz<'a, 'b>(x: Type<'a>) -> Type<'static> {
| ^^
note: ...so that the expression is assignable
--> $DIR/project-fn-ret-invariant.rs:49:14
|
LL | bar(foo, x)
| ^
= note: expected `Type<'_>`
found `Type<'a>`
= note: but, the lifetime must be valid for the static lifetime...
note: ...so that the expression is assignable
--> $DIR/project-fn-ret-invariant.rs:49:5
|
| -------- this data with lifetime `'a`...
...
LL | bar(foo, x)
| ^^^^^^^^^^^
= note: expected `Type<'static>`
found `Type<'_>`
| ----^^^---- ...is captured and required to live as long as `'static` here

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 E0759`.
25 changes: 6 additions & 19 deletions src/test/ui/impl-header-lifetime-elision/dyn-trait.stderr
Original file line number Diff line number Diff line change
@@ -1,30 +1,17 @@
error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
error[E0759]: cannot infer an appropriate lifetime
--> $DIR/dyn-trait.rs:20:16
|
LL | static_val(x);
| ^
|
note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 19:26...
--> $DIR/dyn-trait.rs:19:26
|
LL | fn with_dyn_debug_static<'a>(x: Box<dyn Debug + 'a>) {
| ^^
note: ...so that the expression is assignable
--> $DIR/dyn-trait.rs:20:16
|
| ------------------- this data with lifetime `'a`...
LL | static_val(x);
| ^
= note: expected `std::boxed::Box<dyn std::fmt::Debug>`
found `std::boxed::Box<(dyn std::fmt::Debug + 'a)>`
= note: but, the lifetime must be valid for the static lifetime...
note: ...so that the types are compatible
| ^ ...is captured here...
|
note: ...and is required to live as long as `'static` here
--> $DIR/dyn-trait.rs:20:5
|
LL | static_val(x);
| ^^^^^^^^^^
= note: expected `StaticTrait`
found `StaticTrait`

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 E0759`.
Original file line number Diff line number Diff line change
@@ -1,28 +1,11 @@
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements
error[E0759]: cannot infer an appropriate lifetime
--> $DIR/constant-in-expr-inherent-1.rs:8:5
|
LL | <Foo<'a>>::C
| ^^^^^^^^^^^^
|
note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 7:8...
--> $DIR/constant-in-expr-inherent-1.rs:7:8
|
LL | fn foo<'a>(_: &'a u32) -> &'static u32 {
| ^^
note: ...so that the types are compatible
--> $DIR/constant-in-expr-inherent-1.rs:8:5
|
LL | <Foo<'a>>::C
| ^^^^^^^^^^^^
= note: expected `Foo<'_>`
found `Foo<'a>`
= note: but, the lifetime must be valid for the static lifetime...
note: ...so that reference does not outlive borrowed content
--> $DIR/constant-in-expr-inherent-1.rs:8:5
|
| ------- this data with lifetime `'a`...
LL | <Foo<'a>>::C
| ^^^^^^^^^^^^
| ^^^^^^^^^^^^ ...is captured and required to live as long as `'static` here

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 E0759`.
28 changes: 5 additions & 23 deletions src/test/ui/regions/regions-addr-of-self.stderr
Original file line number Diff line number Diff line change
@@ -1,29 +1,11 @@
error[E0495]: cannot infer an appropriate lifetime for borrow expression due to conflicting requirements
error[E0759]: cannot infer an appropriate lifetime
--> $DIR/regions-addr-of-self.rs:7:37
|
LL | pub fn chase_cat(&mut self) {
| --------- this data with an anonymous lifetime `'_`...
LL | let p: &'static mut usize = &mut self.cats_chased;
| ^^^^^^^^^^^^^^^^^^^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 6:5...
--> $DIR/regions-addr-of-self.rs:6:5
|
LL | / pub fn chase_cat(&mut self) {
LL | | let p: &'static mut usize = &mut self.cats_chased;
LL | | *p += 1;
LL | | }
| |_____^
note: ...so that reference does not outlive borrowed content
--> $DIR/regions-addr-of-self.rs:7:37
|
LL | let p: &'static mut usize = &mut self.cats_chased;
| ^^^^^^^^^^^^^^^^^^^^^
= note: but, the lifetime must be valid for the static lifetime...
note: ...so that reference does not outlive borrowed content
--> $DIR/regions-addr-of-self.rs:7:37
|
LL | let p: &'static mut usize = &mut self.cats_chased;
| ^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^ ...is captured and required to live as long as `'static` here

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 E0759`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
trait OtherTrait<'a> {}
impl<'a> OtherTrait<'a> for &'a () {}

trait ObjectTrait {}

impl dyn ObjectTrait {
fn use_self(&self) -> &() { panic!() }
}

fn use_it<'a>(val: &'a dyn ObjectTrait) -> impl OtherTrait<'a> + 'a {
val.use_self() //~ ERROR mismatched types
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
error[E0308]: mismatched types
--> $DIR/impl-on-dyn-trait-with-implicit-static-bound-without-suggestion.rs:11:9
|
LL | val.use_self()
| ^^^^^^^^ lifetime mismatch
|
= note: expected reference `&(dyn ObjectTrait + 'static)`
found reference `&(dyn ObjectTrait + 'a)`
note: the lifetime `'a` as defined on the function body at 10:11...
--> $DIR/impl-on-dyn-trait-with-implicit-static-bound-without-suggestion.rs:10:11
|
LL | fn use_it<'a>(val: &'a dyn ObjectTrait) -> impl OtherTrait<'a> + 'a {
| ^^
= note: ...does not necessarily outlive the static lifetime

error: aborting due to previous error

For more information about this error, try `rustc --explain E0308`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// run-rustfix
#![allow(dead_code)]

mod foo {
trait OtherTrait<'a> {}
impl<'a> OtherTrait<'a> for &'a () {}

trait ObjectTrait {}
trait MyTrait {
fn use_self(&self) -> &();
}

impl MyTrait for dyn ObjectTrait + '_ {
fn use_self(&self) -> &() { panic!() }
}

fn use_it<'a>(val: &'a dyn ObjectTrait) -> impl OtherTrait<'a> + 'a {
val.use_self() //~ ERROR cannot infer an appropriate lifetime
}
}

mod bar {
trait ObjectTrait {}
trait MyTrait {
fn use_self(&self) -> &();
}

impl MyTrait for dyn ObjectTrait + '_ {
fn use_self(&self) -> &() { panic!() }
}

fn use_it<'a>(val: &'a dyn ObjectTrait) -> &'a () {
val.use_self() //~ ERROR cannot infer an appropriate lifetime
}
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// run-rustfix
#![allow(dead_code)]

mod foo {
trait OtherTrait<'a> {}
impl<'a> OtherTrait<'a> for &'a () {}

trait ObjectTrait {}
trait MyTrait {
fn use_self(&self) -> &();
}

impl MyTrait for dyn ObjectTrait {
fn use_self(&self) -> &() { panic!() }
}

fn use_it<'a>(val: &'a dyn ObjectTrait) -> impl OtherTrait<'a> + 'a {
val.use_self() //~ ERROR cannot infer an appropriate lifetime
}
}

mod bar {
trait ObjectTrait {}
trait MyTrait {
fn use_self(&self) -> &();
}

impl MyTrait for dyn ObjectTrait {
fn use_self(&self) -> &() { panic!() }
}

fn use_it<'a>(val: &'a dyn ObjectTrait) -> &'a () {
val.use_self() //~ ERROR cannot infer an appropriate lifetime
}
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
error[E0759]: cannot infer an appropriate lifetime
--> $DIR/impl-on-dyn-trait-with-implicit-static-bound.rs:18:13
|
LL | fn use_it<'a>(val: &'a dyn ObjectTrait) -> impl OtherTrait<'a> + 'a {
| ------------------- this data with lifetime `'a`...
LL | val.use_self()
| ^^^^^^^^ ...is captured and required to live as long as `'static` here
|
help: this `impl` introduces an implicit `'static` requirement, consider changing it
|
LL | impl MyTrait for dyn ObjectTrait + '_ {
| ^^^^

error[E0759]: cannot infer an appropriate lifetime
--> $DIR/impl-on-dyn-trait-with-implicit-static-bound.rs:33:13
|
LL | fn use_it<'a>(val: &'a dyn ObjectTrait) -> &'a () {
| ------------------- this data with lifetime `'a`...
LL | val.use_self()
| ^^^^^^^^ ...is captured and required to live as long as `'static` here
|
help: this `impl` introduces an implicit `'static` requirement, consider changing it
|
LL | impl MyTrait for dyn ObjectTrait + '_ {
| ^^^^

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0759`.

0 comments on commit e6599ad

Please sign in to comment.