diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 351963bff5bf3..7733ce475e339 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -1083,6 +1083,9 @@ impl<'a, 'cl> Resolver<'a, 'cl> { self.define(module, ident, MacroNS, (def, vis, item.span, expansion, IsMacroExport)); } else { + if !attr::contains_name(&item.attrs, "rustc_doc_only_macro") { + self.check_reserved_macro_name(ident, MacroNS); + } self.unused_macros.insert(def_id); } } else { diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 68709f6891ab7..dfbea0ffe2288 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -452,6 +452,16 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { }) } + crate fn check_reserved_macro_name(&self, ident: Ident, ns: Namespace) { + // Reserve some names that are not quite covered by the general check + // performed on `Resolver::builtin_attrs`. + if ns == MacroNS && + (ident.name == "cfg" || ident.name == "cfg_attr" || ident.name == "derive") { + self.session.span_err(ident.span, + &format!("name `{}` is reserved in macro namespace", ident)); + } + } + // Define the name or return the existing binding if there is a collision. pub fn try_define(&mut self, module: Module<'a>, @@ -459,6 +469,7 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { ns: Namespace, binding: &'a NameBinding<'a>) -> Result<(), &'a NameBinding<'a>> { + self.check_reserved_macro_name(ident, ns); self.update_resolution(module, ident, ns, |this, resolution| { if let Some(old_binding) = resolution.binding { if binding.is_glob_import() { diff --git a/src/test/ui-fulldeps/proc-macro/ambiguous-builtin-attrs.rs b/src/test/ui-fulldeps/proc-macro/ambiguous-builtin-attrs.rs index b3a50e8fb7c33..9f4f0abf32486 100644 --- a/src/test/ui-fulldeps/proc-macro/ambiguous-builtin-attrs.rs +++ b/src/test/ui-fulldeps/proc-macro/ambiguous-builtin-attrs.rs @@ -11,19 +11,6 @@ struct S; #[cfg_attr(all(), repr(C))] //~ ERROR `repr` is ambiguous struct SCond; -#[cfg(all())] //~ ERROR `cfg` is ambiguous -struct A; -#[cfg(any())] // ERROR FIXME -struct A; - -#[cfg_attr(all(), cold)] // ERROR FIXME -fn g() {} -#[cfg_attr(any(), cold)] // ERROR FIXME -fn h() {} - -#[derive(Clone)] // ERROR FIXME -struct B; - #[test] // OK, shadowed fn test() {} diff --git a/src/test/ui-fulldeps/proc-macro/ambiguous-builtin-attrs.stderr b/src/test/ui-fulldeps/proc-macro/ambiguous-builtin-attrs.stderr index 2bf3082aa4228..ea867faf47bb6 100644 --- a/src/test/ui-fulldeps/proc-macro/ambiguous-builtin-attrs.stderr +++ b/src/test/ui-fulldeps/proc-macro/ambiguous-builtin-attrs.stderr @@ -34,26 +34,8 @@ LL | #[cfg_attr(all(), repr(C))] //~ ERROR `repr` is ambiguous | ^^^^ = note: consider adding an explicit import of `repr` to disambiguate -error[E0659]: `cfg` is ambiguous - --> $DIR/ambiguous-builtin-attrs.rs:14:3 - | -LL | #[cfg(all())] //~ ERROR `cfg` is ambiguous - | ^^^ ambiguous name - | -note: `cfg` could refer to the name imported here - --> $DIR/ambiguous-builtin-attrs.rs:7:5 - | -LL | use builtin_attrs::*; - | ^^^^^^^^^^^^^^^^ -note: `cfg` could also refer to the name defined here - --> $DIR/ambiguous-builtin-attrs.rs:14:3 - | -LL | #[cfg(all())] //~ ERROR `cfg` is ambiguous - | ^^^ - = note: consider adding an explicit import of `cfg` to disambiguate - error[E0659]: `repr` is ambiguous - --> $DIR/ambiguous-builtin-attrs.rs:33:34 + --> $DIR/ambiguous-builtin-attrs.rs:20:34 | LL | fn non_macro_expanded_location<#[repr(C)] T>() { //~ ERROR `repr` is ambiguous | ^^^^ ambiguous name @@ -64,14 +46,14 @@ note: `repr` could refer to the name imported here LL | use builtin_attrs::*; | ^^^^^^^^^^^^^^^^ note: `repr` could also refer to the name defined here - --> $DIR/ambiguous-builtin-attrs.rs:33:34 + --> $DIR/ambiguous-builtin-attrs.rs:20:34 | LL | fn non_macro_expanded_location<#[repr(C)] T>() { //~ ERROR `repr` is ambiguous | ^^^^ = note: consider adding an explicit import of `repr` to disambiguate error[E0659]: `repr` is ambiguous - --> $DIR/ambiguous-builtin-attrs.rs:35:11 + --> $DIR/ambiguous-builtin-attrs.rs:22:11 | LL | #[repr(C)] //~ ERROR `repr` is ambiguous | ^^^^ ambiguous name @@ -82,7 +64,7 @@ note: `repr` could refer to the name imported here LL | use builtin_attrs::*; | ^^^^^^^^^^^^^^^^ note: `repr` could also refer to the name defined here - --> $DIR/ambiguous-builtin-attrs.rs:35:11 + --> $DIR/ambiguous-builtin-attrs.rs:22:11 | LL | #[repr(C)] //~ ERROR `repr` is ambiguous | ^^^^ @@ -107,12 +89,12 @@ LL | #![feature(decl_macro)] //~ ERROR `feature` is ambiguous = note: consider adding an explicit import of `feature` to disambiguate error[E0425]: cannot find value `NonExistent` in this scope - --> $DIR/ambiguous-builtin-attrs.rs:43:5 + --> $DIR/ambiguous-builtin-attrs.rs:30:5 | LL | NonExistent; //~ ERROR cannot find value `NonExistent` in this scope | ^^^^^^^^^^^ not found in this scope -error: aborting due to 7 previous errors +error: aborting due to 6 previous errors Some errors occurred: E0425, E0659. For more information about an error, try `rustc --explain E0425`. diff --git a/src/test/ui-fulldeps/proc-macro/auxiliary/builtin-attrs.rs b/src/test/ui-fulldeps/proc-macro/auxiliary/builtin-attrs.rs index 332df815b1933..e18ca57aab1fc 100644 --- a/src/test/ui-fulldeps/proc-macro/auxiliary/builtin-attrs.rs +++ b/src/test/ui-fulldeps/proc-macro/auxiliary/builtin-attrs.rs @@ -25,21 +25,6 @@ pub fn repr(_: TokenStream, input: TokenStream) -> TokenStream { input } -#[proc_macro_attribute] -pub fn cfg(_: TokenStream, input: TokenStream) -> TokenStream { - input -} - -#[proc_macro_attribute] -pub fn cfg_attr(_: TokenStream, input: TokenStream) -> TokenStream { - input -} - -#[proc_macro_attribute] -pub fn derive(_: TokenStream, input: TokenStream) -> TokenStream { - input -} - #[proc_macro_attribute] pub fn test(_: TokenStream, input: TokenStream) -> TokenStream { "struct Test;".parse().unwrap() diff --git a/src/test/ui-fulldeps/proc-macro/reserved-macro-names.rs b/src/test/ui-fulldeps/proc-macro/reserved-macro-names.rs new file mode 100644 index 0000000000000..ff5984aa67c7a --- /dev/null +++ b/src/test/ui-fulldeps/proc-macro/reserved-macro-names.rs @@ -0,0 +1,22 @@ +#![crate_type = "proc-macro"] + +extern crate proc_macro; +use proc_macro::*; + +#[proc_macro_attribute] +pub fn cfg(_: TokenStream, input: TokenStream) -> TokenStream { + //~^ ERROR name `cfg` is reserved in macro namespace + input +} + +#[proc_macro_attribute] +pub fn cfg_attr(_: TokenStream, input: TokenStream) -> TokenStream { + //~^ ERROR name `cfg_attr` is reserved in macro namespace + input +} + +#[proc_macro_attribute] +pub fn derive(_: TokenStream, input: TokenStream) -> TokenStream { + //~^ ERROR name `derive` is reserved in macro namespace + input +} diff --git a/src/test/ui-fulldeps/proc-macro/reserved-macro-names.stderr b/src/test/ui-fulldeps/proc-macro/reserved-macro-names.stderr new file mode 100644 index 0000000000000..be6e80c3878e1 --- /dev/null +++ b/src/test/ui-fulldeps/proc-macro/reserved-macro-names.stderr @@ -0,0 +1,20 @@ +error: name `cfg` is reserved in macro namespace + --> $DIR/reserved-macro-names.rs:7:8 + | +LL | pub fn cfg(_: TokenStream, input: TokenStream) -> TokenStream { + | ^^^ + +error: name `cfg_attr` is reserved in macro namespace + --> $DIR/reserved-macro-names.rs:13:8 + | +LL | pub fn cfg_attr(_: TokenStream, input: TokenStream) -> TokenStream { + | ^^^^^^^^ + +error: name `derive` is reserved in macro namespace + --> $DIR/reserved-macro-names.rs:19:8 + | +LL | pub fn derive(_: TokenStream, input: TokenStream) -> TokenStream { + | ^^^^^^ + +error: aborting due to 3 previous errors +