Skip to content

Commit f9357f6

Browse files
committed
Account for '_ in lifetime suggestion
1 parent cae02f7 commit f9357f6

File tree

3 files changed

+35
-4
lines changed

3 files changed

+35
-4
lines changed

compiler/rustc_resolve/src/late/diagnostics.rs

+15-4
Original file line numberDiff line numberDiff line change
@@ -2880,6 +2880,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
28802880
} else {
28812881
"instead, you are more likely to want"
28822882
};
2883+
let mut owned_sugg = lt.kind == MissingLifetimeKind::Ampersand;
28832884
let mut sugg = vec![(lt.span, String::new())];
28842885
if let Some((kind, _span)) =
28852886
self.diagnostic_metadata.current_function
@@ -2893,6 +2894,17 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
28932894
};
28942895
lt_finder.visit_ty(&ty);
28952896

2897+
if let [Ty { span, kind: TyKind::Ref(_, mut_ty), ..}]
2898+
= &lt_finder.seen[..]
2899+
{
2900+
// We might have a situation like
2901+
// fn g(mut x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()>
2902+
// but `lt.span` only points at `'_`, so to suggest `-> Option<()>`
2903+
// we need to find a more accurate span to end up with
2904+
// fn g<'a>(mut x: impl Iterator<Item = &'_ ()>) -> Option<()>
2905+
sugg = vec![(span.with_hi(mut_ty.ty.span.lo()), String::new())];
2906+
owned_sugg = true;
2907+
}
28962908
if let Some(ty) = lt_finder.found {
28972909
if let TyKind::Path(None, Path { segments, .. }) = &ty.kind
28982910
&& segments.len() == 1
@@ -2902,17 +2914,16 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
29022914
sugg = vec![
29032915
(lt.span.with_hi(ty.span.hi()), "String".to_string()),
29042916
];
2905-
}
2906-
if let TyKind::Slice(inner_ty) = &ty.kind {
2917+
} else if let TyKind::Slice(inner_ty) = &ty.kind {
29072918
// Don't suggest `-> [T]`, suggest `-> Vec<T>`.
29082919
sugg = vec![
29092920
(lt.span.with_hi(inner_ty.span.lo()), "Vec<".to_string()),
29102921
(ty.span.with_lo(inner_ty.span.hi()), ">".to_string()),
29112922
];
29122923
}
29132924
}
2914-
};
2915-
if lt.kind == MissingLifetimeKind::Ampersand {
2925+
}
2926+
if owned_sugg {
29162927
err.multipart_suggestion_verbose(
29172928
format!("{pre} to return an owned value"),
29182929
sugg,

tests/ui/suggestions/impl-trait-missing-lifetime-gated.stderr

+10
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,11 @@ help: consider introducing a named lifetime parameter
5555
|
5656
LL | fn g<'a>(mut x: impl Iterator<Item = &'a ()>) -> Option<&'a ()> { x.next() }
5757
| ++++ ~~~ ~~~
58+
help: alternatively, you might want to return an owned value
59+
|
60+
LL - fn g(mut x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
61+
LL + fn g(mut x: impl Iterator<Item = &'_ ()>) -> Option<()> { x.next() }
62+
|
5863

5964
error[E0106]: missing lifetime specifier
6065
--> $DIR/impl-trait-missing-lifetime-gated.rs:37:64
@@ -71,6 +76,11 @@ help: consider introducing a named lifetime parameter
7176
|
7277
LL | async fn i<'a>(mut x: impl Iterator<Item = &'a ()>) -> Option<&'a ()> { x.next() }
7378
| ++++ ~~~ ~~~
79+
help: alternatively, you might want to return an owned value
80+
|
81+
LL - async fn i(mut x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
82+
LL + async fn i(mut x: impl Iterator<Item = &'_ ()>) -> Option<()> { x.next() }
83+
|
7484

7585
error[E0106]: missing lifetime specifier
7686
--> $DIR/impl-trait-missing-lifetime-gated.rs:47:37

tests/ui/suggestions/impl-trait-missing-lifetime.stderr

+10
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@ help: consider introducing a named lifetime parameter
1313
|
1414
LL | fn g<'a>(mut x: impl Iterator<Item = &'a ()>) -> Option<&'a ()> { x.next() }
1515
| ++++ ~~~ ~~~
16+
help: alternatively, you might want to return an owned value
17+
|
18+
LL - fn g(mut x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
19+
LL + fn g(mut x: impl Iterator<Item = &'_ ()>) -> Option<()> { x.next() }
20+
|
1621

1722
error[E0106]: missing lifetime specifier
1823
--> $DIR/impl-trait-missing-lifetime.rs:16:60
@@ -29,6 +34,11 @@ help: consider introducing a named lifetime parameter
2934
|
3035
LL | async fn i<'a>(mut x: impl Iterator<Item = &'a ()>) -> Option<&'a ()> { x.next() }
3136
| ++++ ~~~ ~~~
37+
help: alternatively, you might want to return an owned value
38+
|
39+
LL - async fn i(mut x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
40+
LL + async fn i(mut x: impl Iterator<Item = &'_ ()>) -> Option<()> { x.next() }
41+
|
3242

3343
error: lifetime may not live long enough
3444
--> $DIR/impl-trait-missing-lifetime.rs:16:69

0 commit comments

Comments
 (0)