Point at return type when it introduces 'static obligation

This commit is contained in:
Esteban Kuber 2021-10-12 09:52:32 +00:00
parent 09dbf37213
commit ee0fd105d8
10 changed files with 142 additions and 0 deletions

View File

@ -181,6 +181,26 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
if let SubregionOrigin::RelateParamBound(_, _, Some(bound)) = sub_origin { if let SubregionOrigin::RelateParamBound(_, _, Some(bound)) = sub_origin {
err.span_note(*bound, "`'static` lifetime requirement introduced by this bound"); err.span_note(*bound, "`'static` lifetime requirement introduced by this bound");
} }
if let SubregionOrigin::Subtype(box TypeTrace { cause, .. }) = sub_origin {
if let ObligationCauseCode::BlockTailExpression(hir_id) = &cause.code {
let parent_id = tcx.hir().get_parent_item(*hir_id);
if let Some(fn_decl) = tcx.hir().fn_decl_by_hir_id(parent_id) {
let mut span: MultiSpan = fn_decl.output.span().into();
span.push_span_label(
fn_decl.output.span(),
"requirement introduced by this return type".to_string(),
);
span.push_span_label(
cause.span,
"because of this returned expression".to_string(),
);
err.span_note(
span,
"`'static` lifetime requirement introduced by the return type",
);
}
}
}
let fn_returns = tcx.return_type_impl_or_dyn_traits(anon_reg_sup.def_id); let fn_returns = tcx.return_type_impl_or_dyn_traits(anon_reg_sup.def_id);

View File

