Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix unused_parens issue for higher ranked function pointers #106148

Merged
merged 4 commits into from
Jan 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions compiler/rustc_lint/src/early.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
lint_callback!(self, enter_where_predicate, 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) {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_lint/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ early_lint_methods!(
[
pub BuiltinCombinedEarlyLintPass,
[
UnusedParens: UnusedParens,
UnusedParens: UnusedParens::new(),
UnusedBraces: UnusedBraces,
UnusedImportBraces: UnusedImportBraces,
UnsafeCode: UnsafeCode,
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_lint/src/passes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,9 @@ macro_rules! early_lint_methods {

/// Counterpart to `enter_lint_attrs`.
fn exit_lint_attrs(a: &[ast::Attribute]);

fn enter_where_predicate(a: &ast::WherePredicate);
fn exit_where_predicate(a: &ast::WherePredicate);
]);
)
}
Expand Down
78 changes: 55 additions & 23 deletions compiler/rustc_lint/src/unused.rs
Original file line number Diff line number Diff line change
Expand Up @@ -824,7 +824,17 @@ declare_lint! {
"`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 {
const DELIM_STR: &'static str = "parentheses";
Expand Down Expand Up @@ -999,36 +1009,58 @@ impl EarlyLintPass for UnusedParens {
}

fn check_ty(&mut self, cx: &EarlyContext<'_>, ty: &ast::Ty) {
if let ast::TyKind::Paren(r) = &ty.kind {
match &r.kind {
ast::TyKind::TraitObject(..) => {}
ast::TyKind::BareFn(b) if b.generic_params.len() > 0 => {}
ast::TyKind::ImplTrait(_, bounds) if bounds.len() > 1 => {}
ast::TyKind::Array(_, len) => {
self.check_unused_delims_expr(
cx,
&len.value,
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));
match &ty.kind {
ast::TyKind::Array(_, len) => {
self.check_unused_delims_expr(
cx,
&len.value,
UnusedDelimsCtx::ArrayLenExpr,
false,
None,
None,
);
}
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) {
<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! {
Expand Down
8 changes: 4 additions & 4 deletions library/std/src/io/error/repr_bitpacked.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::<Custom>() >= TAG_MASK + 1);

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_OS), TAG_OS);
static_assert!(@usize_eq: (TAG_MASK & TAG_SIMPLE), TAG_SIMPLE);
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_OS, TAG_OS);
static_assert!(@usize_eq: TAG_MASK & TAG_SIMPLE, TAG_SIMPLE);

// 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
Expand Down
11 changes: 11 additions & 0 deletions tests/ui/lint/unused/issue-105061-array-lint.rs
Original file line number Diff line number Diff line change
@@ -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

}
56 changes: 56 additions & 0 deletions tests/ui/lint/unused/issue-105061-array-lint.stderr
Original file line number Diff line number Diff line change
@@ -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

23 changes: 23 additions & 0 deletions tests/ui/lint/unused/issue-105061-should-lint.rs
Original file line number Diff line number Diff line change
@@ -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();
}
32 changes: 32 additions & 0 deletions tests/ui/lint/unused/issue-105061-should-lint.stderr
Original file line number Diff line number Diff line change
@@ -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

17 changes: 17 additions & 0 deletions tests/ui/lint/unused/issue-105061.rs
Original file line number Diff line number Diff line change
@@ -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();
}
20 changes: 20 additions & 0 deletions tests/ui/lint/unused/issue-105061.stderr
Original file line number Diff line number Diff line change
@@ -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