From bf1e70cd1f39c0879b36bead3b07a0fdfcfc4c32 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Wed, 12 Dec 2018 04:11:46 +0300 Subject: [PATCH] resolve: Prohibit use of imported non-macro attributes --- src/librustc/hir/def.rs | 2 +- src/librustc_resolve/macros.rs | 19 ++++++++++++++++++- .../rust-2018/uniform-paths/prelude-fail-2.rs | 9 +++++++++ .../uniform-paths/prelude-fail-2.stderr | 14 ++++++++++++++ .../ui/rust-2018/uniform-paths/prelude.rs | 4 ---- 5 files changed, 42 insertions(+), 6 deletions(-) create mode 100644 src/test/ui/rust-2018/uniform-paths/prelude-fail-2.rs create mode 100644 src/test/ui/rust-2018/uniform-paths/prelude-fail-2.stderr diff --git a/src/librustc/hir/def.rs b/src/librustc/hir/def.rs index 20ec620a281f..2382a2ea50bb 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 b2b794c6925c..037ade13c208 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, 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 000000000000..6488b89f3698 --- /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 000000000000..10dd303aa283 --- /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 5aab5fc3a401..46ce725fdba9 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];