From 46b05279dd1c6c82ab1e850220fffb04531b9030 Mon Sep 17 00:00:00 2001 From: fru1tworld Date: Thu, 2 Apr 2026 20:15:33 +0900 Subject: [PATCH] Increase span_look_ahead limit to handle whitespace --- .../rustc_resolve/src/late/diagnostics.rs | 8 ++++-- tests/ui/generics/wrong-number-of-args.stderr | 12 ++++----- ...6-trailing-comma-in-lifetime-suggestion.rs | 18 +++++++++++++ ...ailing-comma-in-lifetime-suggestion.stderr | 25 +++++++++++++++++++ 4 files changed, 55 insertions(+), 8 deletions(-) create mode 100644 tests/ui/lifetimes/E0106-trailing-comma-in-lifetime-suggestion.rs create mode 100644 tests/ui/lifetimes/E0106-trailing-comma-in-lifetime-suggestion.stderr diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index cf048231bd607..3be653f272d9c 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -4064,6 +4064,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { }; let mut spans_suggs: Vec<_> = Vec::new(); + let source_map = self.r.tcx.sess.source_map(); let build_sugg = |lt: MissingLifetime| match lt.kind { MissingLifetimeKind::Underscore => { debug_assert_eq!(lt.count, 1); @@ -4074,9 +4075,12 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { (lt.span.shrink_to_hi(), format!("{existing_name} ")) } MissingLifetimeKind::Comma => { - let sugg: String = std::iter::repeat_n([existing_name.as_str(), ", "], lt.count) - .flatten() + let sugg: String = std::iter::repeat_n(existing_name.as_str(), lt.count) + .intersperse(", ") .collect(); + let is_empty_brackets = + source_map.span_look_ahead(lt.span, ">", Some(50)).is_some(); + let sugg = if is_empty_brackets { sugg } else { format!("{sugg}, ") }; (lt.span.shrink_to_hi(), sugg) } MissingLifetimeKind::Brackets => { diff --git a/tests/ui/generics/wrong-number-of-args.stderr b/tests/ui/generics/wrong-number-of-args.stderr index 554d017d67e33..953cd273eb764 100644 --- a/tests/ui/generics/wrong-number-of-args.stderr +++ b/tests/ui/generics/wrong-number-of-args.stderr @@ -28,8 +28,8 @@ LL | type E = Ty<>; | help: consider introducing a named lifetime parameter | -LL | type E<'a> = Ty<'a, >; - | ++++ +++ +LL | type E<'a> = Ty<'a>; + | ++++ ++ error[E0106]: missing lifetime specifier --> $DIR/wrong-number-of-args.rs:120:22 @@ -55,12 +55,12 @@ LL | type F = Box>; | help: consider making the bound lifetime-generic with a new `'a` lifetime | -LL | type F = Box GenericLifetime<'a, >>; - | +++++++ +++ +LL | type F = Box GenericLifetime<'a>>; + | +++++++ ++ help: consider introducing a named lifetime parameter | -LL | type F<'a> = Box>; - | ++++ +++ +LL | type F<'a> = Box>; + | ++++ ++ error[E0106]: missing lifetime specifier --> $DIR/wrong-number-of-args.rs:163:43 diff --git a/tests/ui/lifetimes/E0106-trailing-comma-in-lifetime-suggestion.rs b/tests/ui/lifetimes/E0106-trailing-comma-in-lifetime-suggestion.rs new file mode 100644 index 0000000000000..acf93ae51cc4d --- /dev/null +++ b/tests/ui/lifetimes/E0106-trailing-comma-in-lifetime-suggestion.rs @@ -0,0 +1,18 @@ +// Regression test for . +// +// When suggesting lifetime parameters for empty angle brackets like `Foo<>`, +// the suggestion should not include a trailing comma (e.g., `Foo<'a>` not `Foo<'a, >`). +// When there are other generic arguments like `Foo`, the trailing comma is needed +// (e.g., `Foo<'a, T>`). + +#![crate_type = "lib"] + +struct Foo<'a>(&'a ()); + +type A = Foo<>; +//~^ ERROR missing lifetime specifier [E0106] + +struct Bar<'a, T>(&'a T); + +type B = Bar; +//~^ ERROR missing lifetime specifier [E0106] diff --git a/tests/ui/lifetimes/E0106-trailing-comma-in-lifetime-suggestion.stderr b/tests/ui/lifetimes/E0106-trailing-comma-in-lifetime-suggestion.stderr new file mode 100644 index 0000000000000..f189c259d65f9 --- /dev/null +++ b/tests/ui/lifetimes/E0106-trailing-comma-in-lifetime-suggestion.stderr @@ -0,0 +1,25 @@ +error[E0106]: missing lifetime specifier + --> $DIR/E0106-trailing-comma-in-lifetime-suggestion.rs:12:13 + | +LL | type A = Foo<>; + | ^ expected named lifetime parameter + | +help: consider introducing a named lifetime parameter + | +LL | type A<'a> = Foo<'a>; + | ++++ ++ + +error[E0106]: missing lifetime specifier + --> $DIR/E0106-trailing-comma-in-lifetime-suggestion.rs:17:13 + | +LL | type B = Bar; + | ^ expected named lifetime parameter + | +help: consider introducing a named lifetime parameter + | +LL | type B<'a> = Bar<'a, u8>; + | ++++ +++ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0106`.