Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit ee0fd10

Browse files
committed
Point at return type when it introduces 'static obligation
1 parent 09dbf37 commit ee0fd10

File tree

10 files changed

+142
-0
lines changed

10 files changed

+142
-0
lines changed

compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,26 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
181181
if let SubregionOrigin::RelateParamBound(_, _, Some(bound)) = sub_origin {
182182
err.span_note(*bound, "`'static` lifetime requirement introduced by this bound");
183183
}
184+
if let SubregionOrigin::Subtype(box TypeTrace { cause, .. }) = sub_origin {
185+
if let ObligationCauseCode::BlockTailExpression(hir_id) = &cause.code {
186+
let parent_id = tcx.hir().get_parent_item(*hir_id);
187+
if let Some(fn_decl) = tcx.hir().fn_decl_by_hir_id(parent_id) {
188+
let mut span: MultiSpan = fn_decl.output.span().into();
189+
span.push_span_label(
190+
fn_decl.output.span(),
191+
"requirement introduced by this return type".to_string(),
192+
);
193+
span.push_span_label(
194+
cause.span,
195+
"because of this returned expression".to_string(),
196+
);
197+
err.span_note(
198+
span,
199+
"`'static` lifetime requirement introduced by the return type",
200+
);
201+
}
202+
}
203+
}
184204

185205
let fn_returns = tcx.return_type_impl_or_dyn_traits(anon_reg_sup.def_id);
186206

src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,15 @@ LL | fn baz<'a, 'b>(x: Type<'a>) -> Type<'static> {
66
...
77
LL | bar(foo, x)
88
| ^^^ - ...is captured and required to live as long as `'static` here
9+
|
10+
note: `'static` lifetime requirement introduced by the return type
11+
--> $DIR/project-fn-ret-invariant.rs:45:32
12+
|
13+
LL | fn baz<'a, 'b>(x: Type<'a>) -> Type<'static> {
14+
| ^^^^^^^^^^^^^ requirement introduced by this return type
15+
...
16+
LL | bar(foo, x)
17+
| ----------- because of this returned expression
918

1019
error: aborting due to previous error
1120

src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,13 @@ LL | fn elided3(x: &i32) -> Box<dyn Debug> { Box::new(x) }
140140
| |
141141
| this data with an anonymous lifetime `'_`...
142142
|
143+
note: `'static` lifetime requirement introduced by the return type
144+
--> $DIR/must_outlive_least_region_or_bound.rs:14:24
145+
|
146+
LL | fn elided3(x: &i32) -> Box<dyn Debug> { Box::new(x) }
147+
| ^^^^^^^^^^^^^^ ----------- because of this returned expression
148+
| |
149+
| requirement introduced by this return type
143150
help: to declare that the trait object captures data from argument `x`, you can add an explicit `'_` lifetime bound
144151
|
145152
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) }
153160
| |
154161
| this data with lifetime `'a`...
155162
|
163+
note: `'static` lifetime requirement introduced by the return type
164+
--> $DIR/must_outlive_least_region_or_bound.rs:16:33
165+
|
166+
LL | fn explicit3<'a>(x: &'a i32) -> Box<dyn Debug> { Box::new(x) }
167+
| ^^^^^^^^^^^^^^ ----------- because of this returned expression
168+
| |
169+
| requirement introduced by this return type
156170
help: to declare that the trait object captures data from argument `x`, you can add an explicit `'a` lifetime bound
157171
|
158172
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) }
166180
| |
167181
| this data with an anonymous lifetime `'_`...
168182
|
183+
note: `'static` lifetime requirement introduced by the return type
184+
--> $DIR/must_outlive_least_region_or_bound.rs:18:24
185+
|
186+
LL | fn elided4(x: &i32) -> Box<dyn Debug + 'static> { Box::new(x) }
187+
| ^^^^^^^^^^^^^^^^^^^^^^^^ ----------- because of this returned expression
188+
| |
189+
| requirement introduced by this return type
169190
help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `x`
170191
|
171192
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
181202
LL | fn explicit4<'a>(x: &'a i32) -> Box<dyn Debug + 'static> { Box::new(x) }
182203
| ------- this data with lifetime `'a`... ^ ...is captured and required to live as long as `'static` here
183204
|
205+
note: `'static` lifetime requirement introduced by the return type
206+
--> $DIR/must_outlive_least_region_or_bound.rs:20:33
207+
|
208+
LL | fn explicit4<'a>(x: &'a i32) -> Box<dyn Debug + 'static> { Box::new(x) }
209+
| ^^^^^^^^^^^^^^^^^^^^^^^^ ----------- because of this returned expression
210+
| |
211+
| requirement introduced by this return type
184212
help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `x`
185213
|
186214
LL | fn explicit4<'a>(x: &'a i32) -> Box<dyn Debug + 'a> { Box::new(x) }

