about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDylan DPC <dylan.dpc@gmail.com>2021-02-14 16:54:42 +0100
committerGitHub <noreply@github.com>2021-02-14 16:54:42 +0100
commitac1d26bcd3a26523c7e7ebb2dd0b37d6b2834291 (patch)
tree96024d4a5568ea17d21e71efd130e71371005e31
parent29ed864dc3a066487180d08dcf8b64c6afedebba (diff)
parent9f0e1d4921bbb40fea71594d7c599c09ab513232 (diff)
downloadrust-ac1d26bcd3a26523c7e7ebb2dd0b37d6b2834291.tar.gz
rust-ac1d26bcd3a26523c7e7ebb2dd0b37d6b2834291.zip
Rollup merge of #80920 - rylev:check_attr-refactor, r=davidtwco
Visit more targets when validating attributes

This begins to address #80048, allowing for additional validation of attributes.

There are more refactorings that can be done, though I think they should be tackled in additional PRs:
* ICE when a builtin attribute is encountered that is not checked
* Move some of the attr checking done `ast_validation` into `rustc_passes`
  * note that this requires a bit of additional refactoring, especially of extern items which currently parse attributes (and thus are a part of the AST) but do not possess attributes in their HIR representation.
* Rename `Target` to `AttributeTarget`
* Refactor attribute validation completely to go through `Visitor::visit_attribute`.
  * This would require at a minimum passing `Target` into this method which might be too big of a refactoring to be worth it.
  * It's also likely not possible to do all the validation this way as some validation requires knowing what other attributes a target has.

r? `@davidtwco`
-rw-r--r--compiler/rustc_hir/src/target.rs2
-rw-r--r--compiler/rustc_passes/src/check_attr.rs28
-rw-r--r--src/test/ui/attributes/attrs-on-params.rs8
-rw-r--r--src/test/ui/attributes/attrs-on-params.stderr17
-rw-r--r--src/test/ui/proc-macro/ambiguous-builtin-attrs.rs2
-rw-r--r--src/test/ui/proc-macro/ambiguous-builtin-attrs.stderr10
6 files changed, 50 insertions, 17 deletions
diff --git a/compiler/rustc_hir/src/target.rs b/compiler/rustc_hir/src/target.rs
index 6dbcfb963ee..473477bf22d 100644
--- a/compiler/rustc_hir/src/target.rs
+++ b/compiler/rustc_hir/src/target.rs
@@ -54,6 +54,7 @@ pub enum Target {
     ForeignTy,
     GenericParam(GenericParamKind),
     MacroDef,
+    Param,
 }
 
 impl Display for Target {
@@ -96,6 +97,7 @@ impl Display for Target {
                     GenericParamKind::Const => "const parameter",
                 },
                 Target::MacroDef => "macro def",
+                Target::Param => "function param",
             }
         )
     }
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index 0e3a722e082..2c79eeeb0e6 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -1101,17 +1101,6 @@ impl Visitor<'tcx> for CheckAttrVisitor<'tcx> {
         intravisit::walk_arm(self, arm);
     }
 
