Rollup merge of #106591 - Ezrashaw:attempted-integer-identifer, r=Estebank
suggestion for attempted integer identifier in patterns Fixes #106552 Implemented a suggestion on `E0005` that occurs when no bindings are present and the pattern is a literal integer.
This commit is contained in:
commit
f74044259a
@ -364,3 +364,5 @@ mir_build_suggest_let_else = you might want to use `let else` to handle the {$co
|
||||
[one] variant that isn't
|
||||
*[other] variants that aren't
|
||||
} matched
|
||||
|
||||
mir_build_suggest_attempted_int_lit = alternatively, you could prepend the pattern with an underscore to define a new named variable; identifiers cannot begin with digits
|
||||
|
@ -770,6 +770,8 @@ pub(crate) struct PatternNotCovered<'s, 'tcx> {
|
||||
#[subdiagnostic]
|
||||
pub let_suggestion: Option<SuggestLet>,
|
||||
#[subdiagnostic]
|
||||
pub misc_suggestion: Option<MiscPatternSuggestion>,
|
||||
#[subdiagnostic]
|
||||
pub res_defined_here: Option<ResDefinedHere>,
|
||||
}
|
||||
|
||||
@ -848,3 +850,16 @@ pub enum SuggestLet {
|
||||
count: usize,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
pub enum MiscPatternSuggestion {
|
||||
#[suggestion(
|
||||
mir_build_suggest_attempted_int_lit,
|
||||
code = "_",
|
||||
applicability = "maybe-incorrect"
|
||||
)]
|
||||
AttemptedIntegerLiteral {
|
||||
#[primary_span]
|
||||
start_span: Span,
|
||||
},
|
||||
}
|
||||
|
@ -6,8 +6,9 @@
|
||||
|
||||
use crate::errors::*;
|
||||
|
||||
use hir::{ExprKind, PatKind};
|
||||
use rustc_arena::TypedArena;
|
||||
use rustc_ast::Mutability;
|
||||
use rustc_ast::{LitKind, Mutability};
|
||||
use rustc_errors::{
|
||||
struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, MultiSpan,
|
||||
};
|
||||
@ -389,7 +390,7 @@ fn check_irrefutable(&self, pat: &'tcx Pat<'tcx>, origin: &str, sp: Option<Span>
|
||||
return;
|
||||
}
|
||||
|
||||
let (inform, interpreted_as_const, res_defined_here,let_suggestion) =
|
||||
let (inform, interpreted_as_const, res_defined_here,let_suggestion, misc_suggestion) =
|
||||
if let hir::PatKind::Path(hir::QPath::Resolved(
|
||||
None,
|
||||
hir::Path {
|
||||
@ -413,6 +414,7 @@ fn check_irrefutable(&self, pat: &'tcx Pat<'tcx>, origin: &str, sp: Option<Span>
|
||||
}
|
||||
},
|
||||
None,
|
||||
None,
|
||||
)
|
||||
} else if let Some(span) = sp && self.tcx.sess.source_map().is_span_accessible(span) {
|
||||
let mut bindings = vec![];
|
||||
@ -426,10 +428,19 @@ fn check_irrefutable(&self, pat: &'tcx Pat<'tcx>, origin: &str, sp: Option<Span>
|
||||
let end_span = semi_span.shrink_to_lo();
|
||||
let count = witnesses.len();
|
||||
|
||||
// If the pattern to match is an integer literal:
|
||||
let int_suggestion = if
|
||||
let PatKind::Lit(expr) = &pat.kind
|
||||
&& bindings.is_empty()
|
||||
&& let ExprKind::Lit(Spanned { node: LitKind::Int(_, _), span }) = expr.kind {
|
||||
// Then give a suggestion, the user might've meant to create a binding instead.
|
||||
Some(MiscPatternSuggestion::AttemptedIntegerLiteral { start_span: span.shrink_to_lo() })
|
||||
} else { None };
|
||||
|
||||
let let_suggestion = if bindings.is_empty() {SuggestLet::If{start_span, semi_span, count}} else{ SuggestLet::Else{end_span, count }};
|
||||
(sp.map(|_|Inform), None, None, Some(let_suggestion))
|
||||
(sp.map(|_|Inform), None, None, Some(let_suggestion), int_suggestion)
|
||||
} else{
|
||||
(sp.map(|_|Inform), None, None, None)
|
||||
(sp.map(|_|Inform), None, None, None, None)
|
||||
};
|
||||
|
||||
let adt_defined_here = try {
|
||||
@ -453,6 +464,7 @@ fn check_irrefutable(&self, pat: &'tcx Pat<'tcx>, origin: &str, sp: Option<Span>
|
||||
_p: (),
|
||||
pattern_ty,
|
||||
let_suggestion,
|
||||
misc_suggestion,
|
||||
res_defined_here,
|
||||
adt_defined_here,
|
||||
});
|
||||
|
@ -11,6 +11,10 @@ help: you might want to use `if let` to ignore the variants that aren't matched
|
||||
|
|
||||
LL | A = { if let 0 = 0 { todo!() } 0 },
|
||||
| ++ ~~~~~~~~~~~
|
||||
help: alternatively, you could prepend the pattern with an underscore to define a new named variable; identifiers cannot begin with digits
|
||||
|
|
||||
LL | A = { let _0 = 0; 0 },
|
||||
| +
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -11,6 +11,10 @@ help: you might want to use `if let` to ignore the variants that aren't matched
|
||||
|
|
||||
LL | let x: [i32; { if let 0 = 0 { todo!() } 0 }] = [];
|
||||
| ++ ~~~~~~~~~~~
|
||||
help: alternatively, you could prepend the pattern with an underscore to define a new named variable; identifiers cannot begin with digits
|
||||
|
|
||||
LL | let x: [i32; { let _0 = 0; 0 }] = [];
|
||||
| +
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -11,6 +11,10 @@ help: you might want to use `if let` to ignore the variants that aren't matched
|
||||
|
|
||||
LL | const X: i32 = { if let 0 = 0 { todo!() } 0 };
|
||||
| ++ ~~~~~~~~~~~
|
||||
help: alternatively, you could prepend the pattern with an underscore to define a new named variable; identifiers cannot begin with digits
|
||||
|
|
||||
LL | const X: i32 = { let _0 = 0; 0 };
|
||||
| +
|
||||
|
||||
error[E0005]: refutable pattern in local binding
|
||||
--> $DIR/const-match-check.rs:8:23
|
||||
@ -25,6 +29,10 @@ help: you might want to use `if let` to ignore the variants that aren't matched
|
||||
|
|
||||
LL | static Y: i32 = { if let 0 = 0 { todo!() } 0 };
|
||||
| ++ ~~~~~~~~~~~
|
||||
help: alternatively, you could prepend the pattern with an underscore to define a new named variable; identifiers cannot begin with digits
|
||||
|
|
||||
LL | static Y: i32 = { let _0 = 0; 0 };
|
||||
| +
|
||||
|
||||
error[E0005]: refutable pattern in local binding
|
||||
--> $DIR/const-match-check.rs:13:26
|
||||
@ -39,6 +47,10 @@ help: you might want to use `if let` to ignore the variants that aren't matched
|
||||
|
|
||||
LL | const X: i32 = { if let 0 = 0 { todo!() } 0 };
|
||||
| ++ ~~~~~~~~~~~
|
||||
help: alternatively, you could prepend the pattern with an underscore to define a new named variable; identifiers cannot begin with digits
|
||||
|
|
||||
LL | const X: i32 = { let _0 = 0; 0 };
|
||||
| +
|
||||
|
||||
error[E0005]: refutable pattern in local binding
|
||||
--> $DIR/const-match-check.rs:19:26
|
||||
@ -53,6 +65,10 @@ help: you might want to use `if let` to ignore the variants that aren't matched
|
||||
|
|
||||
LL | const X: i32 = { if let 0 = 0 { todo!() } 0 };
|
||||
| ++ ~~~~~~~~~~~
|
||||
help: alternatively, you could prepend the pattern with an underscore to define a new named variable; identifiers cannot begin with digits
|
||||
|
|
||||
LL | const X: i32 = { let _0 = 0; 0 };
|
||||
| +
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
|
7
tests/ui/pattern/issue-106552.rs
Normal file
7
tests/ui/pattern/issue-106552.rs
Normal file
@ -0,0 +1,7 @@
|
||||
fn main() {
|
||||
let 5 = 6;
|
||||
//~^ error refutable pattern in local binding [E0005]
|
||||
|
||||
let x @ 5 = 6;
|
||||
//~^ error refutable pattern in local binding [E0005]
|
||||
}
|
35
tests/ui/pattern/issue-106552.stderr
Normal file
35
tests/ui/pattern/issue-106552.stderr
Normal file
@ -0,0 +1,35 @@
|
||||
error[E0005]: refutable pattern in local binding
|
||||
--> $DIR/issue-106552.rs:2:9
|
||||
|
|
||||
LL | let 5 = 6;
|
||||
| ^ patterns `i32::MIN..=4_i32` and `6_i32..=i32::MAX` not covered
|
||||
|
|
||||
= note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
|
||||
= note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
|
||||
= note: the matched value is of type `i32`
|
||||
help: you might want to use `if let` to ignore the variants that aren't matched
|
||||
|
|
||||
LL | if let 5 = 6 { todo!() }
|
||||
| ++ ~~~~~~~~~~~
|
||||
help: alternatively, you could prepend the pattern with an underscore to define a new named variable; identifiers cannot begin with digits
|
||||
|
|
||||
LL | let _5 = 6;
|
||||
| +
|
||||
|
||||
error[E0005]: refutable pattern in local binding
|
||||
--> $DIR/issue-106552.rs:5:9
|
||||
|
|
||||
LL | let x @ 5 = 6;
|
||||
| ^^^^^ patterns `i32::MIN..=4_i32` and `6_i32..=i32::MAX` not covered
|
||||
|
|
||||
= note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
|
||||
= note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
|
||||
= note: the matched value is of type `i32`
|
||||
help: you might want to use `let else` to handle the variants that aren't matched
|
||||
|
|
||||
LL | let x @ 5 = 6 else { todo!() };
|
||||
| ++++++++++++++++
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0005`.
|
Loading…
Reference in New Issue
Block a user