From eb186bb745a8c42fc64c0e3dde695816d38908b9 Mon Sep 17 00:00:00 2001 From: GTimothy <22472919+GTimothy@users.noreply.github.com> Date: Sun, 31 May 2026 20:25:17 +0200 Subject: [PATCH] add suggestion for detect_missing_binding_available_from_pattern When a pattern has `..` and a matching binding, suggest replacing `..` with `binding, ..` bless tests Co-authored-by: Roland Xu --- compiler/rustc_resolve/src/late.rs | 7 ++++++- compiler/rustc_resolve/src/late/diagnostics.rs | 14 +++++++++++--- ...attern-with-missing-fields-resolve-error.stderr | 9 +++++++++ 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index c21d3653a13be..0fe0aad06e6cc 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -286,7 +286,8 @@ impl RibKind<'_> { #[derive(Debug)] pub(crate) struct Rib<'ra, R = Res> { pub bindings: FxIndexMap, - pub patterns_with_skipped_bindings: UnordMap)>>, + pub patterns_with_skipped_bindings: + UnordMap, Result<(), ErrorGuaranteed>)>>, pub kind: RibKind<'ra>, } @@ -4309,6 +4310,10 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { .or_default() .push(( pat.span, + match rest { + ast::PatFieldsRest::Rest(span) => Some(*span), + _ => None, + }, match rest { ast::PatFieldsRest::Recovered(guar) => Err(*guar), _ => Ok(()), diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index b126272583692..18145a85174ba 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -1602,11 +1602,11 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { { for field in fields { if field.name == segment.ident.name { - if spans.iter().all(|(_, had_error)| had_error.is_err()) { + if spans.iter().all(|(.., had_error)| had_error.is_err()) { // This resolution error will likely be fixed by fixing a // syntax error in a pattern, so it is irrelevant to the user. let multispan: MultiSpan = - spans.iter().map(|(s, _)| *s).collect::>().into(); + spans.iter().map(|(s, ..)| *s).collect::>().into(); err.span_note( multispan, "this pattern had a recovered parse error which likely lost \ @@ -1615,7 +1615,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { err.downgrade_to_delayed_bug(); } let ty = self.r.tcx.item_name(*def_id); - for (span, _) in spans { + for (span, rest_span, _) in spans { err.span_label( *span, format!( @@ -1623,6 +1623,14 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { available in `{ty}`", ), ); + if let Some(rest_span) = rest_span { + err.span_suggestion_verbose( + *rest_span, + format!("include `{field}` in the pattern"), + format!("{field}, .."), + Applicability::MaybeIncorrect, + ); + } } } } diff --git a/tests/ui/pattern/struct-pattern-with-missing-fields-resolve-error.stderr b/tests/ui/pattern/struct-pattern-with-missing-fields-resolve-error.stderr index b8c6f1d867a19..8cfc52bf8d8ea 100644 --- a/tests/ui/pattern/struct-pattern-with-missing-fields-resolve-error.stderr +++ b/tests/ui/pattern/struct-pattern-with-missing-fields-resolve-error.stderr @@ -13,6 +13,11 @@ LL | if let Website { url, .. } = website { | ------------------- this pattern doesn't include `title`, which is available in `Website` LL | println!("[{}]({})", title, url); | ^^^^^ not found in this scope + | +help: include `title` in the pattern + | +LL | if let Website { url, title, .. } = website { + | ++++++ error[E0425]: cannot find value `a` in this scope --> $DIR/struct-pattern-with-missing-fields-resolve-error.rs:28:20 @@ -22,6 +27,10 @@ LL | if let Foo::Bar { .. } = x { LL | println!("{a}"); | ^ | +help: include `a` in the pattern + | +LL | if let Foo::Bar { a, .. } = x { + | ++ help: a local variable with a similar name exists | LL - println!("{a}");