preserve brackets around if-lets and skip while-lets
This commit is contained in:
parent
329e7b4d4e
commit
6d1a25ad7e
@ -122,7 +122,11 @@ fn probe_if_cascade<'tcx>(&mut self, cx: &LateContext<'tcx>, mut expr: &'tcx hir
|
|||||||
}
|
}
|
||||||
let tcx = cx.tcx;
|
let tcx = cx.tcx;
|
||||||
let source_map = tcx.sess.source_map();
|
let source_map = tcx.sess.source_map();
|
||||||
let expr_end = expr.span.shrink_to_hi();
|
let expr_end = match expr.kind {
|
||||||
|
hir::ExprKind::If(_cond, conseq, None) => conseq.span.shrink_to_hi(),
|
||||||
|
hir::ExprKind::If(_cond, _conseq, Some(alt)) => alt.span.shrink_to_hi(),
|
||||||
|
_ => return,
|
||||||
|
};
|
||||||
let mut add_bracket_to_match_head = match_head_needs_bracket(tcx, expr);
|
let mut add_bracket_to_match_head = match_head_needs_bracket(tcx, expr);
|
||||||
let mut significant_droppers = vec![];
|
let mut significant_droppers = vec![];
|
||||||
let mut lifetime_ends = vec![];
|
let mut lifetime_ends = vec![];
|
||||||
@ -145,7 +149,10 @@ fn probe_if_cascade<'tcx>(&mut self, cx: &LateContext<'tcx>, mut expr: &'tcx hir
|
|||||||
recovered: Recovered::No,
|
recovered: Recovered::No,
|
||||||
}) = cond.kind
|
}) = cond.kind
|
||||||
{
|
{
|
||||||
let if_let_pat = expr.span.shrink_to_lo().between(init.span);
|
// Peel off round braces
|
||||||
|
let if_let_pat = source_map
|
||||||
|
.span_take_while(expr.span, |&ch| ch == '(' || ch.is_whitespace())
|
||||||
|
.between(init.span);
|
||||||
// The consequent fragment is always a block.
|
// The consequent fragment is always a block.
|
||||||
let before_conseq = conseq.span.shrink_to_lo();
|
let before_conseq = conseq.span.shrink_to_lo();
|
||||||
let lifetime_end = source_map.end_point(conseq.span);
|
let lifetime_end = source_map.end_point(conseq.span);
|
||||||
@ -159,6 +166,8 @@ fn probe_if_cascade<'tcx>(&mut self, cx: &LateContext<'tcx>, mut expr: &'tcx hir
|
|||||||
if ty_ascription.is_some()
|
if ty_ascription.is_some()
|
||||||
|| !expr.span.can_be_used_for_suggestions()
|
|| !expr.span.can_be_used_for_suggestions()
|
||||||
|| !pat.span.can_be_used_for_suggestions()
|
|| !pat.span.can_be_used_for_suggestions()
|
||||||
|
|| !if_let_pat.can_be_used_for_suggestions()
|
||||||
|
|| !before_conseq.can_be_used_for_suggestions()
|
||||||
{
|
{
|
||||||
// Our `match` rewrites does not support type ascription,
|
// Our `match` rewrites does not support type ascription,
|
||||||
// so we just bail.
|
// so we just bail.
|
||||||
@ -240,6 +249,22 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>) {
|
|||||||
if let (Level::Allow, _) = cx.tcx.lint_level_at_node(IF_LET_RESCOPE, expr.hir_id) {
|
if let (Level::Allow, _) = cx.tcx.lint_level_at_node(IF_LET_RESCOPE, expr.hir_id) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if let hir::ExprKind::Loop(block, _label, hir::LoopSource::While, _span) = expr.kind
|
||||||
|
&& let Some(value) = block.expr
|
||||||
|
&& let hir::ExprKind::If(cond, _conseq, _alt) = value.kind
|
||||||
|
&& let hir::ExprKind::Let(..) = cond.kind
|
||||||
|
{
|
||||||
|
// Recall that `while let` is lowered into this:
|
||||||
|
// ```
|
||||||
|
// loop {
|
||||||
|
// if let .. { body } else { break; }
|
||||||
|
// }
|
||||||
|
// ```
|
||||||
|
// There is no observable from the `{ break; }` block so the edition change
|
||||||
|
// means nothing substantial to this `while` statement.
|
||||||
|
self.skip.insert(value.hir_id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if expr_parent_is_stmt(cx.tcx, expr.hir_id)
|
if expr_parent_is_stmt(cx.tcx, expr.hir_id)
|
||||||
&& matches!(expr.kind, hir::ExprKind::If(_cond, _conseq, None))
|
&& matches!(expr.kind, hir::ExprKind::If(_cond, _conseq, None))
|
||||||
{
|
{
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#![deny(if_let_rescope)]
|
#![deny(if_let_rescope)]
|
||||||
#![feature(if_let_rescope)]
|
#![feature(if_let_rescope)]
|
||||||
#![allow(irrefutable_let_patterns)]
|
#![allow(irrefutable_let_patterns, unused_parens)]
|
||||||
|
|
||||||
fn droppy() -> Droppy {
|
fn droppy() -> Droppy {
|
||||||
Droppy
|
Droppy
|
||||||
@ -68,4 +68,17 @@ fn main() {
|
|||||||
//~| HELP: the value is now dropped here in Edition 2024
|
//~| HELP: the value is now dropped here in Edition 2024
|
||||||
//~| HELP: a `match` with a single arm can preserve the drop order up to Edition 2021
|
//~| HELP: a `match` with a single arm can preserve the drop order up to Edition 2021
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (match droppy().get() { Some(_value) => { true } _ => { false }}) {
|
||||||
|
//~^ ERROR: `if let` assigns a shorter lifetime since Edition 2024
|
||||||
|
//~| WARN: this changes meaning in Rust 2024
|
||||||
|
//~| HELP: a `match` with a single arm can preserve the drop order up to Edition 2021
|
||||||
|
//~| HELP: the value is now dropped here in Edition 2024
|
||||||
|
// do something
|
||||||
|
}
|
||||||
|
|
||||||
|
while let Some(_value) = droppy().get() {
|
||||||
|
// Should not lint
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#![deny(if_let_rescope)]
|
#![deny(if_let_rescope)]
|
||||||
#![feature(if_let_rescope)]
|
#![feature(if_let_rescope)]
|
||||||
#![allow(irrefutable_let_patterns)]
|
#![allow(irrefutable_let_patterns, unused_parens)]
|
||||||
|
|
||||||
fn droppy() -> Droppy {
|
fn droppy() -> Droppy {
|
||||||
Droppy
|
Droppy
|
||||||
@ -68,4 +68,17 @@ fn main() {
|
|||||||
//~| HELP: the value is now dropped here in Edition 2024
|
//~| HELP: the value is now dropped here in Edition 2024
|
||||||
//~| HELP: a `match` with a single arm can preserve the drop order up to Edition 2021
|
//~| HELP: a `match` with a single arm can preserve the drop order up to Edition 2021
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (if let Some(_value) = droppy().get() { true } else { false }) {
|
||||||
|
//~^ ERROR: `if let` assigns a shorter lifetime since Edition 2024
|
||||||
|
//~| WARN: this changes meaning in Rust 2024
|
||||||
|
//~| HELP: a `match` with a single arm can preserve the drop order up to Edition 2021
|
||||||
|
//~| HELP: the value is now dropped here in Edition 2024
|
||||||
|
// do something
|
||||||
|
}
|
||||||
|
|
||||||
|
while let Some(_value) = droppy().get() {
|
||||||
|
// Should not lint
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -131,5 +131,25 @@ help: a `match` with a single arm can preserve the drop order up to Edition 2021
|
|||||||
LL | if let () = { match Droppy.get() { Some(_value) => {} _ => {}} } {
|
LL | if let () = { match Droppy.get() { Some(_value) => {} _ => {}} } {
|
||||||
| ~~~~~ +++++++++++++++++ ++++++++
|
| ~~~~~ +++++++++++++++++ ++++++++
|
||||||
|
|
||||||
error: aborting due to 5 previous errors
|
error: `if let` assigns a shorter lifetime since Edition 2024
|
||||||
|
--> $DIR/lint-if-let-rescope.rs:72:12
|
||||||
|
|
|
||||||
|
LL | if (if let Some(_value) = droppy().get() { true } else { false }) {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^--------^^^^^^
|
||||||
|
| |
|
||||||
|
| this value has a significant drop implementation which may observe a major change in drop order and requires your discretion
|
||||||
|
|
|
||||||
|
= warning: this changes meaning in Rust 2024
|
||||||
|
= note: for more information, see issue #124085 <https://github.com/rust-lang/rust/issues/124085>
|
||||||
|
help: the value is now dropped here in Edition 2024
|
||||||
|
--> $DIR/lint-if-let-rescope.rs:72:53
|
||||||
|
|
|
||||||
|
LL | if (if let Some(_value) = droppy().get() { true } else { false }) {
|
||||||
|
| ^
|
||||||
|
help: a `match` with a single arm can preserve the drop order up to Edition 2021
|
||||||
|
|
|
||||||
|
LL | if (match droppy().get() { Some(_value) => { true } _ => { false }}) {
|
||||||
|
| ~~~~~ +++++++++++++++++ ~~~~ +
|
||||||
|
|
||||||
|
error: aborting due to 6 previous errors
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user