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

Commit 10a74ac

Browse files
committed
Use a more accurate Span for 'static obligation from return type
1 parent ee0fd10 commit 10a74ac

File tree

12 files changed

+85
-79
lines changed

12 files changed

+85
-79
lines changed

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

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ use rustc_hir::def_id::DefId;
1010
use rustc_hir::intravisit::{walk_ty, ErasedMap, NestedVisitorMap, Visitor};
1111
use rustc_hir::{self as hir, GenericBound, Item, ItemKind, Lifetime, LifetimeName, Node, TyKind};
1212
use rustc_middle::ty::{
13-
self, AssocItemContainer, RegionKind, Ty, TyCtxt, TypeFoldable, TypeVisitor,
13+
self, AssocItemContainer, RegionKind, StaticLifetimeVisitor, Ty, TyCtxt, TypeFoldable,
14+
TypeVisitor,
1415
};
1516
use rustc_span::symbol::Ident;
1617
use rustc_span::{MultiSpan, Span};
@@ -186,10 +187,27 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
186187
let parent_id = tcx.hir().get_parent_item(*hir_id);
187188
if let Some(fn_decl) = tcx.hir().fn_decl_by_hir_id(parent_id) {
188189
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-
);
190+
let mut add_label = true;
191+
if let hir::FnRetTy::Return(ty) = fn_decl.output {
192+
let mut v = StaticLifetimeVisitor(vec![], tcx.hir());
193+
v.visit_ty(ty);
194+
if !v.0.is_empty() {
195+
span = v.0.clone().into();
196+
for sp in v.0 {
197+
span.push_span_label(
198+
sp,
199+
"`'static` requirement introduced here".to_string(),
200+
);
201+
}
202+
add_label = false;
203+
}
204+
}
205+
if add_label {
206+
span.push_span_label(
207+
fn_decl.output.span(),
208+
"requirement introduced by this return type".to_string(),
209+
);
210+
}
193211
span.push_span_label(
194212
cause.span,
195213
"because of this returned expression".to_string(),

compiler/rustc_middle/src/ty/context.rs

Lines changed: 2 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1481,40 +1481,8 @@ impl<'tcx> TyCtxt<'tcx> {
14811481
scope_def_id: LocalDefId,
14821482
) -> Vec<&'tcx hir::Ty<'tcx>> {
14831483
let hir_id = self.hir().local_def_id_to_hir_id(scope_def_id);
1484-
let hir_output = match self.hir().get(hir_id) {
1485-
Node::Item(hir::Item {
1486-
kind:
1487-
ItemKind::Fn(
1488-
hir::FnSig {
1489-
decl: hir::FnDecl { output: hir::FnRetTy::Return(ty), .. },
1490-
..
1491-
},
1492-
..,
1493-
),
1494-
..
1495-
})
1496-
| Node::ImplItem(hir::ImplItem {
1497-
kind:
1498-
hir::ImplItemKind::Fn(
1499-
hir::FnSig {
1500-
decl: hir::FnDecl { output: hir::FnRetTy::Return(ty), .. },
1501-
..
1502-
},
1503-
_,
1504-
),
1505-
..
1506-
})
1507-
| Node::TraitItem(hir::TraitItem {
1508-
kind:
1509-
hir::TraitItemKind::Fn(
1510-
hir::FnSig {
1511-
decl: hir::FnDecl { output: hir::FnRetTy::Return(ty), .. },
1512-
..
1513-
},
1514-
_,
1515-
),
1516-
..
1517-
}) => ty,
1484+
let hir_output = match self.hir().fn_decl_by_hir_id(hir_id) {
1485+
Some(hir::FnDecl { output: hir::FnRetTy::Return(ty), .. }) => ty,
15181486
_ => return vec![],
15191487
};
15201488

compiler/rustc_middle/src/ty/diagnostics.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use rustc_errors::{Applicability, DiagnosticBuilder};
66
use rustc_hir as hir;
77
use rustc_hir::def_id::DefId;
88
use rustc_hir::{QPath, TyKind, WhereBoundPredicate, WherePredicate};
9+
use rustc_span::Span;
910

1011
impl<'tcx> TyS<'tcx> {
1112
/// Similar to `TyS::is_primitive`, but also considers inferred numeric values to be primitive.
@@ -432,3 +433,22 @@ impl<'v> hir::intravisit::Visitor<'v> for TraitObjectVisitor<'v> {
432433
hir::intravisit::walk_ty(self, ty);
433434
}
434435
}
436+
437+
/// Collect al types that have an implicit `'static` obligation that we could suggest `'_` for.
438+
pub struct StaticLifetimeVisitor<'tcx>(pub Vec<Span>, pub crate::hir::map::Map<'tcx>);
439+
440+
impl<'v> hir::intravisit::Visitor<'v> for StaticLifetimeVisitor<'v> {
441+
type Map = rustc_hir::intravisit::ErasedMap<'v>;
442+
443+
fn nested_visit_map(&mut self) -> hir::intravisit::NestedVisitorMap<Self::Map> {
444+
hir::intravisit::NestedVisitorMap::None
445+
}
446+
447+
fn visit_lifetime(&mut self, lt: &'v hir::Lifetime) {
448+
if let hir::LifetimeName::ImplicitObjectLifetimeDefault | hir::LifetimeName::Static =
449+
lt.name
450+
{
451+
self.0.push(lt.span);
452+
}
453+
}
454+
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ LL | bar(foo, x)
88
| ^^^ - ...is captured and required to live as long as `'static` here
99
|
1010
note: `'static` lifetime requirement introduced by the return type
11-
--> $DIR/project-fn-ret-invariant.rs:45:32
11+
--> $DIR/project-fn-ret-invariant.rs:45:37
1212
|
1313
LL | fn baz<'a, 'b>(x: Type<'a>) -> Type<'static> {
14-
| ^^^^^^^^^^^^^ requirement introduced by this return type
14+
| ^^^^^^^ `'static` requirement introduced here
1515
...
1616
LL | bar(foo, x)
1717
| ----------- because of this returned expression

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

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -141,12 +141,12 @@ LL | fn elided3(x: &i32) -> Box<dyn Debug> { Box::new(x) }
141141
| this data with an anonymous lifetime `'_`...
142142
|
143143
note: `'static` lifetime requirement introduced by the return type
144-
--> $DIR/must_outlive_least_region_or_bound.rs:14:24
144+
--> $DIR/must_outlive_least_region_or_bound.rs:14:28
145145
|
146146
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
147+
| ^^^^^^^^^ ----------- because of this returned expression
148+
| |
149+
| `'static` requirement introduced here
150150
help: to declare that the trait object captures data from argument `x`, you can add an explicit `'_` lifetime bound
151151
|
152152
LL | fn elided3(x: &i32) -> Box<dyn Debug + '_> { Box::new(x) }
@@ -161,12 +161,12 @@ LL | fn explicit3<'a>(x: &'a i32) -> Box<dyn Debug> { Box::new(x) }
161161
| this data with lifetime `'a`...
162162
|
163163
note: `'static` lifetime requirement introduced by the return type
164-
--> $DIR/must_outlive_least_region_or_bound.rs:16:33
164+
--> $DIR/must_outlive_least_region_or_bound.rs:16:37
165165
|
166166
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
167+
| ^^^^^^^^^ ----------- because of this returned expression
168+
| |
169+
| `'static` requirement introduced here
170170
help: to declare that the trait object captures data from argument `x`, you can add an explicit `'a` lifetime bound
171171
|
172172
LL | fn explicit3<'a>(x: &'a i32) -> Box<dyn Debug + 'a> { Box::new(x) }
@@ -181,12 +181,12 @@ LL | fn elided4(x: &i32) -> Box<dyn Debug + 'static> { Box::new(x) }
181181
| this data with an anonymous lifetime `'_`...
182182
|
183183
note: `'static` lifetime requirement introduced by the return type
184-
--> $DIR/must_outlive_least_region_or_bound.rs:18:24
184+
--> $DIR/must_outlive_least_region_or_bound.rs:18:40
185185
|
186186
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
187+
| ^^^^^^^ ----------- because of this returned expression
188+
| |
189+
| `'static` requirement introduced here
190190
help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `x`
191191
|
192192
LL | fn elided4(x: &i32) -> Box<dyn Debug + '_> { Box::new(x) }
@@ -203,12 +203,12 @@ LL | fn explicit4<'a>(x: &'a i32) -> Box<dyn Debug + 'static> { Box::new(x) }
203203
| ------- this data with lifetime `'a`... ^ ...is captured and required to live as long as `'static` here
204204
|
205205
note: `'static` lifetime requirement introduced by the return type
206-
--> $DIR/must_outlive_least_region_or_bound.rs:20:33
206+
--> $DIR/must_outlive_least_region_or_bound.rs:20:49
207207
|
208208
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
209+
| ^^^^^^^ ----------- because of this returned expression
210+
| |
211+
| `'static` requirement introduced here
212212
help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `x`
213213
|
214214
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: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ LL | ss.r
88
| ^^^^ ...is captured and required to live as long as `'static` here
99
|
1010
note: `'static` lifetime requirement introduced by the return type
11-
--> $DIR/object-lifetime-default-from-box-error.rs:14:33
11+
--> $DIR/object-lifetime-default-from-box-error.rs:14:37
1212
|
1313
LL | fn load(ss: &mut SomeStruct) -> Box<dyn SomeTrait> {
14-
| ^^^^^^^^^^^^^^^^^^ requirement introduced by this return type
14+
| ^^^^^^^^^^^^^ `'static` requirement introduced here
1515
...
1616
LL | ss.r
1717
| ---- because of this returned expression

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@ LL | Box::new(v)
2424
| ^ ...is captured and required to live as long as `'static` here
2525
|
2626
note: `'static` lifetime requirement introduced by the return type
27-
--> $DIR/region-object-lifetime-in-coercion.rs:12:19
27+
--> $DIR/region-object-lifetime-in-coercion.rs:12:33
2828
|
2929
LL | fn b(v: &[u8]) -> Box<dyn Foo + 'static> {
30-
| ^^^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type
30+
| ^^^^^^^ `'static` requirement introduced here
3131
LL | Box::new(v)
3232
| ----------- because of this returned expression
3333
help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `v`
@@ -49,10 +49,10 @@ LL | Box::new(v)
4949
| ^ ...is captured and required to live as long as `'static` here
5050
|
5151
note: `'static` lifetime requirement introduced by the return type
52-
--> $DIR/region-object-lifetime-in-coercion.rs:16:19
52+
--> $DIR/region-object-lifetime-in-coercion.rs:16:23
5353
|
5454
LL | fn c(v: &[u8]) -> Box<dyn Foo> {
55-
| ^^^^^^^^^^^^ requirement introduced by this return type
55+
| ^^^^^^^ `'static` requirement introduced here
5656
...
5757
LL | Box::new(v)
5858
| ----------- because of this returned expression

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

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

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

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

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ LL | Box::new(move || { *x })
88
| ^^^^^^^^^^^^^^ ...is captured and required to live as long as `'static` here
99
|
1010
note: `'static` lifetime requirement introduced by the return type
11-
--> $DIR/regions-proc-bound-capture.rs:7:30
11+
--> $DIR/regions-proc-bound-capture.rs:7:59
1212
|
1313
LL | fn static_proc(x: &isize) -> Box<dyn FnMut() -> (isize) + 'static> {
14-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type
14+
| ^^^^^^^ `'static` requirement introduced here
1515
LL | // This is illegal, because the region bound on `proc` is 'static.
1616
LL | Box::new(move || { *x })
1717
| ------------------------ because of this returned expression

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

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,10 @@ note: ...and is required to live as long as `'static` here
4747
LL | y.get_b() // ERROR
4848
| ^^^^^^^^^
4949
note: `'static` lifetime requirement introduced by the return type
50-
--> $DIR/type-checking-test-4.rs:26:40
50+
--> $DIR/type-checking-test-4.rs:26:48
5151
|
5252
LL | fn test_wrong3<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
53-
| ^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type
53+
| ^^^^^^^ `'static` requirement introduced here
5454
...
5555
LL | y.get_b() // ERROR
5656
| --------- because of this returned expression
@@ -64,10 +64,10 @@ LL | <_ as Bar>::get_b(x) // ERROR
6464
| ^^^^^^^^^^^^^^^^^ ...is captured and required to live as long as `'static` here
6565
|
6666
note: `'static` lifetime requirement introduced by the return type
67-
--> $DIR/type-checking-test-4.rs:32:40
67+
--> $DIR/type-checking-test-4.rs:32:48
6868
|
6969
LL | fn test_wrong4<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
70-
| ^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type
70+
| ^^^^^^^ `'static` requirement introduced here
7171
LL | <_ as Bar>::get_b(x) // ERROR
7272
| -------------------- because of this returned expression
7373

@@ -80,10 +80,10 @@ LL | <_ as Bar<'_, '_>>::get_b(x) // ERROR
8080
| ----------^^------------- ...is captured and required to live as long as `'static` here
8181
|
8282
note: `'static` lifetime requirement introduced by the return type
83-
--> $DIR/type-checking-test-4.rs:37:40
83+
--> $DIR/type-checking-test-4.rs:37:48
8484
|
8585
LL | fn test_wrong5<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
86-
| ^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type
86+
| ^^^^^^^ `'static` requirement introduced here
8787
LL | <_ as Bar<'_, '_>>::get_b(x) // ERROR
8888
| ---------------------------- because of this returned expression
8989

@@ -109,10 +109,10 @@ note: ...and is required to live as long as `'static` here
109109
LL | z.get_b() // ERROR
110110
| ^^^^^^^^^
111111
note: `'static` lifetime requirement introduced by the return type
112-
--> $DIR/type-checking-test-4.rs:42:40
112+
--> $DIR/type-checking-test-4.rs:42:48
113113
|
114114
LL | fn test_wrong6<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
115-
| ^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type
115+
| ^^^^^^^ `'static` requirement introduced here
116116
...
117117
LL | z.get_b() // ERROR
118118
| --------- because of this returned expression

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@ LL | Box::new(items.iter())
1010
| ...is captured and required to live as long as `'static` here
1111
|
1212
note: `'static` lifetime requirement introduced by the return type
13-
--> $DIR/dyn-trait-underscore.rs:6:25
13+
--> $DIR/dyn-trait-underscore.rs:6:29
1414
|
1515
LL | fn a<T>(items: &[T]) -> Box<dyn Iterator<Item=&T>> {
16-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type
16+
| ^^^^^^^^^^^^^^^^^^^^^ `'static` requirement introduced here
1717
LL | // ^^^^^^^^^^^^^^^^^^^^^ bound *here* defaults to `'static`
1818
LL | Box::new(items.iter())
1919
| ---------------------- because of this returned expression

0 commit comments

Comments
 (0)