src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,14 @@ LL | fn load(ss: &mut SomeStruct) -> Box<dyn SomeTrait> {
77
LL | ss.r
88
| ^^^^ ...is captured and required to live as long as `'static` here
99
|
10+
note: `'static` lifetime requirement introduced by the return type
11+
--> $DIR/object-lifetime-default-from-box-error.rs:14:33
12+
|
13+
LL | fn load(ss: &mut SomeStruct) -> Box<dyn SomeTrait> {
14+
| ^^^^^^^^^^^^^^^^^^ requirement introduced by this return type
15+
...
16+
LL | ss.r
17+
| ---- because of this returned expression
1018
help: to declare that the trait object captures data from argument `ss`, you can add an explicit `'_` lifetime bound
1119
|
1220
LL | fn load(ss: &mut SomeStruct) -> Box<dyn SomeTrait + '_> {

src/test/ui/regions/region-object-lifetime-in-coercion.stderr

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,13 @@ LL | fn b(v: &[u8]) -> Box<dyn Foo + 'static> {
2323
LL | Box::new(v)
2424
| ^ ...is captured and required to live as long as `'static` here
2525
|
26+
note: `'static` lifetime requirement introduced by the return type
27+
--> $DIR/region-object-lifetime-in-coercion.rs:12:19
28+
|
29+
LL | fn b(v: &[u8]) -> Box<dyn Foo + 'static> {
30+
| ^^^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type
31+
LL | Box::new(v)
32+
| ----------- because of this returned expression
2633
help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `v`
2734
|
2835
LL | fn b(v: &[u8]) -> Box<dyn Foo + '_> {
@@ -41,6 +48,14 @@ LL | fn c(v: &[u8]) -> Box<dyn Foo> {
4148
LL | Box::new(v)
4249
| ^ ...is captured and required to live as long as `'static` here
4350
|
51+
note: `'static` lifetime requirement introduced by the return type
52+
--> $DIR/region-object-lifetime-in-coercion.rs:16:19
53+
|
54+
LL | fn c(v: &[u8]) -> Box<dyn Foo> {
55+
| ^^^^^^^^^^^^ requirement introduced by this return type
56+
...
57+
LL | Box::new(v)
58+
| ----------- because of this returned expression
4459
help: to declare that the trait object captures data from argument `v`, you can add an explicit `'_` lifetime bound
4560
|
4661
LL | fn c(v: &[u8]) -> Box<dyn Foo + '_> {

src/test/ui/regions/regions-close-object-into-object-2.stderr

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,13 @@ LL | fn g<'a, T: 'static>(v: Box<dyn A<T> + 'a>) -> Box<dyn X + 'static> {
66
LL | Box::new(B(&*v)) as Box<dyn X>
77
| ^^^ ...is captured and required to live as long as `'static` here
88
|
9+
note: `'static` lifetime requirement introduced by the return type
10+
--> $DIR/regions-close-object-into-object-2.rs:8:48
11+
|
12+
LL | fn g<'a, T: 'static>(v: Box<dyn A<T> + 'a>) -> Box<dyn X + 'static> {
13+
| ^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type
14+
LL | Box::new(B(&*v)) as Box<dyn X>
15+
| ------------------------------ because of this returned expression
916
help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `v`
1017
|
1118
LL | fn g<'a, T: 'static>(v: Box<dyn A<T> + 'a>) -> Box<dyn X + 'a> {

src/test/ui/regions/regions-close-object-into-object-4.stderr

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,13 @@ LL | fn i<'a, T, U>(v: Box<dyn A<U>+'a>) -> Box<dyn X + 'static> {
66
LL | Box::new(B(&*v)) as Box<dyn X>
77
| ^^^ ...is captured and required to live as long as `'static` here
88
|
9+
note: `'static` lifetime requirement introduced by the return type
10+
--> $DIR/regions-close-object-into-object-4.rs:8:40
11+
|
12+
LL | fn i<'a, T, U>(v: Box<dyn A<U>+'a>) -> Box<dyn X + 'static> {
13+
| ^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type
14+
LL | Box::new(B(&*v)) as Box<dyn X>
15+
| ------------------------------ because of this returned expression
916
help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `v`
1017
|
1118
LL | fn i<'a, T, U>(v: Box<dyn A<U>+'a>) -> Box<dyn X + 'a> {

src/test/ui/regions/regions-proc-bound-capture.stderr

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,14 @@ LL | // This is illegal, because the region bound on `proc` is 'static.
77
LL | Box::new(move || { *x })
88
| ^^^^^^^^^^^^^^ ...is captured and required to live as long as `'static` here
99
|
10+
note: `'static` lifetime requirement introduced by the return type
11+
--> $DIR/regions-proc-bound-capture.rs:7:30
12+
|
13+
LL | fn static_proc(x: &isize) -> Box<dyn FnMut() -> (isize) + 'static> {
14+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type
15+
LL | // This is illegal, because the region bound on `proc` is 'static.
16+
LL | Box::new(move || { *x })
17+
| ------------------------ because of this returned expression
1018
help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `x`
1119
|
1220
LL | fn static_proc(x: &isize) -> Box<dyn FnMut() -> (isize) + '_> {

src/test/ui/traits/trait-upcasting/type-checking-test-4.stderr

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,14 @@ note: ...and is required to live as long as `'static` here
4646
|
4747
LL | y.get_b() // ERROR
4848
| ^^^^^^^^^
49+
note: `'static` lifetime requirement introduced by the return type
50+
--> $DIR/type-checking-test-4.rs:26:40
51+
|
52+
LL | fn test_wrong3<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
53+
| ^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type
54+
...
55+
LL | y.get_b() // ERROR
56+
| --------- because of this returned expression
4957

5058
error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement
5159
--> $DIR/type-checking-test-4.rs:33:5
@@ -54,6 +62,14 @@ LL | fn test_wrong4<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
5462
| ------------ this data with lifetime `'a`...
5563
LL | <_ as Bar>::get_b(x) // ERROR
5664
| ^^^^^^^^^^^^^^^^^ ...is captured and required to live as long as `'static` here
65+
|
66+
note: `'static` lifetime requirement introduced by the return type
67+
--> $DIR/type-checking-test-4.rs:32:40
68+
|
69+
LL | fn test_wrong4<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
70+
| ^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type
71+
LL | <_ as Bar>::get_b(x) // ERROR
72+
| -------------------- because of this returned expression
5773

5874
error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement
5975
--> $DIR/type-checking-test-4.rs:38:15
@@ -62,6 +78,14 @@ LL | fn test_wrong5<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
6278
| ------------ this data with lifetime `'a`...
6379
LL | <_ as Bar<'_, '_>>::get_b(x) // ERROR
6480
| ----------^^------------- ...is captured and required to live as long as `'static` here
81+
|
82+
note: `'static` lifetime requirement introduced by the return type
83+
--> $DIR/type-checking-test-4.rs:37:40
84+
|
85+
LL | fn test_wrong5<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
86+
| ^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type
87+
LL | <_ as Bar<'_, '_>>::get_b(x) // ERROR
88+
| ---------------------------- because of this returned expression
6589

6690
error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement
6791
--> $DIR/type-checking-test-4.rs:43:27
@@ -84,6 +108,14 @@ note: ...and is required to live as long as `'static` here
84108
|
85109
LL | z.get_b() // ERROR
86110
| ^^^^^^^^^
111+
note: `'static` lifetime requirement introduced by the return type
112+
--> $DIR/type-checking-test-4.rs:42:40
113+
|
114+
LL | fn test_wrong6<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
115+
| ^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type
116+
...
117+
LL | z.get_b() // ERROR
118+
| --------- because of this returned expression
87119

88120
error: aborting due to 6 previous errors
89121

src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,14 @@ LL | Box::new(items.iter())
99
| |
1010
| ...is captured and required to live as long as `'static` here
1111
|
12+
note: `'static` lifetime requirement introduced by the return type
13+
--> $DIR/dyn-trait-underscore.rs:6:25
14+
|
15+
LL | fn a<T>(items: &[T]) -> Box<dyn Iterator<Item=&T>> {
16+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type
17+
LL | // ^^^^^^^^^^^^^^^^^^^^^ bound *here* defaults to `'static`
18+
LL | Box::new(items.iter())
19+
| ---------------------- because of this returned expression
1220
help: to declare that the trait object captures data from argument `items`, you can add an explicit `'_` lifetime bound
1321
|
1422
LL | fn a<T>(items: &[T]) -> Box<dyn Iterator<Item=&T> + '_> {

0 commit comments

Comments
 (0)