diff options
| author | Esteban Küber <esteban@kuber.com.ar> | 2025-08-24 19:22:51 +0000 |
|---|---|---|
| committer | Esteban Küber <esteban@kuber.com.ar> | 2025-08-25 15:16:25 +0000 |
| commit | 8dbdb1760b23112f87aedad37e4dad97559bc750 (patch) | |
| tree | dd2cd17a9704e56eac5416f6c5c9883ebd6deaf5 | |
| parent | 41a79f1862aa6b81bac674598e275e80e9f09eb9 (diff) | |
| download | rust-8dbdb1760b23112f87aedad37e4dad97559bc750.tar.gz rust-8dbdb1760b23112f87aedad37e4dad97559bc750.zip | |
On binding not present in all patterns, suggest potential typo
```
error[E0408]: variable `Ban` is not bound in all patterns
--> f12.rs:9:9
|
9 | (Foo,Bar)|(Ban,Foo) => {}
| ^^^^^^^^^ --- variable not in all patterns
| |
| pattern doesn't bind `Ban`
|
help: you might have meant to use the similarly named previously used binding `Bar`
|
9 - (Foo,Bar)|(Ban,Foo) => {}
9 + (Foo,Bar)|(Bar,Foo) => {}
|
```
| -rw-r--r-- | compiler/rustc_resolve/messages.ftl | 2 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/diagnostics.rs | 53 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/errors.rs | 12 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/late.rs | 52 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/lib.rs | 4 | ||||
| -rw-r--r-- | tests/ui/or-patterns/mismatched-bindings-async-fn.stderr | 24 | ||||
| -rw-r--r-- | tests/ui/or-patterns/missing-bindings.stderr | 81 | ||||
| -rw-r--r-- | tests/ui/or-patterns/nested-undelimited-precedence.stderr | 6 | ||||
| -rw-r--r-- | tests/ui/pattern/rfc-3637-guard-patterns/name-resolution.stderr | 12 | ||||
| -rw-r--r-- | tests/ui/resolve/resolve-inconsistent-names.rs | 6 | ||||
| -rw-r--r-- | tests/ui/resolve/resolve-inconsistent-names.stderr | 46 | ||||
| -rw-r--r-- | tests/ui/span/issue-39698.stderr | 24 |
12 files changed, 268 insertions, 54 deletions
diff --git a/compiler/rustc_resolve/messages.ftl b/compiler/rustc_resolve/messages.ftl index 47280a93677..0e566e20a12 100644 --- a/compiler/rustc_resolve/messages.ftl +++ b/compiler/rustc_resolve/messages.ftl @@ -470,6 +470,8 @@ resolve_variable_bound_with_different_mode = .label = bound in different ways .first_binding_span = first binding +resolve_variable_is_a_typo = you might have meant to use the similarly named previously used binding `{$typo}` + resolve_variable_is_not_bound_in_all_patterns = variable `{$name}` is not bound in all patterns diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 337e7d2dd86..324310ff48b 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -661,8 +661,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ResolutionError::VariableNotBoundInPattern(binding_error, parent_scope) => { let BindingError { name, target, origin, could_be_path } = binding_error; - let target_sp = target.iter().copied().collect::<Vec<_>>(); - let origin_sp = origin.iter().copied().collect::<Vec<_>>(); + let mut target_sp = target.iter().map(|pat| pat.span).collect::<Vec<_>>(); + target_sp.sort(); + target_sp.dedup(); + let mut origin_sp = origin.iter().map(|(span, _)| *span).collect::<Vec<_>>(); + origin_sp.sort(); + origin_sp.dedup(); let msp = MultiSpan::from_spans(target_sp.clone()); let mut err = self @@ -671,8 +675,29 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { for sp in target_sp { err.subdiagnostic(errors::PatternDoesntBindName { span: sp, name }); } - for sp in origin_sp { - err.subdiagnostic(errors::VariableNotInAllPatterns { span: sp }); + for sp in &origin_sp { + err.subdiagnostic(errors::VariableNotInAllPatterns { span: *sp }); + } + let mut target_visitor = BindingVisitor::default(); + for pat in &target { + target_visitor.visit_pat(pat); + } + target_visitor.identifiers.sort(); + target_visitor.identifiers.dedup(); + let mut origin_visitor = BindingVisitor::default(); + for (_, pat) in &origin { + origin_visitor.visit_pat(pat); + } + origin_visitor.identifiers.sort(); + origin_visitor.identifiers.dedup(); + // Find if the binding could have been a typo + let mut suggested_typo = false; + if let Some(typo) = + find_best_match_for_name(&target_visitor.identifiers, name.name, None) + && !origin_visitor.identifiers.contains(&typo) + { + err.subdiagnostic(errors::PatternBindingTypo { spans: origin_sp, typo }); + suggested_typo = true; } if could_be_path { let import_suggestions = self.lookup_import_candidates( @@ -693,7 +718,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { }, ); - if import_suggestions.is_empty() { + if import_suggestions.is_empty() && !suggested_typo { let help_msg = format!( "if you meant to match on a variant or a `const` item, consider \ making the path in the pattern qualified: `path::to::ModOrType::{name}`", @@ -3395,7 +3420,7 @@ impl UsePlacementFinder { } } -impl<'tcx> visit::Visitor<'tcx> for UsePlacementFinder { +impl<'tcx> Visitor<'tcx> for UsePlacementFinder { fn visit_crate(&mut self, c: &Crate) { if self.target_module == CRATE_NODE_ID { let inject = c.spans.inject_use_span; @@ -3423,6 +3448,22 @@ impl<'tcx> visit::Visitor<'tcx> for UsePlacementFinder { } } +#[derive(Default)] +struct BindingVisitor { + identifiers: Vec<Symbol>, + spans: FxHashMap<Symbol, Vec<Span>>, +} + +impl<'tcx> Visitor<'tcx> for BindingVisitor { + fn visit_pat(&mut self, pat: &ast::Pat) { + if let ast::PatKind::Ident(_, ident, _) = pat.kind { + self.identifiers.push(ident.name); + self.spans.entry(ident.name).or_default().push(ident.span); + } + visit::walk_pat(self, pat); + } +} + fn search_for_any_use_in_items(items: &[Box<ast::Item>]) -> Option<Span> { for item in items { if let ItemKind::Use(..) = item.kind diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs index 63d6fa23a14..72be94e58db 100644 --- a/compiler/rustc_resolve/src/errors.rs +++ b/compiler/rustc_resolve/src/errors.rs @@ -986,6 +986,18 @@ pub(crate) struct VariableNotInAllPatterns { pub(crate) span: Span, } +#[derive(Subdiagnostic)] +#[multipart_suggestion( + resolve_variable_is_a_typo, + applicability = "maybe-incorrect", + style = "verbose" +)] +pub(crate) struct PatternBindingTypo { + #[suggestion_part(code = "{typo}")] + pub(crate) spans: Vec<Span>, + pub(crate) typo: Symbol, +} + #[derive(Diagnostic)] #[diag(resolve_name_defined_multiple_time)] #[note] diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 679e663f886..6f1bd4572dd 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -8,7 +8,6 @@ use std::assert_matches::debug_assert_matches; use std::borrow::Cow; -use std::collections::BTreeSet; use std::collections::hash_map::Entry; use std::mem::{replace, swap, take}; @@ -3682,31 +3681,30 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { // 2) Record any missing bindings or binding mode inconsistencies. for (map_outer, pat_outer) in not_never_pats.iter() { // Check against all arms except for the same pattern which is always self-consistent. - let inners = not_never_pats - .iter() - .filter(|(_, pat)| pat.id != pat_outer.id) - .flat_map(|(map, _)| map); - - for (&name, binding_inner) in inners { - match map_outer.get(&name) { - None => { - // The inner binding is missing in the outer. - let binding_error = - missing_vars.entry(name).or_insert_with(|| BindingError { - name, - origin: BTreeSet::new(), - target: BTreeSet::new(), - could_be_path: name.as_str().starts_with(char::is_uppercase), - }); - binding_error.origin.insert(binding_inner.span); - binding_error.target.insert(pat_outer.span); - } - Some(binding_outer) => { - if binding_outer.annotation != binding_inner.annotation { - // The binding modes in the outer and inner bindings differ. - inconsistent_vars - .entry(name) - .or_insert((binding_inner.span, binding_outer.span)); + let inners = not_never_pats.iter().filter(|(_, pat)| pat.id != pat_outer.id); + + for (map, pat) in inners { + for (&name, binding_inner) in map { + match map_outer.get(&name) { + None => { + // The inner binding is missing in the outer. + let binding_error = + missing_vars.entry(name).or_insert_with(|| BindingError { + name, + origin: Default::default(), + target: Default::default(), + could_be_path: name.as_str().starts_with(char::is_uppercase), + }); + binding_error.origin.push((binding_inner.span, (***pat).clone())); + binding_error.target.push((***pat_outer).clone()); + } + Some(binding_outer) => { + if binding_outer.annotation != binding_inner.annotation { + // The binding modes in the outer and inner bindings differ. + inconsistent_vars + .entry(name) + .or_insert((binding_inner.span, binding_outer.span)); + } } } } @@ -3719,7 +3717,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { v.could_be_path = false; } self.report_error( - *v.origin.iter().next().unwrap(), + v.origin.iter().next().unwrap().0, ResolutionError::VariableNotBoundInPattern(v, self.parent_scope), ); } diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 2afb52ef4d4..c36a6883300 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -230,8 +230,8 @@ enum Used { #[derive(Debug)] struct BindingError { name: Ident, - origin: BTreeSet<Span>, - target: BTreeSet<Span>, + origin: Vec<(Span, ast::Pat)>, + target: Vec<ast::Pat>, could_be_path: bool, } diff --git a/tests/ui/or-patterns/mismatched-bindings-async-fn.stderr b/tests/ui/or-patterns/mismatched-bindings-async-fn.stderr index 81602fffa8d..523cdf959e7 100644 --- a/tests/ui/or-patterns/mismatched-bindings-async-fn.stderr +++ b/tests/ui/or-patterns/mismatched-bindings-async-fn.stderr @@ -5,6 +5,12 @@ LL | async fn a((x | s): String) {} | ^ - variable not in all patterns | | | pattern doesn't bind `s` + | +help: you might have meant to use the similarly named previously used binding `x` + | +LL - async fn a((x | s): String) {} +LL + async fn a((x | x): String) {} + | error[E0408]: variable `x` is not bound in all patterns --> $DIR/mismatched-bindings-async-fn.rs:4:17 @@ -13,6 +19,12 @@ LL | async fn a((x | s): String) {} | - ^ pattern doesn't bind `x` | | | variable not in all patterns + | +help: you might have meant to use the similarly named previously used binding `s` + | +LL - async fn a((x | s): String) {} +LL + async fn a((s | s): String) {} + | error[E0408]: variable `s` is not bound in all patterns --> $DIR/mismatched-bindings-async-fn.rs:9:10 @@ -21,6 +33,12 @@ LL | let (x | s) = String::new(); | ^ - variable not in all patterns | | | pattern doesn't bind `s` + | +help: you might have meant to use the similarly named previously used binding `x` + | +LL - let (x | s) = String::new(); +LL + let (x | x) = String::new(); + | error[E0408]: variable `x` is not bound in all patterns --> $DIR/mismatched-bindings-async-fn.rs:9:14 @@ -29,6 +47,12 @@ LL | let (x | s) = String::new(); | - ^ pattern doesn't bind `x` | | | variable not in all patterns + | +help: you might have meant to use the similarly named previously used binding `s` + | +LL - let (x | s) = String::new(); +LL + let (s | s) = String::new(); + | error: aborting due to 4 previous errors diff --git a/tests/ui/or-patterns/missing-bindings.stderr b/tests/ui/or-patterns/missing-bindings.stderr index 6288cc58913..636f7016647 100644 --- a/tests/ui/or-patterns/missing-bindings.stderr +++ b/tests/ui/or-patterns/missing-bindings.stderr @@ -86,6 +86,12 @@ LL | let (A(A(a, b) | B(c), d) | B(e)) = Y; | ^^^^^^^ - variable not in all patterns | | | pattern doesn't bind `c` + | +help: you might have meant to use the similarly named previously used binding `a` + | +LL - let (A(A(a, b) | B(c), d) | B(e)) = Y; +LL + let (A(A(a, b) | B(a), d) | B(e)) = Y; + | error[E0408]: variable `a` is not bound in all patterns --> $DIR/missing-bindings.rs:47:22 @@ -94,6 +100,12 @@ LL | let (A(A(a, b) | B(c), d) | B(e)) = Y; | - ^^^^ pattern doesn't bind `a` | | | variable not in all patterns + | +help: you might have meant to use the similarly named previously used binding `c` + | +LL - let (A(A(a, b) | B(c), d) | B(e)) = Y; +LL + let (A(A(c, b) | B(c), d) | B(e)) = Y; + | error[E0408]: variable `b` is not bound in all patterns --> $DIR/missing-bindings.rs:47:22 @@ -102,6 +114,12 @@ LL | let (A(A(a, b) | B(c), d) | B(e)) = Y; | - ^^^^ pattern doesn't bind `b` | | | variable not in all patterns + | +help: you might have meant to use the similarly named previously used binding `c` + | +LL - let (A(A(a, b) | B(c), d) | B(e)) = Y; +LL + let (A(A(a, c) | B(c), d) | B(e)) = Y; + | error[E0408]: variable `e` is not bound in all patterns --> $DIR/missing-bindings.rs:47:10 @@ -110,6 +128,12 @@ LL | let (A(A(a, b) | B(c), d) | B(e)) = Y; | ^^^^^^^^^^^^^^^^^^^^ - variable not in all patterns | | | pattern doesn't bind `e` + | +help: you might have meant to use the similarly named previously used binding `c` + | +LL - let (A(A(a, b) | B(c), d) | B(e)) = Y; +LL + let (A(A(a, b) | B(c), d) | B(c)) = Y; + | error[E0408]: variable `a` is not bound in all patterns --> $DIR/missing-bindings.rs:47:33 @@ -118,6 +142,12 @@ LL | let (A(A(a, b) | B(c), d) | B(e)) = Y; | - ^^^^ pattern doesn't bind `a` | | | variable not in all patterns + | +help: you might have meant to use the similarly named previously used binding `e` + | +LL - let (A(A(a, b) | B(c), d) | B(e)) = Y; +LL + let (A(A(e, b) | B(c), d) | B(e)) = Y; + | error[E0408]: variable `b` is not bound in all patterns --> $DIR/missing-bindings.rs:47:33 @@ -126,6 +156,12 @@ LL | let (A(A(a, b) | B(c), d) | B(e)) = Y; | - ^^^^ pattern doesn't bind `b` | | | variable not in all patterns + | +help: you might have meant to use the similarly named previously used binding `e` + | +LL - let (A(A(a, b) | B(c), d) | B(e)) = Y; +LL + let (A(A(a, e) | B(c), d) | B(e)) = Y; + | error[E0408]: variable `c` is not bound in all patterns --> $DIR/missing-bindings.rs:47:33 @@ -134,6 +170,12 @@ LL | let (A(A(a, b) | B(c), d) | B(e)) = Y; | - ^^^^ pattern doesn't bind `c` | | | variable not in all patterns + | +help: you might have meant to use the similarly named previously used binding `e` + | +LL - let (A(A(a, b) | B(c), d) | B(e)) = Y; +LL + let (A(A(a, b) | B(e), d) | B(e)) = Y; + | error[E0408]: variable `d` is not bound in all patterns --> $DIR/missing-bindings.rs:47:33 @@ -142,6 +184,12 @@ LL | let (A(A(a, b) | B(c), d) | B(e)) = Y; | - ^^^^ pattern doesn't bind `d` | | | variable not in all patterns + | +help: you might have meant to use the similarly named previously used binding `e` + | +LL - let (A(A(a, b) | B(c), d) | B(e)) = Y; +LL + let (A(A(a, b) | B(c), e) | B(e)) = Y; + | error[E0408]: variable `a` is not bound in all patterns --> $DIR/missing-bindings.rs:63:29 @@ -158,6 +206,12 @@ LL | A(_, a) | | ^^^^^^^ pattern doesn't bind `b` LL | B(b), | - variable not in all patterns + | +help: you might have meant to use the similarly named previously used binding `a` + | +LL - B(b), +LL + B(a), + | error[E0408]: variable `a` is not bound in all patterns --> $DIR/missing-bindings.rs:71:21 @@ -166,6 +220,12 @@ LL | A(_, a) | | - variable not in all patterns LL | B(b), | ^^^^ pattern doesn't bind `a` + | +help: you might have meant to use the similarly named previously used binding `b` + | +LL - A(_, a) | +LL + A(_, b) | + | error[E0408]: variable `a` is not bound in all patterns --> $DIR/missing-bindings.rs:74:17 @@ -202,6 +262,12 @@ LL | B(b), ... LL | V3(c), | ^^^^^ pattern doesn't bind `b` + | +help: you might have meant to use the similarly named previously used binding `c` + | +LL - B(b), +LL + B(c), + | error[E0408]: variable `c` is not bound in all patterns --> $DIR/missing-bindings.rs:59:13 @@ -223,6 +289,12 @@ LL | | ) | | |_____________^ pattern doesn't bind `c` LL | V3(c), | - variable not in all patterns + | +help: you might have meant to use the similarly named previously used binding `a` + | +LL - V3(c), +LL + V3(a), + | error[E0408]: variable `a` is not bound in all patterns --> $DIR/missing-bindings.rs:78:13 @@ -235,6 +307,15 @@ LL | A(_, a) | ... LL | V3(c), | ^^^^^ pattern doesn't bind `a` + | +help: you might have meant to use the similarly named previously used binding `c` + | +LL ~ B(Ok(a) | Err(c)) +LL | ) | +LL | V2( +LL | A( +LL ~ A(_, c) | + | error[E0170]: pattern binding `beta` is named the same as one of the variants of the type `check_handling_of_paths::bar::foo` --> $DIR/missing-bindings.rs:19:18 diff --git a/tests/ui/or-patterns/nested-undelimited-precedence.stderr b/tests/ui/or-patterns/nested-undelimited-precedence.stderr index 0835ca1929f..10dbc9d16c0 100644 --- a/tests/ui/or-patterns/nested-undelimited-precedence.stderr +++ b/tests/ui/or-patterns/nested-undelimited-precedence.stderr @@ -60,6 +60,12 @@ LL | let b @ A | B: E = A; | - ^ pattern doesn't bind `b` | | | variable not in all patterns + | +help: you might have meant to use the similarly named previously used binding `B` + | +LL - let b @ A | B: E = A; +LL + let B @ A | B: E = A; + | error[E0308]: mismatched types --> $DIR/nested-undelimited-precedence.rs:34:9 diff --git a/tests/ui/pattern/rfc-3637-guard-patterns/name-resolution.stderr b/tests/ui/pattern/rfc-3637-guard-patterns/name-resolution.stderr index d76e60478a1..a5d9fd2b1a6 100644 --- a/tests/ui/pattern/rfc-3637-guard-patterns/name-resolution.stderr +++ b/tests/ui/pattern/rfc-3637-guard-patterns/name-resolution.stderr @@ -5,6 +5,12 @@ LL | ((Ok(x) if y) | (Err(y) if x),) => x && y, | ^^^^^^^^^^^^ - variable not in all patterns | | | pattern doesn't bind `y` + | +help: you might have meant to use the similarly named previously used binding `x` + | +LL - ((Ok(x) if y) | (Err(y) if x),) => x && y, +LL + ((Ok(x) if y) | (Err(x) if x),) => x && y, + | error[E0408]: variable `x` is not bound in all patterns --> $DIR/name-resolution.rs:37:25 @@ -13,6 +19,12 @@ LL | ((Ok(x) if y) | (Err(y) if x),) => x && y, | - ^^^^^^^^^^^^^ pattern doesn't bind `x` | | | variable not in all patterns + | +help: you might have meant to use the similarly named previously used binding `y` + | +LL - ((Ok(x) if y) | (Err(y) if x),) => x && y, +LL + ((Ok(y) if y) | (Err(y) if x),) => x && y, + | error[E0408]: variable `x` is not bound in all patterns --> $DIR/name-resolution.rs:63:28 diff --git a/tests/ui/resolve/resolve-inconsistent-names.rs b/tests/ui/resolve/resolve-inconsistent-names.rs index 9a40b20346c..bf74a4ba0f3 100644 --- a/tests/ui/resolve/resolve-inconsistent-names.rs +++ b/tests/ui/resolve/resolve-inconsistent-names.rs @@ -10,8 +10,10 @@ pub mod m { fn main() { let y = 1; match y { - a | b => {} //~ ERROR variable `a` is not bound in all patterns - //~| ERROR variable `b` is not bound in all patterns + a | b => {} //~ ERROR variable `a` is not bound in all patterns + //~| ERROR variable `b` is not bound in all patterns + //~| HELP you might have meant to use the similarly named previously used binding `a` + //~| HELP you might have meant to use the similarly named previously used binding `b` } let x = (E::A, E::B); diff --git a/tests/ui/resolve/resolve-inconsistent-names.stderr b/tests/ui/resolve/resolve-inconsistent-names.stderr index 5fac622eef2..152c16ad404 100644 --- a/tests/ui/resolve/resolve-inconsistent-names.stderr +++ b/tests/ui/resolve/resolve-inconsistent-names.stderr @@ -1,21 +1,33 @@ error[E0408]: variable `b` is not bound in all patterns - --> $DIR/resolve-inconsistent-names.rs:13:8 + --> $DIR/resolve-inconsistent-names.rs:13:9 + | +LL | a | b => {} + | ^ - variable not in all patterns + | | + | pattern doesn't bind `b` + | +help: you might have meant to use the similarly named previously used binding `a` + | +LL - a | b => {} +LL + a | a => {} | -LL | a | b => {} - | ^ - variable not in all patterns - | | - | pattern doesn't bind `b` error[E0408]: variable `a` is not bound in all patterns - --> $DIR/resolve-inconsistent-names.rs:13:12 + --> $DIR/resolve-inconsistent-names.rs:13:13 + | +LL | a | b => {} + | - ^ pattern doesn't bind `a` + | | + | variable not in all patterns + | +help: you might have meant to use the similarly named previously used binding `b` + | +LL - a | b => {} +LL + b | b => {} | -LL | a | b => {} - | - ^ pattern doesn't bind `a` - | | - | variable not in all patterns error[E0408]: variable `c` is not bound in all patterns - --> $DIR/resolve-inconsistent-names.rs:19:9 + --> $DIR/resolve-inconsistent-names.rs:21:9 | LL | (A, B) | (ref B, c) | (c, A) => () | ^^^^^^ - - variable not in all patterns @@ -24,7 +36,7 @@ LL | (A, B) | (ref B, c) | (c, A) => () | pattern doesn't bind `c` error[E0408]: variable `A` is not bound in all patterns - --> $DIR/resolve-inconsistent-names.rs:19:18 + --> $DIR/resolve-inconsistent-names.rs:21:18 | LL | (A, B) | (ref B, c) | (c, A) => () | - ^^^^^^^^^^ - variable not in all patterns @@ -38,7 +50,7 @@ LL | (E::A, B) | (ref B, c) | (c, A) => () | +++ error[E0408]: variable `B` is not bound in all patterns - --> $DIR/resolve-inconsistent-names.rs:19:31 + --> $DIR/resolve-inconsistent-names.rs:21:31 | LL | (A, B) | (ref B, c) | (c, A) => () | - - ^^^^^^ pattern doesn't bind `B` @@ -47,7 +59,7 @@ LL | (A, B) | (ref B, c) | (c, A) => () | variable not in all patterns error[E0409]: variable `B` is bound inconsistently across alternatives separated by `|` - --> $DIR/resolve-inconsistent-names.rs:19:23 + --> $DIR/resolve-inconsistent-names.rs:21:23 | LL | (A, B) | (ref B, c) | (c, A) => () | - ^ bound in different ways @@ -55,7 +67,7 @@ LL | (A, B) | (ref B, c) | (c, A) => () | first binding error[E0408]: variable `Const2` is not bound in all patterns - --> $DIR/resolve-inconsistent-names.rs:31:9 + --> $DIR/resolve-inconsistent-names.rs:33:9 | LL | (CONST1, _) | (_, Const2) => () | ^^^^^^^^^^^ ------ variable not in all patterns @@ -68,7 +80,7 @@ LL | (CONST1, _) | (_, m::Const2) => () | +++ error[E0408]: variable `CONST1` is not bound in all patterns - --> $DIR/resolve-inconsistent-names.rs:31:23 + --> $DIR/resolve-inconsistent-names.rs:33:23 | LL | (CONST1, _) | (_, Const2) => () | ------ ^^^^^^^^^^^ pattern doesn't bind `CONST1` @@ -82,7 +94,7 @@ LL | const CONST1: usize = 10; | ^^^^^^^^^^^^^^^^^^^^^^^^^ not accessible error[E0308]: mismatched types - --> $DIR/resolve-inconsistent-names.rs:19:19 + --> $DIR/resolve-inconsistent-names.rs:21:19 | LL | match x { | - this expression has type `(E, E)` diff --git a/tests/ui/span/issue-39698.stderr b/tests/ui/span/issue-39698.stderr index 73fcc5c8477..eb18969c3c0 100644 --- a/tests/ui/span/issue-39698.stderr +++ b/tests/ui/span/issue-39698.stderr @@ -7,6 +7,12 @@ LL | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?} | | | pattern doesn't bind `b` | | variable not in all patterns | pattern doesn't bind `b` + | +help: you might have meant to use the similarly named previously used binding `c` + | +LL - T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); } +LL + T::T1(a, d) | T::T2(d, c) | T::T3(c) | T::T4(a) => { println!("{:?}", a); } + | error[E0408]: variable `c` is not bound in all patterns --> $DIR/issue-39698.rs:10:9 @@ -17,6 +23,12 @@ LL | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?} | | | variable not in all patterns | | pattern doesn't bind `c` | pattern doesn't bind `c` + | +help: you might have meant to use the similarly named previously used binding `d` + | +LL - T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); } +LL + T::T1(a, d) | T::T2(d, b) | T::T3(d) | T::T4(a) => { println!("{:?}", a); } + | error[E0408]: variable `a` is not bound in all patterns --> $DIR/issue-39698.rs:10:23 @@ -27,6 +39,12 @@ LL | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?} | | | pattern doesn't bind `a` | | pattern doesn't bind `a` | variable not in all patterns + | +help: you might have meant to use the similarly named previously used binding `c` + | +LL - T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); } +LL + T::T1(c, d) | T::T2(d, b) | T::T3(c) | T::T4(c) => { println!("{:?}", a); } + | error[E0408]: variable `d` is not bound in all patterns --> $DIR/issue-39698.rs:10:37 @@ -37,6 +55,12 @@ LL | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?} | | | pattern doesn't bind `d` | | variable not in all patterns | variable not in all patterns + | +help: you might have meant to use the similarly named previously used binding `c` + | +LL - T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); } +LL + T::T1(a, c) | T::T2(c, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); } + | error[E0381]: used binding `a` is possibly-uninitialized --> $DIR/issue-39698.rs:10:79 |
