mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
Improve irrefutable let-else lint wording
This commit is contained in:
@@ -932,13 +932,14 @@ pub(crate) struct IrrefutableLetPatternsIfLetGuard {
|
||||
)]
|
||||
#[note(
|
||||
"{$count ->
|
||||
[one] this pattern
|
||||
*[other] these patterns
|
||||
} will always match, so the `else` clause is useless"
|
||||
[one] this pattern always matches, so the else clause is unreachable
|
||||
*[other] these patterns always match, so the else clause is unreachable
|
||||
}"
|
||||
)]
|
||||
#[help("consider removing the `else` clause")]
|
||||
pub(crate) struct IrrefutableLetPatternsLetElse {
|
||||
pub(crate) count: usize,
|
||||
#[help("remove this `else` block")]
|
||||
pub(crate) else_span: Option<Span>,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
|
||||
@@ -160,7 +160,7 @@ fn visit_expr(&mut self, ex: &'p Expr<'tcx>) {
|
||||
self.check_match(scrutinee, arms, MatchSource::Normal, span);
|
||||
}
|
||||
ExprKind::Let { box ref pat, expr } => {
|
||||
self.check_let(pat, Some(expr), ex.span);
|
||||
self.check_let(pat, Some(expr), ex.span, None);
|
||||
}
|
||||
ExprKind::LogicalOp { op: LogicalOp::And, .. }
|
||||
if !matches!(self.let_source, LetSource::None) =>
|
||||
@@ -169,7 +169,7 @@ fn visit_expr(&mut self, ex: &'p Expr<'tcx>) {
|
||||
let Ok(()) = self.visit_land(ex, &mut chain_refutabilities) else { return };
|
||||
// Lint only single irrefutable let binding.
|
||||
if let [Some((_, Irrefutable))] = chain_refutabilities[..] {
|
||||
self.lint_single_let(ex.span);
|
||||
self.lint_single_let(ex.span, None);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -184,8 +184,9 @@ fn visit_stmt(&mut self, stmt: &'p Stmt<'tcx>) {
|
||||
self.with_hir_source(hir_id, |this| {
|
||||
let let_source =
|
||||
if else_block.is_some() { LetSource::LetElse } else { LetSource::PlainLet };
|
||||
let else_span = else_block.map(|bid| this.thir.blocks[bid].span);
|
||||
this.with_let_source(let_source, |this| {
|
||||
this.check_let(pattern, initializer, span)
|
||||
this.check_let(pattern, initializer, span, else_span)
|
||||
});
|
||||
visit::walk_stmt(this, stmt);
|
||||
});
|
||||
@@ -426,13 +427,19 @@ fn analyze_patterns(
|
||||
}
|
||||
|
||||
#[instrument(level = "trace", skip(self))]
|
||||
fn check_let(&mut self, pat: &'p Pat<'tcx>, scrutinee: Option<ExprId>, span: Span) {
|
||||
fn check_let(
|
||||
&mut self,
|
||||
pat: &'p Pat<'tcx>,
|
||||
scrutinee: Option<ExprId>,
|
||||
span: Span,
|
||||
else_span: Option<Span>,
|
||||
) {
|
||||
assert!(self.let_source != LetSource::None);
|
||||
let scrut = scrutinee.map(|id| &self.thir[id]);
|
||||
if let LetSource::PlainLet = self.let_source {
|
||||
self.check_binding_is_irrefutable(pat, "local binding", scrut, Some(span));
|
||||
} else if let Ok(Irrefutable) = self.is_let_irrefutable(pat, scrut) {
|
||||
self.lint_single_let(span);
|
||||
self.lint_single_let(span, else_span);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -540,8 +547,15 @@ fn check_match(
|
||||
}
|
||||
|
||||
#[instrument(level = "trace", skip(self))]
|
||||
fn lint_single_let(&mut self, let_span: Span) {
|
||||
report_irrefutable_let_patterns(self.tcx, self.hir_source, self.let_source, 1, let_span);
|
||||
fn lint_single_let(&mut self, let_span: Span, else_span: Option<Span>) {
|
||||
report_irrefutable_let_patterns(
|
||||
self.tcx,
|
||||
self.hir_source,
|
||||
self.let_source,
|
||||
1,
|
||||
let_span,
|
||||
else_span,
|
||||
);
|
||||
}
|
||||
|
||||
fn analyze_binding(
|
||||
@@ -836,6 +850,7 @@ fn report_irrefutable_let_patterns(
|
||||
source: LetSource,
|
||||
count: usize,
|
||||
span: Span,
|
||||
else_span: Option<Span>,
|
||||
) {
|
||||
macro_rules! emit_diag {
|
||||
($lint:tt) => {{
|
||||
@@ -847,7 +862,14 @@ macro_rules! emit_diag {
|
||||
LetSource::None | LetSource::PlainLet | LetSource::Else => bug!(),
|
||||
LetSource::IfLet | LetSource::ElseIfLet => emit_diag!(IrrefutableLetPatternsIfLet),
|
||||
LetSource::IfLetGuard => emit_diag!(IrrefutableLetPatternsIfLetGuard),
|
||||
LetSource::LetElse => emit_diag!(IrrefutableLetPatternsLetElse),
|
||||
LetSource::LetElse => {
|
||||
tcx.emit_node_span_lint(
|
||||
IRREFUTABLE_LET_PATTERNS,
|
||||
id,
|
||||
span,
|
||||
IrrefutableLetPatternsLetElse { count, else_span },
|
||||
);
|
||||
}
|
||||
LetSource::WhileLet => emit_diag!(IrrefutableLetPatternsWhileLet),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
//@ check-pass
|
||||
|
||||
// Regression test for https://github.com/rust-lang/rust/issues/152938
|
||||
// The irrefutable `let...else` diagnostic should explain that the pattern
|
||||
// always matches and point at the `else` block for removal.
|
||||
|
||||
pub fn say_hello(name: Option<String>) {
|
||||
let name_str = Some(name) else { return; };
|
||||
//~^ WARN irrefutable `let...else` pattern
|
||||
drop(name_str);
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
@@ -0,0 +1,16 @@
|
||||
warning: irrefutable `let...else` pattern
|
||||
--> $DIR/let-else-irrefutable-152938.rs:8:5
|
||||
|
|
||||
LL | let name_str = Some(name) else { return; };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: this pattern always matches, so the else clause is unreachable
|
||||
help: remove this `else` block
|
||||
--> $DIR/let-else-irrefutable-152938.rs:8:36
|
||||
|
|
||||
LL | let name_str = Some(name) else { return; };
|
||||
| ^^^^^^^^^^^
|
||||
= note: `#[warn(irrefutable_let_patterns)]` on by default
|
||||
|
||||
warning: 1 warning emitted
|
||||
|
||||
@@ -4,8 +4,12 @@ warning: irrefutable `let...else` pattern
|
||||
LL | let x = 1 else { return };
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= note: this pattern will always match, so the `else` clause is useless
|
||||
= help: consider removing the `else` clause
|
||||
= note: this pattern always matches, so the else clause is unreachable
|
||||
help: remove this `else` block
|
||||
--> $DIR/let-else-irrefutable.rs:4:20
|
||||
|
|
||||
LL | let x = 1 else { return };
|
||||
| ^^^^^^^^^^
|
||||
= note: `#[warn(irrefutable_let_patterns)]` on by default
|
||||
|
||||
warning: irrefutable `let...else` pattern
|
||||
@@ -14,8 +18,16 @@ warning: irrefutable `let...else` pattern
|
||||
LL | let x = 1 else {
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= note: this pattern will always match, so the `else` clause is useless
|
||||
= help: consider removing the `else` clause
|
||||
= note: this pattern always matches, so the else clause is unreachable
|
||||
help: remove this `else` block
|
||||
--> $DIR/let-else-irrefutable.rs:7:20
|
||||
|
|
||||
LL | let x = 1 else {
|
||||
| ____________________^
|
||||
LL | | eprintln!("problem case encountered");
|
||||
LL | | return
|
||||
LL | | };
|
||||
| |_____^
|
||||
|
||||
warning: 2 warnings emitted
|
||||
|
||||
|
||||
@@ -268,8 +268,16 @@ LL | | 1
|
||||
LL | | } else {
|
||||
| |_____^
|
||||
|
|
||||
= note: this pattern will always match, so the `else` clause is useless
|
||||
= help: consider removing the `else` clause
|
||||
= note: this pattern always matches, so the else clause is unreachable
|
||||
help: remove this `else` block
|
||||
--> $DIR/bad-let-else-statement.rs:98:12
|
||||
|
|
||||
LL | } else {
|
||||
| ____________^
|
||||
LL | |
|
||||
LL | | return;
|
||||
LL | | };
|
||||
| |_____^
|
||||
= note: `#[warn(irrefutable_let_patterns)]` on by default
|
||||
|
||||
warning: irrefutable `let...else` pattern
|
||||
@@ -281,8 +289,16 @@ LL | | x
|
||||
LL | | } else {
|
||||
| |_____^
|
||||
|
|
||||
= note: this pattern will always match, so the `else` clause is useless
|
||||
= help: consider removing the `else` clause
|
||||
= note: this pattern always matches, so the else clause is unreachable
|
||||
help: remove this `else` block
|
||||
--> $DIR/bad-let-else-statement.rs:163:12
|
||||
|
|
||||
LL | } else {
|
||||
| ____________^
|
||||
LL | |
|
||||
LL | | return;
|
||||
LL | | };
|
||||
| |_____^
|
||||
|
||||
warning: irrefutable `let...else` pattern
|
||||
--> $DIR/bad-let-else-statement.rs:170:5
|
||||
@@ -290,8 +306,12 @@ warning: irrefutable `let...else` pattern
|
||||
LL | let ok = format_args!("") else { return; };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: this pattern will always match, so the `else` clause is useless
|
||||
= help: consider removing the `else` clause
|
||||
= note: this pattern always matches, so the else clause is unreachable
|
||||
help: remove this `else` block
|
||||
--> $DIR/bad-let-else-statement.rs:170:36
|
||||
|
|
||||
LL | let ok = format_args!("") else { return; };
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
warning: irrefutable `let...else` pattern
|
||||
--> $DIR/bad-let-else-statement.rs:173:5
|
||||
@@ -299,8 +319,12 @@ warning: irrefutable `let...else` pattern
|
||||
LL | let bad = format_args! {""} else { return; };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: this pattern will always match, so the `else` clause is useless
|
||||
= help: consider removing the `else` clause
|
||||
= note: this pattern always matches, so the else clause is unreachable
|
||||
help: remove this `else` block
|
||||
--> $DIR/bad-let-else-statement.rs:173:38
|
||||
|
|
||||
LL | let bad = format_args! {""} else { return; };
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
warning: irrefutable `let...else` pattern
|
||||
--> $DIR/bad-let-else-statement.rs:204:5
|
||||
@@ -311,8 +335,16 @@ LL | | 8
|
||||
LL | | } else {
|
||||
| |_____^
|
||||
|
|
||||
= note: this pattern will always match, so the `else` clause is useless
|
||||
= help: consider removing the `else` clause
|
||||
= note: this pattern always matches, so the else clause is unreachable
|
||||
help: remove this `else` block
|
||||
--> $DIR/bad-let-else-statement.rs:207:12
|
||||
|
|
||||
LL | } else {
|
||||
| ____________^
|
||||
LL | |
|
||||
LL | | return;
|
||||
LL | | };
|
||||
| |_____^
|
||||
|
||||
error: aborting due to 19 previous errors; 5 warnings emitted
|
||||
|
||||
|
||||
@@ -14,8 +14,12 @@ warning: irrefutable `let...else` pattern
|
||||
LL | let x = offset_of!(Foo, field) else { return; };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: this pattern will always match, so the `else` clause is useless
|
||||
= help: consider removing the `else` clause
|
||||
= note: this pattern always matches, so the else clause is unreachable
|
||||
help: remove this `else` block
|
||||
--> $DIR/let-offset-of.rs:17:41
|
||||
|
|
||||
LL | let x = offset_of!(Foo, field) else { return; };
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
warning: 2 warnings emitted
|
||||
|
||||
|
||||
Reference in New Issue
Block a user