]> git.lizzy.rs Git - rust.git/commitdiff
Rollup merge of #106148 - chenyukang:yukang/fix-105061-unused, r=lcnr
authorDylan DPC <99973273+Dylan-DPC@users.noreply.github.com>
Tue, 17 Jan 2023 15:03:03 +0000 (20:33 +0530)
committerGitHub <noreply@github.com>
Tue, 17 Jan 2023 15:03:03 +0000 (20:33 +0530)
Fix unused_parens issue for higher ranked function pointers

fixes #105061

r? `@lcnr`

compiler/rustc_lint/src/early.rs
compiler/rustc_lint/src/lib.rs
compiler/rustc_lint/src/passes.rs
compiler/rustc_lint/src/unused.rs
library/std/src/io/error/repr_bitpacked.rs
tests/ui/lint/unused/issue-105061-array-lint.rs [new file with mode: 0644]
tests/ui/lint/unused/issue-105061-array-lint.stderr [new file with mode: 0644]
tests/ui/lint/unused/issue-105061-should-lint.rs [new file with mode: 0644]
tests/ui/lint/unused/issue-105061-should-lint.stderr [new file with mode: 0644]
tests/ui/lint/unused/issue-105061.rs [new file with mode: 0644]
tests/ui/lint/unused/issue-105061.stderr [new file with mode: 0644]

index f9b2df49592244fa701928bfbe71eeac0357df41..337a19dd024d2fec195601c77de253036df847bf 100644 (file)
@@ -248,7 +248,9 @@ fn visit_generics(&mut self, g: &'a ast::Generics) {
     }
 
     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) {
index 3d818154cb94ff48c1a7c33fd2a19d473b089588..d6be4da03286f75f1e4868e5bac454b345008a8b 100644 (file)
@@ -145,7 +145,7 @@ fn lint_mod(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
     [
         pub BuiltinCombinedEarlyLintPass,
         [
-            UnusedParens: UnusedParens,
+            UnusedParens: UnusedParens::new(),
             UnusedBraces: UnusedBraces,
             UnusedImportBraces: UnusedImportBraces,
             UnsafeCode: UnsafeCode,
index 5558156a4b9ef040a07ff54271328b64f31e2ba4..0bf01c4e567814f1f720de66362f310cf5c0f934 100644 (file)
@@ -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);
         ]);
     )
 }
index 36791915964df75565cc6d3a1670fdc01b1e7f95..4c9b3df2dbd33d706d04c3cc5e911ceeb9c70a2c 100644 (file)
@@ -824,7 +824,17 @@ fn check_item(&mut self, cx: &EarlyContext<'_>, item: &ast::Item) {
     "`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";
@@ -999,36 +1009,58 @@ fn check_arm(&mut self, cx: &EarlyContext<'_>, arm: &ast::Arm) {
     }
 
     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! {
index 601c01c2128c816757c103d3a04f3c4c0dd8646c..3581484050dd1a4e506574b46d99ce609c5ed996 100644 (file)
@@ -374,10 +374,10 @@ macro_rules! static_assert {
 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
diff --git a/tests/ui/lint/unused/issue-105061-array-lint.rs b/tests/ui/lint/unused/issue-105061-array-lint.rs
new file mode 100644 (file)
index 0000000..9b06a4f
--- /dev/null
@@ -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
+
+}
diff --git a/tests/ui/lint/unused/issue-105061-array-lint.stderr b/tests/ui/lint/unused/issue-105061-array-lint.stderr
new file mode 100644 (file)
index 0000000..7eb761a
--- /dev/null
@@ -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
+
diff --git a/tests/ui/lint/unused/issue-105061-should-lint.rs b/tests/ui/lint/unused/issue-105061-should-lint.rs
new file mode 100644 (file)
index 0000000..7e4e094
--- /dev/null
@@ -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();
+}
diff --git a/tests/ui/lint/unused/issue-105061-should-lint.stderr b/tests/ui/lint/unused/issue-105061-should-lint.stderr
new file mode 100644 (file)
index 0000000..e591f1f
--- /dev/null
@@ -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
+
diff --git a/tests/ui/lint/unused/issue-105061.rs b/tests/ui/lint/unused/issue-105061.rs
new file mode 100644 (file)
index 0000000..92d636d
--- /dev/null
@@ -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();
+}
diff --git a/tests/ui/lint/unused/issue-105061.stderr b/tests/ui/lint/unused/issue-105061.stderr
new file mode 100644 (file)
index 0000000..f07aa20
--- /dev/null
@@ -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
+