fix #103435, unused lint won't produce invalid code
This commit is contained in:
parent
9be2f35a4c
commit
c0447b489b
4 changed files with 106 additions and 13 deletions
|
@ -565,10 +565,26 @@ trait UnusedDelimLint {
|
||||||
lint.set_arg("delim", Self::DELIM_STR);
|
lint.set_arg("delim", Self::DELIM_STR);
|
||||||
lint.set_arg("item", msg);
|
lint.set_arg("item", msg);
|
||||||
if let Some((lo, hi)) = spans {
|
if let Some((lo, hi)) = spans {
|
||||||
let replacement = vec![
|
let sm = cx.sess().source_map();
|
||||||
(lo, if keep_space.0 { " ".into() } else { "".into() }),
|
let lo_replace =
|
||||||
(hi, if keep_space.1 { " ".into() } else { "".into() }),
|
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(
|
lint.multipart_suggestion(
|
||||||
fluent::suggestion,
|
fluent::suggestion,
|
||||||
replacement,
|
replacement,
|
||||||
|
@ -765,6 +781,7 @@ impl UnusedParens {
|
||||||
value: &ast::Pat,
|
value: &ast::Pat,
|
||||||
avoid_or: bool,
|
avoid_or: bool,
|
||||||
avoid_mut: bool,
|
avoid_mut: bool,
|
||||||
|
keep_space: (bool, bool),
|
||||||
) {
|
) {
|
||||||
use ast::{BindingAnnotation, PatKind};
|
use ast::{BindingAnnotation, PatKind};
|
||||||
|
|
||||||
|
@ -789,7 +806,7 @@ impl UnusedParens {
|
||||||
} else {
|
} else {
|
||||||
None
|
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) {
|
fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) {
|
||||||
match e.kind {
|
match e.kind {
|
||||||
ExprKind::Let(ref pat, _, _) | ExprKind::ForLoop(ref pat, ..) => {
|
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
|
// 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
|
// handle a hard error for them during AST lowering in `lower_expr_mut`, but we still
|
||||||
|
@ -842,6 +859,7 @@ impl EarlyLintPass for UnusedParens {
|
||||||
|
|
||||||
fn check_pat(&mut self, cx: &EarlyContext<'_>, p: &ast::Pat) {
|
fn check_pat(&mut self, cx: &EarlyContext<'_>, p: &ast::Pat) {
|
||||||
use ast::{Mutability, PatKind::*};
|
use ast::{Mutability, PatKind::*};
|
||||||
|
let keep_space = (false, false);
|
||||||
match &p.kind {
|
match &p.kind {
|
||||||
// Do not lint on `(..)` as that will result in the other arms being useless.
|
// Do not lint on `(..)` as that will result in the other arms being useless.
|
||||||
Paren(_)
|
Paren(_)
|
||||||
|
@ -849,33 +867,33 @@ impl EarlyLintPass for UnusedParens {
|
||||||
| Wild | Rest | Lit(..) | MacCall(..) | Range(..) | Ident(.., None) | Path(..) => {},
|
| Wild | Rest | Lit(..) | MacCall(..) | Range(..) | Ident(.., None) | Path(..) => {},
|
||||||
// These are list-like patterns; parens can always be removed.
|
// These are list-like patterns; parens can always be removed.
|
||||||
TupleStruct(_, _, ps) | Tuple(ps) | Slice(ps) | Or(ps) => for p in ps {
|
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 {
|
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.
|
// 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.
|
// Avoid linting on `&(mut x)` as `&mut x` has a different meaning, #55342.
|
||||||
// Also avoid linting on `& mut? (p0 | .. | pn)`, #64106.
|
// 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) {
|
fn check_stmt(&mut self, cx: &EarlyContext<'_>, s: &ast::Stmt) {
|
||||||
if let StmtKind::Local(ref local) = s.kind {
|
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)
|
<Self as UnusedDelimLint>::check_stmt(self, cx, s)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_param(&mut self, cx: &EarlyContext<'_>, param: &ast::Param) {
|
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) {
|
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) {
|
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…
Add table
Add a link
Reference in a new issue