Rollup merge of #106148 - chenyukang:yukang/fix-105061-unused, r=lcnr

Fix unused_parens issue for higher ranked function pointers

fixes #105061

r? `@lcnr`
This commit is contained in:
Dylan DPC 2023-01-17 20:33:03 +05:30 committed by GitHub
commit f91f369949
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 225 additions and 29 deletions

View File

@ -248,7 +248,9 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T>
} }
fn visit_where_predicate(&mut self, p: &'a ast::WherePredicate) { fn visit_where_predicate(&mut self, p: &'a ast::WherePredicate) {
lint_callback!(self, enter_where_predicate, p);
ast_visit::walk_where_predicate(self, p); ast_visit::walk_where_predicate(self, p);
lint_callback!(self, exit_where_predicate, p);
} }
fn visit_poly_trait_ref(&mut self, t: &'a ast::PolyTraitRef) { fn visit_poly_trait_ref(&mut self, t: &'a ast::PolyTraitRef) {

View File

@ -145,7 +145,7 @@ early_lint_methods!(
[ [
pub BuiltinCombinedEarlyLintPass, pub BuiltinCombinedEarlyLintPass,
[ [
UnusedParens: UnusedParens, UnusedParens: UnusedParens::new(),
UnusedBraces: UnusedBraces, UnusedBraces: UnusedBraces,
UnusedImportBraces: UnusedImportBraces, UnusedImportBraces: UnusedImportBraces,
UnsafeCode: UnsafeCode, UnsafeCode: UnsafeCode,

View File

@ -171,6 +171,9 @@ macro_rules! early_lint_methods {
/// Counterpart to `enter_lint_attrs`. /// Counterpart to `enter_lint_attrs`.
fn exit_lint_attrs(a: &[ast::Attribute]); fn exit_lint_attrs(a: &[ast::Attribute]);
fn enter_where_predicate(a: &ast::WherePredicate);
fn exit_where_predicate(a: &ast::WherePredicate);
]); ]);
) )
} }

View File

