about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>2018-12-12 04:11:46 +0300
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>2019-01-12 16:18:20 +0300
commitbf1e70cd1f39c0879b36bead3b07a0fdfcfc4c32 (patch)
tree20892d50221fee59cc22e9e336c791726c3e73ad
parente1d1487fc44104d59f3faa550b91d5e248d2bce1 (diff)
downloadrust-bf1e70cd1f39c0879b36bead3b07a0fdfcfc4c32.tar.gz
rust-bf1e70cd1f39c0879b36bead3b07a0fdfcfc4c32.zip
resolve: Prohibit use of imported non-macro attributes
-rw-r--r--src/librustc/hir/def.rs2
-rw-r--r--src/librustc_resolve/macros.rs19
-rw-r--r--src/test/ui/rust-2018/uniform-paths/prelude-fail-2.rs9
-rw-r--r--src/test/ui/rust-2018/uniform-paths/prelude-fail-2.stderr14
-rw-r--r--src/test/ui/rust-2018/uniform-paths/prelude.rs4
5 files changed, 42 insertions, 6 deletions
diff --git a/src/librustc/hir/def.rs b/src/librustc/hir/def.rs
index 20ec620a281..2382a2ea50b 100644
--- a/src/librustc/hir/def.rs
+++ b/src/librustc/hir/def.rs
@@ -240,7 +240,7 @@ impl CtorKind {
 }
 
 impl NonMacroAttrKind {
-    fn descr(self) -> &'static str {
+    pub fn descr(self) -> &'static str {
         match self {
             NonMacroAttrKind::Builtin => "built-in attribute",
             NonMacroAttrKind::Tool => "tool attribute",
diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index b2b794c6925..037ade13c20 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -376,6 +376,7 @@ impl<'a> Resolver<'a> {
                     .push((path, path_span, kind, parent_scope.clone(), def.ok()));
             }
 
+            self.prohibit_imported_non_macro_attrs(None, def.ok(), path_span);
             def
         } else {
             let binding = self.early_resolve_ident_in_lexical_scope(
@@ -390,7 +391,9 @@ impl<'a> Resolver<'a> {
                     .push((path[0].ident, kind, parent_scope.clone(), binding.ok()));
             }
 
-            binding.map(|binding| binding.def())
+            let def = binding.map(|binding| binding.def());
+            self.prohibit_imported_non_macro_attrs(binding.ok(), def.ok(), path_span);
+            def
         }
     }
 
@@ -982,6 +985,20 @@ impl<'a> Resolver<'a> {
         }
     }
 
+    fn prohibit_imported_non_macro_attrs(&self, binding: Option<&'a NameBinding<'a>>,
+                                         def: Option<Def>, span: Span) {
+        if let Some(Def::NonMacroAttr(kind)) = def {
+            if kind != NonMacroAttrKind::Tool && binding.map_or(true, |b| b.is_import()) {
+                let msg = format!("cannot use a {} through an import", kind.descr());
+                let mut err = self.session.struct_span_err(span, &msg);
+                if let Some(binding) = binding {
+                    err.span_note(binding.span, &format!("the {} imported here", kind.descr()));
+                }
+                err.emit();
+            }
+        }
+    }
+
     fn suggest_macro_name(&mut self, name: &str, kind: MacroKind,
                           err: &mut DiagnosticBuilder<'a>, span: Span) {
         // First check if this is a locally-defined bang macro.
diff --git a/src/test/ui/rust-2018/uniform-paths/prelude-fail-2.rs b/src/test/ui/rust-2018/uniform-paths/prelude-fail-2.rs
new file mode 100644
index 00000000000..6488b89f369
--- /dev/null
+++ b/src/test/ui/rust-2018/uniform-paths/prelude-fail-2.rs
@@ -0,0 +1,9 @@
+// edition:2018
+
+#![feature(uniform_paths)]
+
+// Built-in attribute
+use inline as imported_inline;
+
+#[imported_inline] //~ ERROR cannot use a built-in attribute through an import
+fn main() {}
diff --git a/src/test/ui/rust-2018/uniform-paths/prelude-fail-2.stderr b/src/test/ui/rust-2018/uniform-paths/prelude-fail-2.stderr
new file mode 100644
index 00000000000..10dd303aa28
--- /dev/null
+++ b/src/test/ui/rust-2018/uniform-paths/prelude-fail-2.stderr
@@ -0,0 +1,14 @@
+error: cannot use a built-in attribute through an import
+  --> $DIR/prelude-fail-2.rs:8:3
+   |
+LL | #[imported_inline] //~ ERROR cannot use a built-in attribute through an import
+   |   ^^^^^^^^^^^^^^^
+   |
+note: the built-in attribute imported here
+  --> $DIR/prelude-fail-2.rs:6:5
+   |
+LL | use inline as imported_inline;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/rust-2018/uniform-paths/prelude.rs b/src/test/ui/rust-2018/uniform-paths/prelude.rs
index 5aab5fc3a40..46ce725fdba 100644
--- a/src/test/ui/rust-2018/uniform-paths/prelude.rs
+++ b/src/test/ui/rust-2018/uniform-paths/prelude.rs
@@ -6,9 +6,6 @@
 // Macro imported with `#[macro_use] extern crate`
 use vec as imported_vec;
 
-// Built-in attribute
-use inline as imported_inline;
-
 // Tool module
 use rustfmt as imported_rustfmt;
 
@@ -20,7 +17,6 @@ use u8 as imported_u8;
 
 type A = imported_u8;
 
-#[imported_inline]
 #[imported_rustfmt::skip]
 fn main() {
     imported_vec![0];