diff options
| author | Esteban Küber <esteban@kuber.com.ar> | 2023-11-15 18:00:43 +0000 |
|---|---|---|
| committer | Esteban Küber <esteban@kuber.com.ar> | 2023-11-20 23:44:37 +0000 |
| commit | 85f26ade8dc3364f29a2c0b0d8f5fe2068df8969 (patch) | |
| tree | b215114727885740f7d7950d3327b01edd9e2ed7 | |
| parent | 2a92d820c79e56be8191bdf64e8b2dc7c96210df (diff) | |
| download | rust-85f26ade8dc3364f29a2c0b0d8f5fe2068df8969.tar.gz rust-85f26ade8dc3364f29a2c0b0d8f5fe2068df8969.zip | |
Account for '_ in lifetime suggestion
3 files changed, 35 insertions, 4 deletions
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 984516baa18..f7560d9949b 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -3079,6 +3079,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { } else { "instead, you are more likely to want" }; + let mut owned_sugg = lt.kind == MissingLifetimeKind::Ampersand; let mut sugg = vec![(lt.span, String::new())]; if let Some((kind, _span)) = self.diagnostic_metadata.current_function @@ -3092,6 +3093,17 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { }; lt_finder.visit_ty(&ty); + if let [Ty { span, kind: TyKind::Ref(_, mut_ty), ..}] + = <_finder.seen[..] + { + // We might have a situation like + // fn g(mut x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> + // but `lt.span` only points at `'_`, so to suggest `-> Option<()>` + // we need to find a more accurate span to end up with + // fn g<'a>(mut x: impl Iterator<Item = &'_ ()>) -> Option<()> + sugg = vec![(span.with_hi(mut_ty.ty.span.lo()), String::new())]; + owned_sugg = true; + } if let Some(ty) = lt_finder.found { if let TyKind::Path(None, Path { segments, .. }) = &ty.kind && segments.len() == 1 @@ -3101,8 +3113,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { sugg = vec![ (lt.span.with_hi(ty.span.hi()), "String".to_string()), ]; - } - if let TyKind::Slice(inner_ty) = &ty.kind { + } else if let TyKind::Slice(inner_ty) = &ty.kind { // Don't suggest `-> [T]`, suggest `-> Vec<T>`. sugg = vec![ (lt.span.with_hi(inner_ty.span.lo()), "Vec<".to_string()), @@ -3110,8 +3121,8 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { ]; } } - }; - if lt.kind == MissingLifetimeKind::Ampersand { + } + if owned_sugg { err.multipart_suggestion_verbose( format!("{pre} to return an owned value"), sugg, diff --git a/tests/ui/suggestions/impl-trait-missing-lifetime-gated.stderr b/tests/ui/suggestions/impl-trait-missing-lifetime-gated.stderr index 383cba75e28..2dfaa731194 100644 --- a/tests/ui/suggestions/impl-trait-missing-lifetime-gated.stderr +++ b/tests/ui/suggestions/impl-trait-missing-lifetime-gated.stderr @@ -55,6 +55,11 @@ help: consider introducing a named lifetime parameter | LL | fn g<'a>(mut x: impl Iterator<Item = &'a ()>) -> Option<&'a ()> { x.next() } | ++++ ~~~ ~~~ +help: alternatively, you might want to return an owned value + | +LL - fn g(mut x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() } +LL + fn g(mut x: impl Iterator<Item = &'_ ()>) -> Option<()> { x.next() } + | error[E0106]: missing lifetime specifier --> $DIR/impl-trait-missing-lifetime-gated.rs:37:64 @@ -71,6 +76,11 @@ help: consider introducing a named lifetime parameter | LL | async fn i<'a>(mut x: impl Iterator<Item = &'a ()>) -> Option<&'a ()> { x.next() } | ++++ ~~~ ~~~ +help: alternatively, you might want to return an owned value + | +LL - async fn i(mut x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() } +LL + async fn i(mut x: impl Iterator<Item = &'_ ()>) -> Option<()> { x.next() } + | error[E0106]: missing lifetime specifier --> $DIR/impl-trait-missing-lifetime-gated.rs:47:37 diff --git a/tests/ui/suggestions/impl-trait-missing-lifetime.stderr b/tests/ui/suggestions/impl-trait-missing-lifetime.stderr index 98b0ab82b3c..c1dbaae0649 100644 --- a/tests/ui/suggestions/impl-trait-missing-lifetime.stderr +++ b/tests/ui/suggestions/impl-trait-missing-lifetime.stderr @@ -13,6 +13,11 @@ help: consider introducing a named lifetime parameter | LL | fn g<'a>(mut x: impl Iterator<Item = &'a ()>) -> Option<&'a ()> { x.next() } | ++++ ~~~ ~~~ +help: alternatively, you might want to return an owned value + | +LL - fn g(mut x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() } +LL + fn g(mut x: impl Iterator<Item = &'_ ()>) -> Option<()> { x.next() } + | error[E0106]: missing lifetime specifier --> $DIR/impl-trait-missing-lifetime.rs:16:60 @@ -29,6 +34,11 @@ help: consider introducing a named lifetime parameter | LL | async fn i<'a>(mut x: impl Iterator<Item = &'a ()>) -> Option<&'a ()> { x.next() } | ++++ ~~~ ~~~ +help: alternatively, you might want to return an owned value + | +LL - async fn i(mut x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() } +LL + async fn i(mut x: impl Iterator<Item = &'_ ()>) -> Option<()> { x.next() } + | error: lifetime may not live long enough --> $DIR/impl-trait-missing-lifetime.rs:16:69 |