@ -824,7 +824,17 @@ declare_lint! {
"`if`, `match`, `while` and `return` do not need parentheses" "`if`, `match`, `while` and `return` do not need parentheses"
} }
declare_lint_pass!(UnusedParens => [UNUSED_PARENS]); pub struct UnusedParens {
with_self_ty_parens: bool,
}
impl UnusedParens {
pub fn new() -> Self {
Self { with_self_ty_parens: false }
}
}
impl_lint_pass!(UnusedParens => [UNUSED_PARENS]);
impl UnusedDelimLint for UnusedParens { impl UnusedDelimLint for UnusedParens {
const DELIM_STR: &'static str = "parentheses"; const DELIM_STR: &'static str = "parentheses";
@ -999,36 +1009,58 @@ impl EarlyLintPass for UnusedParens {
} }
fn check_ty(&mut self, cx: &EarlyContext<'_>, ty: &ast::Ty) { fn check_ty(&mut self, cx: &EarlyContext<'_>, ty: &ast::Ty) {
if let ast::TyKind::Paren(r) = &ty.kind { match &ty.kind {
match &r.kind { ast::TyKind::Array(_, len) => {
ast::TyKind::TraitObject(..) => {} self.check_unused_delims_expr(
ast::TyKind::BareFn(b) if b.generic_params.len() > 0 => {} cx,
ast::TyKind::ImplTrait(_, bounds) if bounds.len() > 1 => {} &len.value,
ast::TyKind::Array(_, len) => { UnusedDelimsCtx::ArrayLenExpr,
self.check_unused_delims_expr( false,
cx, None,
&len.value, None,
UnusedDelimsCtx::ArrayLenExpr, );
false,
None,
None,
);
}
_ => {
let spans = if let Some(r) = r.span.find_ancestor_inside(ty.span) {
Some((ty.span.with_hi(r.lo()), ty.span.with_lo(r.hi())))
} else {
None
};
self.emit_unused_delims(cx, ty.span, spans, "type", (false, false));
}
} }
ast::TyKind::Paren(r) => {
match &r.kind {
ast::TyKind::TraitObject(..) => {}
ast::TyKind::BareFn(b)
if self.with_self_ty_parens && b.generic_params.len() > 0 => {}
ast::TyKind::ImplTrait(_, bounds) if bounds.len() > 1 => {}
_ => {
let spans = if let Some(r) = r.span.find_ancestor_inside(ty.span) {
Some((ty.span.with_hi(r.lo()), ty.span.with_lo(r.hi())))
} else {
None
};
self.emit_unused_delims(cx, ty.span, spans, "type", (false, false));
}
}
self.with_self_ty_parens = false;
}
_ => {}
} }
} }
fn check_item(&mut self, cx: &EarlyContext<'_>, item: &ast::Item) { fn check_item(&mut self, cx: &EarlyContext<'_>, item: &ast::Item) {
<Self as UnusedDelimLint>::check_item(self, cx, item) <Self as UnusedDelimLint>::check_item(self, cx, item)
} }
fn enter_where_predicate(&mut self, _: &EarlyContext<'_>, pred: &ast::WherePredicate) {
use rustc_ast::{WhereBoundPredicate, WherePredicate};
if let WherePredicate::BoundPredicate(WhereBoundPredicate {
bounded_ty,
bound_generic_params,
..
}) = pred &&
let ast::TyKind::Paren(_) = &bounded_ty.kind &&
bound_generic_params.is_empty() {
self.with_self_ty_parens = true;
}
}
fn exit_where_predicate(&mut self, _: &EarlyContext<'_>, _: &ast::WherePredicate) {
assert!(!self.with_self_ty_parens);
}
} }
declare_lint! { declare_lint! {

View File

@ -374,10 +374,10 @@ static_assert!((TAG_MASK + 1).is_power_of_two());
static_assert!(align_of::<SimpleMessage>() >= TAG_MASK + 1); static_assert!(align_of::<SimpleMessage>() >= TAG_MASK + 1);
static_assert!(align_of::<Custom>() >= TAG_MASK + 1); static_assert!(align_of::<Custom>() >= TAG_MASK + 1);
static_assert!(@usize_eq: (TAG_MASK & TAG_SIMPLE_MESSAGE), TAG_SIMPLE_MESSAGE); static_assert!(@usize_eq: TAG_MASK & TAG_SIMPLE_MESSAGE, TAG_SIMPLE_MESSAGE);
static_assert!(@usize_eq: (TAG_MASK & TAG_CUSTOM), TAG_CUSTOM); static_assert!(@usize_eq: TAG_MASK & TAG_CUSTOM, TAG_CUSTOM);
static_assert!(@usize_eq: (TAG_MASK & TAG_OS), TAG_OS); static_assert!(@usize_eq: TAG_MASK & TAG_OS, TAG_OS);
static_assert!(@usize_eq: (TAG_MASK & TAG_SIMPLE), TAG_SIMPLE); static_assert!(@usize_eq: TAG_MASK & TAG_SIMPLE, TAG_SIMPLE);
// This is obviously true (`TAG_CUSTOM` is `0b01`), but in `Repr::new_custom` we // This is obviously true (`TAG_CUSTOM` is `0b01`), but in `Repr::new_custom` we
// offset a pointer by this value, and expect it to both be within the same // offset a pointer by this value, and expect it to both be within the same

View File

@ -0,0 +1,11 @@
#![warn(unused)]
#![deny(warnings)]
fn main() {
let _x: ([u32; 3]); //~ ERROR unnecessary parentheses around type
let _y: [u8; (3)]; //~ ERROR unnecessary parentheses around const expression
let _z: ([u8; (3)]);
//~^ ERROR unnecessary parentheses around const expression
//~| ERROR unnecessary parentheses around type
}

View File

@ -0,0 +1,56 @@
error: unnecessary parentheses around type
--> $DIR/issue-105061-array-lint.rs:5:13
|
LL | let _x: ([u32; 3]);
| ^ ^
|
note: the lint level is defined here
--> $DIR/issue-105061-array-lint.rs:2:9
|
LL | #![deny(warnings)]
| ^^^^^^^^
= note: `#[deny(unused_parens)]` implied by `#[deny(warnings)]`
help: remove these parentheses
|
LL - let _x: ([u32; 3]);
LL + let _x: [u32; 3];
|
error: unnecessary parentheses around const expression
--> $DIR/issue-105061-array-lint.rs:6:18
|
LL | let _y: [u8; (3)];
| ^ ^
|
help: remove these parentheses
|
LL - let _y: [u8; (3)];
LL + let _y: [u8; 3];
|
error: unnecessary parentheses around type
--> $DIR/issue-105061-array-lint.rs:7:13
|
LL | let _z: ([u8; (3)]);
| ^ ^
|
help: remove these parentheses
|
LL - let _z: ([u8; (3)]);
LL + let _z: [u8; (3)];
|
error: unnecessary parentheses around const expression
--> $DIR/issue-105061-array-lint.rs:7:19
|
LL | let _z: ([u8; (3)]);
| ^ ^
|
help: remove these parentheses
|
LL - let _z: ([u8; (3)]);
LL + let _z: ([u8; 3]);
|
error: aborting due to 4 previous errors

View File

@ -0,0 +1,23 @@
#![warn(unused)]
#![deny(warnings)]
struct Inv<'a>(&'a mut &'a ());
trait Trait<'a> {}
impl<'b> Trait<'b> for for<'a> fn(Inv<'a>) {}
fn with_bound()
where
for<'b> (for<'a> fn(Inv<'a>)): Trait<'b>, //~ ERROR unnecessary parentheses around type
{}
trait Hello<T> {}
fn with_dyn_bound<T>()
where
(dyn Hello<(for<'b> fn(&'b ()))>): Hello<T> //~ ERROR unnecessary parentheses around type
{}
fn main() {
with_bound();
with_dyn_bound();
}

View File

@ -0,0 +1,32 @@
error: unnecessary parentheses around type
--> $DIR/issue-105061-should-lint.rs:11:13
|
LL | for<'b> (for<'a> fn(Inv<'a>)): Trait<'b>,
| ^ ^
|
note: the lint level is defined here
--> $DIR/issue-105061-should-lint.rs:2:9
|
LL | #![deny(warnings)]
| ^^^^^^^^
= note: `#[deny(unused_parens)]` implied by `#[deny(warnings)]`
help: remove these parentheses
|
LL - for<'b> (for<'a> fn(Inv<'a>)): Trait<'b>,
LL + for<'b> for<'a> fn(Inv<'a>): Trait<'b>,
|
error: unnecessary parentheses around type
--> $DIR/issue-105061-should-lint.rs:17:16
|
LL | (dyn Hello<(for<'b> fn(&'b ()))>): Hello<T>
| ^ ^
|
help: remove these parentheses
|
LL - (dyn Hello<(for<'b> fn(&'b ()))>): Hello<T>
LL + (dyn Hello<for<'b> fn(&'b ())>): Hello<T>
|
error: aborting due to 2 previous errors

View File

@ -0,0 +1,17 @@
#![warn(unused)]
#![deny(warnings)]
struct Inv<'a>(&'a mut &'a ());
trait Trait {}
impl Trait for (for<'a> fn(Inv<'a>),) {}
fn with_bound()
where
((for<'a> fn(Inv<'a>)),): Trait, //~ ERROR unnecessary parentheses around type
{}
fn main() {
with_bound();
}

View File

@ -0,0 +1,20 @@
error: unnecessary parentheses around type
--> $DIR/issue-105061.rs:12:6
|
LL | ((for<'a> fn(Inv<'a>)),): Trait,
| ^ ^
|
note: the lint level is defined here
--> $DIR/issue-105061.rs:2:9
|
LL | #![deny(warnings)]
| ^^^^^^^^
= note: `#[deny(unused_parens)]` implied by `#[deny(warnings)]`
help: remove these parentheses
|
LL - ((for<'a> fn(Inv<'a>)),): Trait,
LL + (for<'a> fn(Inv<'a>),): Trait,
|
error: aborting due to previous error