fix #103435, unused lint won't produce invalid code
This commit is contained in:
parent
9be2f35a4c
commit
c0447b489b
@ -565,10 +565,26 @@ fn emit_unused_delims(
|
||||
lint.set_arg("delim", Self::DELIM_STR);
|
||||
lint.set_arg("item", msg);
|
||||
if let Some((lo, hi)) = spans {
|
||||
let replacement = vec![
|
||||
(lo, if keep_space.0 { " ".into() } else { "".into() }),
|
||||
(hi, if keep_space.1 { " ".into() } else { "".into() }),
|
||||
];
|
||||
let sm = cx.sess().source_map();
|
||||
let lo_replace =
|
||||
if keep_space.0 &&
|
||||
let Ok(snip) = sm.span_to_snippet(lo.with_lo(lo.lo() - BytePos(1))) &&
|
||||
!snip.starts_with(" ") {
|
||||
" ".to_string()
|
||||
} else {
|
||||
"".to_string()
|
||||
};
|
||||
|
||||
let hi_replace =
|
||||
if keep_space.1 &&
|
||||
let Ok(snip) = sm.span_to_snippet(sm.next_point(hi)) &&
|
||||
!snip.starts_with(" ") {
|
||||
" ".to_string()
|
||||
} else {
|
||||
"".to_string()
|
||||
};
|
||||
|
||||
let replacement = vec![(lo, lo_replace), (hi, hi_replace)];
|
||||
lint.multipart_suggestion(
|
||||
fluent::suggestion,
|
||||
replacement,
|
||||
@ -765,6 +781,7 @@ fn check_unused_parens_pat(
|
||||
value: &ast::Pat,
|
||||
avoid_or: bool,
|
||||
avoid_mut: bool,
|
||||
keep_space: (bool, bool),
|
||||
) {
|
||||
use ast::{BindingAnnotation, PatKind};
|
||||
|
||||
@ -789,7 +806,7 @@ fn check_unused_parens_pat(
|
||||
} else {
|
||||
None
|
||||
};
|
||||
self.emit_unused_delims(cx, value.span, spans, "pattern", (false, false));
|
||||
self.emit_unused_delims(cx, value.span, spans, "pattern", keep_space);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -798,7 +815,7 @@ impl EarlyLintPass for UnusedParens {
|
||||
fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) {
|
||||
match e.kind {
|
||||
ExprKind::Let(ref pat, _, _) | ExprKind::ForLoop(ref pat, ..) => {
|
||||
self.check_unused_parens_pat(cx, pat, false, false);
|
||||
self.check_unused_parens_pat(cx, pat, false, false, (true, true));
|
||||
}
|
||||
// We ignore parens in cases like `if (((let Some(0) = Some(1))))` because we already
|
||||
// handle a hard error for them during AST lowering in `lower_expr_mut`, but we still
|
||||
@ -842,6 +859,7 @@ fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) {
|
||||
|
||||
fn check_pat(&mut self, cx: &EarlyContext<'_>, p: &ast::Pat) {
|
||||
use ast::{Mutability, PatKind::*};
|
||||
let keep_space = (false, false);
|
||||
match &p.kind {
|
||||
// Do not lint on `(..)` as that will result in the other arms being useless.
|
||||
Paren(_)
|
||||
@ -849,33 +867,33 @@ fn check_pat(&mut self, cx: &EarlyContext<'_>, p: &ast::Pat) {
|
||||
| Wild | Rest | Lit(..) | MacCall(..) | Range(..) | Ident(.., None) | Path(..) => {},
|
||||
// These are list-like patterns; parens can always be removed.
|
||||
TupleStruct(_, _, ps) | Tuple(ps) | Slice(ps) | Or(ps) => for p in ps {
|
||||
self.check_unused_parens_pat(cx, p, false, false);
|
||||
self.check_unused_parens_pat(cx, p, false, false, keep_space);
|
||||
},
|
||||
Struct(_, _, fps, _) => for f in fps {
|
||||
self.check_unused_parens_pat(cx, &f.pat, false, false);
|
||||
self.check_unused_parens_pat(cx, &f.pat, false, false, keep_space);
|
||||
},
|
||||
// Avoid linting on `i @ (p0 | .. | pn)` and `box (p0 | .. | pn)`, #64106.
|
||||
Ident(.., Some(p)) | Box(p) => self.check_unused_parens_pat(cx, p, true, false),
|
||||
Ident(.., Some(p)) | Box(p) => self.check_unused_parens_pat(cx, p, true, false, keep_space),
|
||||
// Avoid linting on `&(mut x)` as `&mut x` has a different meaning, #55342.
|
||||
// Also avoid linting on `& mut? (p0 | .. | pn)`, #64106.
|
||||
Ref(p, m) => self.check_unused_parens_pat(cx, p, true, *m == Mutability::Not),
|
||||
Ref(p, m) => self.check_unused_parens_pat(cx, p, true, *m == Mutability::Not, keep_space),
|
||||
}
|
||||
}
|
||||
|
||||
fn check_stmt(&mut self, cx: &EarlyContext<'_>, s: &ast::Stmt) {
|
||||
if let StmtKind::Local(ref local) = s.kind {
|
||||
self.check_unused_parens_pat(cx, &local.pat, true, false);
|
||||
self.check_unused_parens_pat(cx, &local.pat, true, false, (false, false));
|
||||
}
|
||||
|
||||
<Self as UnusedDelimLint>::check_stmt(self, cx, s)
|
||||
}
|
||||
|
||||
fn check_param(&mut self, cx: &EarlyContext<'_>, param: &ast::Param) {
|
||||
self.check_unused_parens_pat(cx, ¶m.pat, true, false);
|
||||
self.check_unused_parens_pat(cx, ¶m.pat, true, false, (false, false));
|
||||
}
|
||||
|
||||
fn check_arm(&mut self, cx: &EarlyContext<'_>, arm: &ast::Arm) {
|
||||
self.check_unused_parens_pat(cx, &arm.pat, false, false);
|
||||
self.check_unused_parens_pat(cx, &arm.pat, false, false, (false, false));
|
||||
}
|
||||
|
||||
fn check_ty(&mut self, cx: &EarlyContext<'_>, ty: &ast::Ty) {
|
||||
|
16
src/test/ui/lint/issue-103435-extra-parentheses.fixed
Normal file
16
src/test/ui/lint/issue-103435-extra-parentheses.fixed
Normal file
@ -0,0 +1,16 @@
|
||||
// run-rustfix
|
||||
#![deny(unused_parens)]
|
||||
|
||||
fn main() {
|
||||
if let Some(_) = Some(1) {}
|
||||
//~^ ERROR unnecessary parentheses around pattern
|
||||
|
||||
for _x in 1..10 {}
|
||||
//~^ ERROR unnecessary parentheses around pattern
|
||||
|
||||
if 2 == 1 {}
|
||||
//~^ ERROR unnecessary parentheses around `if` condition
|
||||
|
||||
// FIXME, auto recover from this one?
|
||||
// for(_x in 1..10) {}
|
||||
}
|
16
src/test/ui/lint/issue-103435-extra-parentheses.rs
Normal file
16
src/test/ui/lint/issue-103435-extra-parentheses.rs
Normal file
@ -0,0 +1,16 @@
|
||||
// run-rustfix
|
||||
#![deny(unused_parens)]
|
||||
|
||||
fn main() {
|
||||
if let(Some(_))= Some(1) {}
|
||||
//~^ ERROR unnecessary parentheses around pattern
|
||||
|
||||
for(_x)in 1..10 {}
|
||||
//~^ ERROR unnecessary parentheses around pattern
|
||||
|
||||
if(2 == 1){}
|
||||
//~^ ERROR unnecessary parentheses around `if` condition
|
||||
|
||||
// FIXME, auto recover from this one?
|
||||
// for(_x in 1..10) {}
|
||||
}
|
43
src/test/ui/lint/issue-103435-extra-parentheses.stderr
Normal file
43
src/test/ui/lint/issue-103435-extra-parentheses.stderr
Normal file
@ -0,0 +1,43 @@
|
||||
error: unnecessary parentheses around pattern
|
||||
--> $DIR/issue-103435-extra-parentheses.rs:5:11
|
||||
|
|
||||
LL | if let(Some(_))= Some(1) {}
|
||||
| ^ ^
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/issue-103435-extra-parentheses.rs:2:9
|
||||
|
|
||||
LL | #![deny(unused_parens)]
|
||||
| ^^^^^^^^^^^^^
|
||||
help: remove these parentheses
|
||||
|
|
||||
LL - if let(Some(_))= Some(1) {}
|
||||
LL + if let Some(_) = Some(1) {}
|
||||
|
|
||||
|
||||
error: unnecessary parentheses around pattern
|
||||
--> $DIR/issue-103435-extra-parentheses.rs:8:8
|
||||
|
|
||||
LL | for(_x)in 1..10 {}
|
||||
| ^ ^
|
||||
|
|
||||
help: remove these parentheses
|
||||
|
|
||||
LL - for(_x)in 1..10 {}
|
||||
LL + for _x in 1..10 {}
|
||||
|
|
||||
|
||||
error: unnecessary parentheses around `if` condition
|
||||
--> $DIR/issue-103435-extra-parentheses.rs:11:7
|
||||
|
|
||||
LL | if(2 == 1){}
|
||||
| ^ ^
|
||||
|
|
||||
help: remove these parentheses
|
||||
|
|
||||
LL - if(2 == 1){}
|
||||
LL + if 2 == 1 {}
|
||||
|
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
Loading…
Reference in New Issue
Block a user