-    fn visit_macro_def(&mut self, macro_def: &'tcx hir::MacroDef<'tcx>) {
-        self.check_attributes(
-            macro_def.hir_id,
-            &macro_def.attrs,
-            &macro_def.span,
-            Target::MacroDef,
-            None,
-        );
-        intravisit::walk_macro_def(self, macro_def);
-    }
-
     fn visit_foreign_item(&mut self, f_item: &'tcx ForeignItem<'tcx>) {
         let target = Target::from_foreign_item(f_item);
         self.check_attributes(
@@ -1157,6 +1146,23 @@ impl Visitor<'tcx> for CheckAttrVisitor<'tcx> {
         self.check_attributes(variant.id, variant.attrs, &variant.span, Target::Variant, None);
         intravisit::walk_variant(self, variant, generics, item_id)
     }
+
+    fn visit_macro_def(&mut self, macro_def: &'tcx hir::MacroDef<'tcx>) {
+        self.check_attributes(
+            macro_def.hir_id,
+            macro_def.attrs,
+            &macro_def.span,
+            Target::MacroDef,
+            None,
+        );
+        intravisit::walk_macro_def(self, macro_def);
+    }
+
+    fn visit_param(&mut self, param: &'tcx hir::Param<'tcx>) {
+        self.check_attributes(param.hir_id, param.attrs, &param.span, Target::Param, None);
+
+        intravisit::walk_param(self, param);
+    }
 }
 
 fn is_c_like_enum(item: &Item<'_>) -> bool {
diff --git a/src/test/ui/attributes/attrs-on-params.rs b/src/test/ui/attributes/attrs-on-params.rs
new file mode 100644
index 00000000000..0e606eac1e8
--- /dev/null
+++ b/src/test/ui/attributes/attrs-on-params.rs
@@ -0,0 +1,8 @@
+// This checks that incorrect params on function parameters are caught
+
+fn function(#[inline] param: u32) {
+    //~^ ERROR attribute should be applied to function or closure
+    //~| ERROR allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes
+}
+
+fn main() {}
diff --git a/src/test/ui/attributes/attrs-on-params.stderr b/src/test/ui/attributes/attrs-on-params.stderr
new file mode 100644
index 00000000000..003f43d371a
--- /dev/null
+++ b/src/test/ui/attributes/attrs-on-params.stderr
@@ -0,0 +1,17 @@
+error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
+  --> $DIR/attrs-on-params.rs:3:13
+   |
+LL | fn function(#[inline] param: u32) {
+   |             ^^^^^^^^^
+
+error[E0518]: attribute should be applied to function or closure
+  --> $DIR/attrs-on-params.rs:3:13
+   |
+LL | fn function(#[inline] param: u32) {
+   |             ^^^^^^^^^-----------
+   |             |
+   |             not a function or closure
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0518`.
diff --git a/src/test/ui/proc-macro/ambiguous-builtin-attrs.rs b/src/test/ui/proc-macro/ambiguous-builtin-attrs.rs
index a6e9ed14ff1..65d8bcd9972 100644
--- a/src/test/ui/proc-macro/ambiguous-builtin-attrs.rs
+++ b/src/test/ui/proc-macro/ambiguous-builtin-attrs.rs
@@ -3,8 +3,8 @@
 #![feature(decl_macro)] //~ ERROR `feature` is ambiguous
 
 extern crate builtin_attrs;
-use builtin_attrs::{test, bench};
 use builtin_attrs::*;
+use builtin_attrs::{bench, test};
 
 #[repr(C)] //~ ERROR `repr` is ambiguous
 struct S;
diff --git a/src/test/ui/proc-macro/ambiguous-builtin-attrs.stderr b/src/test/ui/proc-macro/ambiguous-builtin-attrs.stderr
index 31959248a68..1ad991db3be 100644
--- a/src/test/ui/proc-macro/ambiguous-builtin-attrs.stderr
+++ b/src/test/ui/proc-macro/ambiguous-builtin-attrs.stderr
@@ -12,7 +12,7 @@ LL | #[repr(C)]
    |
    = note: `repr` could refer to a built-in attribute
 note: `repr` could also refer to the attribute macro imported here
-  --> $DIR/ambiguous-builtin-attrs.rs:7:5
+  --> $DIR/ambiguous-builtin-attrs.rs:6:5
    |
 LL | use builtin_attrs::*;
    |     ^^^^^^^^^^^^^^^^
@@ -26,7 +26,7 @@ LL | #[cfg_attr(all(), repr(C))]
    |
    = note: `repr` could refer to a built-in attribute
 note: `repr` could also refer to the attribute macro imported here
-  --> $DIR/ambiguous-builtin-attrs.rs:7:5
+  --> $DIR/ambiguous-builtin-attrs.rs:6:5
    |
 LL | use builtin_attrs::*;
    |     ^^^^^^^^^^^^^^^^
@@ -40,7 +40,7 @@ LL | fn non_macro_expanded_location<#[repr(C)] T>() {
    |
    = note: `repr` could refer to a built-in attribute
 note: `repr` could also refer to the attribute macro imported here
-  --> $DIR/ambiguous-builtin-attrs.rs:7:5
+  --> $DIR/ambiguous-builtin-attrs.rs:6:5
    |
 LL | use builtin_attrs::*;
    |     ^^^^^^^^^^^^^^^^
@@ -54,7 +54,7 @@ LL |         #[repr(C)]
    |
    = note: `repr` could refer to a built-in attribute
 note: `repr` could also refer to the attribute macro imported here
-  --> $DIR/ambiguous-builtin-attrs.rs:7:5
+  --> $DIR/ambiguous-builtin-attrs.rs:6:5
    |
 LL | use builtin_attrs::*;
    |     ^^^^^^^^^^^^^^^^
@@ -82,7 +82,7 @@ LL | #![feature(decl_macro)]
    |
    = note: `feature` could refer to a built-in attribute
 note: `feature` could also refer to the attribute macro imported here
-  --> $DIR/ambiguous-builtin-attrs.rs:7:5
+  --> $DIR/ambiguous-builtin-attrs.rs:6:5
    |
 LL | use builtin_attrs::*;
    |     ^^^^^^^^^^^^^^^^