@ -6,6 +6,15 @@ LL | fn baz<'a, 'b>(x: Type<'a>) -> Type<'static> {
... ...
LL | bar(foo, x) LL | bar(foo, x)
| ^^^ - ...is captured and required to live as long as `'static` here | ^^^ - ...is captured and required to live as long as `'static` here
|
note: `'static` lifetime requirement introduced by the return type
--> $DIR/project-fn-ret-invariant.rs:45:32
|
LL | fn baz<'a, 'b>(x: Type<'a>) -> Type<'static> {
| ^^^^^^^^^^^^^ requirement introduced by this return type
...
LL | bar(foo, x)
| ----------- because of this returned expression
error: aborting due to previous error error: aborting due to previous error

View File

@ -140,6 +140,13 @@ LL | fn elided3(x: &i32) -> Box<dyn Debug> { Box::new(x) }
| | | |
| this data with an anonymous lifetime `'_`... | this data with an anonymous lifetime `'_`...
| |
note: `'static` lifetime requirement introduced by the return type
--> $DIR/must_outlive_least_region_or_bound.rs:14:24
|
LL | fn elided3(x: &i32) -> Box<dyn Debug> { Box::new(x) }
| ^^^^^^^^^^^^^^ ----------- because of this returned expression
| |
| requirement introduced by this return type
help: to declare that the trait object captures data from argument `x`, you can add an explicit `'_` lifetime bound help: to declare that the trait object captures data from argument `x`, you can add an explicit `'_` lifetime bound
| |
LL | fn elided3(x: &i32) -> Box<dyn Debug + '_> { Box::new(x) } LL | fn elided3(x: &i32) -> Box<dyn Debug + '_> { Box::new(x) }
@ -153,6 +160,13 @@ LL | fn explicit3<'a>(x: &'a i32) -> Box<dyn Debug> { Box::new(x) }
| | | |
| this data with lifetime `'a`... | this data with lifetime `'a`...
| |
note: `'static` lifetime requirement introduced by the return type
--> $DIR/must_outlive_least_region_or_bound.rs:16:33
|
LL | fn explicit3<'a>(x: &'a i32) -> Box<dyn Debug> { Box::new(x) }
| ^^^^^^^^^^^^^^ ----------- because of this returned expression
| |
| requirement introduced by this return type
help: to declare that the trait object captures data from argument `x`, you can add an explicit `'a` lifetime bound help: to declare that the trait object captures data from argument `x`, you can add an explicit `'a` lifetime bound
| |
LL | fn explicit3<'a>(x: &'a i32) -> Box<dyn Debug + 'a> { Box::new(x) } LL | fn explicit3<'a>(x: &'a i32) -> Box<dyn Debug + 'a> { Box::new(x) }
@ -166,6 +180,13 @@ LL | fn elided4(x: &i32) -> Box<dyn Debug + 'static> { Box::new(x) }
| | | |
| this data with an anonymous lifetime `'_`... | this data with an anonymous lifetime `'_`...
| |
note: `'static` lifetime requirement introduced by the return type
--> $DIR/must_outlive_least_region_or_bound.rs:18:24
|
LL | fn elided4(x: &i32) -> Box<dyn Debug + 'static> { Box::new(x) }
| ^^^^^^^^^^^^^^^^^^^^^^^^ ----------- because of this returned expression
| |
| requirement introduced by this return type
help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `x` help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `x`
| |
LL | fn elided4(x: &i32) -> Box<dyn Debug + '_> { Box::new(x) } LL | fn elided4(x: &i32) -> Box<dyn Debug + '_> { Box::new(x) }
@ -181,6 +202,13 @@ error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime
LL | fn explicit4<'a>(x: &'a i32) -> Box<dyn Debug + 'static> { Box::new(x) } LL | fn explicit4<'a>(x: &'a i32) -> Box<dyn Debug + 'static> { Box::new(x) }
| ------- this data with lifetime `'a`... ^ ...is captured and required to live as long as `'static` here | ------- this data with lifetime `'a`... ^ ...is captured and required to live as long as `'static` here
| |
note: `'static` lifetime requirement introduced by the return type
--> $DIR/must_outlive_least_region_or_bound.rs:20:33
|
LL | fn explicit4<'a>(x: &'a i32) -> Box<dyn Debug + 'static> { Box::new(x) }
| ^^^^^^^^^^^^^^^^^^^^^^^^ ----------- because of this returned expression
| |
| requirement introduced by this return type
help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `x` help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `x`
| |
LL | fn explicit4<'a>(x: &'a i32) -> Box<dyn Debug + 'a> { Box::new(x) } LL | fn explicit4<'a>(x: &'a i32) -> Box<dyn Debug + 'a> { Box::new(x) }

View File

@ -7,6 +7,14 @@ LL | fn load(ss: &mut SomeStruct) -> Box<dyn SomeTrait> {
LL | ss.r LL | ss.r
| ^^^^ ...is captured and required to live as long as `'static` here | ^^^^ ...is captured and required to live as long as `'static` here
| |
note: `'static` lifetime requirement introduced by the return type
--> $DIR/object-lifetime-default-from-box-error.rs:14:33
|
LL | fn load(ss: &mut SomeStruct) -> Box<dyn SomeTrait> {
| ^^^^^^^^^^^^^^^^^^ requirement introduced by this return type
...
LL | ss.r
| ---- because of this returned expression
help: to declare that the trait object captures data from argument `ss`, you can add an explicit `'_` lifetime bound help: to declare that the trait object captures data from argument `ss`, you can add an explicit `'_` lifetime bound
| |
LL | fn load(ss: &mut SomeStruct) -> Box<dyn SomeTrait + '_> { LL | fn load(ss: &mut SomeStruct) -> Box<dyn SomeTrait + '_> {

View File

@ -23,6 +23,13 @@ LL | fn b(v: &[u8]) -> Box<dyn Foo + 'static> {
LL | Box::new(v) LL | Box::new(v)
| ^ ...is captured and required to live as long as `'static` here | ^ ...is captured and required to live as long as `'static` here
| |
note: `'static` lifetime requirement introduced by the return type
--> $DIR/region-object-lifetime-in-coercion.rs:12:19
|
LL | fn b(v: &[u8]) -> Box<dyn Foo + 'static> {
| ^^^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type
LL | Box::new(v)
| ----------- because of this returned expression
help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `v` help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `v`
| |
LL | fn b(v: &[u8]) -> Box<dyn Foo + '_> { LL | fn b(v: &[u8]) -> Box<dyn Foo + '_> {
@ -41,6 +48,14 @@ LL | fn c(v: &[u8]) -> Box<dyn Foo> {
LL | Box::new(v) LL | Box::new(v)
| ^ ...is captured and required to live as long as `'static` here | ^ ...is captured and required to live as long as `'static` here
| |
note: `'static` lifetime requirement introduced by the return type
--> $DIR/region-object-lifetime-in-coercion.rs:16:19
|
LL | fn c(v: &[u8]) -> Box<dyn Foo> {
| ^^^^^^^^^^^^ requirement introduced by this return type
...
LL | Box::new(v)
| ----------- because of this returned expression
help: to declare that the trait object captures data from argument `v`, you can add an explicit `'_` lifetime bound help: to declare that the trait object captures data from argument `v`, you can add an explicit `'_` lifetime bound
| |
LL | fn c(v: &[u8]) -> Box<dyn Foo + '_> { LL | fn c(v: &[u8]) -> Box<dyn Foo + '_> {

View File

@ -6,6 +6,13 @@ LL | fn g<'a, T: 'static>(v: Box<dyn A<T> + 'a>) -> Box<dyn X + 'static> {
LL | Box::new(B(&*v)) as Box<dyn X> LL | Box::new(B(&*v)) as Box<dyn X>
| ^^^ ...is captured and required to live as long as `'static` here | ^^^ ...is captured and required to live as long as `'static` here
| |
note: `'static` lifetime requirement introduced by the return type
--> $DIR/regions-close-object-into-object-2.rs:8:48
|
LL | fn g<'a, T: 'static>(v: Box<dyn A<T> + 'a>) -> Box<dyn X + 'static> {
| ^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type
LL | Box::new(B(&*v)) as Box<dyn X>
| ------------------------------ because of this returned expression
help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `v` help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `v`
| |
LL | fn g<'a, T: 'static>(v: Box<dyn A<T> + 'a>) -> Box<dyn X + 'a> { LL | fn g<'a, T: 'static>(v: Box<dyn A<T> + 'a>) -> Box<dyn X + 'a> {

View File

@ -6,6 +6,13 @@ LL | fn i<'a, T, U>(v: Box<dyn A<U>+'a>) -> Box<dyn X + 'static> {
LL | Box::new(B(&*v)) as Box<dyn X> LL | Box::new(B(&*v)) as Box<dyn X>
| ^^^ ...is captured and required to live as long as `'static` here | ^^^ ...is captured and required to live as long as `'static` here
| |
note: `'static` lifetime requirement introduced by the return type
--> $DIR/regions-close-object-into-object-4.rs:8:40
|
LL | fn i<'a, T, U>(v: Box<dyn A<U>+'a>) -> Box<dyn X + 'static> {
| ^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type
LL | Box::new(B(&*v)) as Box<dyn X>
| ------------------------------ because of this returned expression
help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `v` help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `v`
| |
LL | fn i<'a, T, U>(v: Box<dyn A<U>+'a>) -> Box<dyn X + 'a> { LL | fn i<'a, T, U>(v: Box<dyn A<U>+'a>) -> Box<dyn X + 'a> {

View File

@ -7,6 +7,14 @@ LL | // This is illegal, because the region bound on `proc` is 'static.
LL | Box::new(move || { *x }) LL | Box::new(move || { *x })
| ^^^^^^^^^^^^^^ ...is captured and required to live as long as `'static` here | ^^^^^^^^^^^^^^ ...is captured and required to live as long as `'static` here
| |
note: `'static` lifetime requirement introduced by the return type
--> $DIR/regions-proc-bound-capture.rs:7:30
|
LL | fn static_proc(x: &isize) -> Box<dyn FnMut() -> (isize) + 'static> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type
LL | // This is illegal, because the region bound on `proc` is 'static.
LL | Box::new(move || { *x })
| ------------------------ because of this returned expression
help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `x` help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `x`
| |
LL | fn static_proc(x: &isize) -> Box<dyn FnMut() -> (isize) + '_> { LL | fn static_proc(x: &isize) -> Box<dyn FnMut() -> (isize) + '_> {

View File

@ -46,6 +46,14 @@ note: ...and is required to live as long as `'static` here
| |
LL | y.get_b() // ERROR LL | y.get_b() // ERROR
| ^^^^^^^^^ | ^^^^^^^^^
note: `'static` lifetime requirement introduced by the return type
--> $DIR/type-checking-test-4.rs:26:40
|
LL | fn test_wrong3<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
| ^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type
...
LL | y.get_b() // ERROR
| --------- because of this returned expression
error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement
--> $DIR/type-checking-test-4.rs:33:5 --> $DIR/type-checking-test-4.rs:33:5
@ -54,6 +62,14 @@ LL | fn test_wrong4<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
| ------------ this data with lifetime `'a`... | ------------ this data with lifetime `'a`...
LL | <_ as Bar>::get_b(x) // ERROR LL | <_ as Bar>::get_b(x) // ERROR
| ^^^^^^^^^^^^^^^^^ ...is captured and required to live as long as `'static` here | ^^^^^^^^^^^^^^^^^ ...is captured and required to live as long as `'static` here
|
note: `'static` lifetime requirement introduced by the return type
--> $DIR/type-checking-test-4.rs:32:40
|
LL | fn test_wrong4<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
| ^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type
LL | <_ as Bar>::get_b(x) // ERROR
| -------------------- because of this returned expression
error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement
--> $DIR/type-checking-test-4.rs:38:15 --> $DIR/type-checking-test-4.rs:38:15
@ -62,6 +78,14 @@ LL | fn test_wrong5<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
| ------------ this data with lifetime `'a`... | ------------ this data with lifetime `'a`...
LL | <_ as Bar<'_, '_>>::get_b(x) // ERROR LL | <_ as Bar<'_, '_>>::get_b(x) // ERROR
| ----------^^------------- ...is captured and required to live as long as `'static` here | ----------^^------------- ...is captured and required to live as long as `'static` here
|
note: `'static` lifetime requirement introduced by the return type
--> $DIR/type-checking-test-4.rs:37:40
|
LL | fn test_wrong5<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
| ^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type
LL | <_ as Bar<'_, '_>>::get_b(x) // ERROR
| ---------------------------- because of this returned expression
error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement
--> $DIR/type-checking-test-4.rs:43:27 --> $DIR/type-checking-test-4.rs:43:27
@ -84,6 +108,14 @@ note: ...and is required to live as long as `'static` here
| |
LL | z.get_b() // ERROR LL | z.get_b() // ERROR
| ^^^^^^^^^ | ^^^^^^^^^
note: `'static` lifetime requirement introduced by the return type
--> $DIR/type-checking-test-4.rs:42:40
|
LL | fn test_wrong6<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
| ^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type
...
LL | z.get_b() // ERROR
| --------- because of this returned expression
error: aborting due to 6 previous errors error: aborting due to 6 previous errors

View File

@ -9,6 +9,14 @@ LL | Box::new(items.iter())
| | | |
| ...is captured and required to live as long as `'static` here | ...is captured and required to live as long as `'static` here
| |
note: `'static` lifetime requirement introduced by the return type
--> $DIR/dyn-trait-underscore.rs:6:25
|
LL | fn a<T>(items: &[T]) -> Box<dyn Iterator<Item=&T>> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type
LL | // ^^^^^^^^^^^^^^^^^^^^^ bound *here* defaults to `'static`
LL | Box::new(items.iter())
| ---------------------- because of this returned expression
help: to declare that the trait object captures data from argument `items`, you can add an explicit `'_` lifetime bound help: to declare that the trait object captures data from argument `items`, you can add an explicit `'_` lifetime bound
| |
LL | fn a<T>(items: &[T]) -> Box<dyn Iterator<Item=&T> + '_> { LL | fn a<T>(items: &[T]) -> Box<dyn Iterator<Item=&T> + '_> {