use syntax::ext::base::Determinacy::Undetermined;
use syntax::ext::hygiene::Mark;
use syntax::ext::tt::macro_rules;
+use syntax::feature_gate::is_builtin_attr;
use syntax::parse::token::{self, Token};
use syntax::std_inject::injected_crate_name;
use syntax::symbol::keywords;
}
}
}
+
+ fn visit_attribute(&mut self, attr: &'a ast::Attribute) {
+ if !attr.is_sugared_doc && is_builtin_attr(attr) {
+ self.resolver.current_module.builtin_attrs.borrow_mut().push((
+ attr.path.segments[0].ident, self.expansion, self.current_legacy_scope
+ ));
+ }
+ visit::walk_attribute(self, attr);
+ }
}
resolutions: RefCell<FxHashMap<(Ident, Namespace), &'a RefCell<NameResolution<'a>>>>,
legacy_macro_resolutions: RefCell<Vec<(Ident, MacroKind, Mark, LegacyScope<'a>, Option<Def>)>>,
macro_resolutions: RefCell<Vec<(Box<[Ident]>, Span)>>,
+ builtin_attrs: RefCell<Vec<(Ident, Mark, LegacyScope<'a>)>>,
// Macro invocations that can expand into items in this module.
unresolved_invocations: RefCell<FxHashSet<Mark>>,
resolutions: RefCell::new(FxHashMap()),
legacy_macro_resolutions: RefCell::new(Vec::new()),
macro_resolutions: RefCell::new(Vec::new()),
+ builtin_attrs: RefCell::new(Vec::new()),
unresolved_invocations: RefCell::new(FxHashSet()),
no_implicit_prelude: false,
glob_importers: RefCell::new(Vec::new()),
}
};
}
+
+ for &(ident, parent_expansion, parent_legacy_scope)
+ in module.builtin_attrs.borrow().iter() {
+ let resolve_legacy = |this: &mut Self| this.resolve_legacy_scope(
+ ident, parent_expansion, parent_legacy_scope, true, true
+ );
+ let resolve_modern = |this: &mut Self| this.resolve_lexical_macro_path_segment(
+ ident, MacroNS, parent_expansion, true, true, true, ident.span
+ ).map(|(binding, _)| binding).ok();
+
+ if let Some(binding) = resolve_legacy(self).or_else(|| resolve_modern(self)) {
+ if binding.def_ignoring_ambiguity() !=
+ Def::NonMacroAttr(NonMacroAttrKind::Builtin) {
+ let builtin_binding = (Def::NonMacroAttr(NonMacroAttrKind::Builtin),
+ ty::Visibility::Public, ident.span, Mark::root())
+ .to_name_binding(self.arenas);
+ self.report_ambiguity_error(ident, binding, builtin_binding);
+ }
+ }
+ }
}
fn suggest_macro_name(&mut self, name: &str, kind: MacroKind,
--- /dev/null
+// aux-build:builtin-attrs.rs
+// compile-flags:--test
+
+#![feature(decl_macro, test)]
+
+extern crate test;
+extern crate builtin_attrs;
+use builtin_attrs::{test, bench};
+
+#[test] // OK, shadowed
+fn test() {}
+
+#[bench] // OK, shadowed
+fn bench(b: &mut test::Bencher) {}
+
+fn not_main() {
+ Test;
+ Bench;
+ NonExistent; //~ ERROR cannot find value `NonExistent` in this scope
+}
--- /dev/null
+error[E0425]: cannot find value `NonExistent` in this scope
+ --> $DIR/ambiguous-builtin-attrs-test.rs:19:5
+ |
+LL | NonExistent; //~ ERROR cannot find value `NonExistent` in this scope
+ | ^^^^^^^^^^^ not found in this scope
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0425`.
--- /dev/null
+// aux-build:builtin-attrs.rs
+
+#![feature(decl_macro)] //~ ERROR `feature` is ambiguous
+
+extern crate builtin_attrs;
+use builtin_attrs::{test, bench};
+use builtin_attrs::*;
+
+#[repr(C)] //~ ERROR `repr` is ambiguous
+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() {}
+
+#[bench] // OK, shadowed
+fn bench() {}
+
+fn non_macro_expanded_location<#[repr(C)] T>() { //~ ERROR `repr` is ambiguous
+ match 0u8 {
+ #[repr(C)] //~ ERROR `repr` is ambiguous
+ _ => {}
+ }
+}
+
+fn main() {
+ Test;
+ Bench;
+ NonExistent; //~ ERROR cannot find value `NonExistent` in this scope
+}
--- /dev/null
+error[E0659]: `repr` is ambiguous
+ --> $DIR/ambiguous-builtin-attrs.rs:9:3
+ |
+LL | #[repr(C)] //~ ERROR `repr` is ambiguous
+ | ^^^^ ambiguous name
+ |
+note: `repr` could refer to the name imported here
+ --> $DIR/ambiguous-builtin-attrs.rs:7:5
+ |
+LL | use builtin_attrs::*;
+ | ^^^^^^^^^^^^^^^^
+note: `repr` could also refer to the name defined here
+ --> $DIR/ambiguous-builtin-attrs.rs:9:3
+ |
+LL | #[repr(C)] //~ ERROR `repr` is ambiguous
+ | ^^^^
+ = note: consider adding an explicit import of `repr` to disambiguate
+
+error[E0659]: `repr` is ambiguous
+ --> $DIR/ambiguous-builtin-attrs.rs:11:19
+ |
+LL | #[cfg_attr(all(), repr(C))] //~ ERROR `repr` is ambiguous
+ | ^^^^ ambiguous name
+ |
+note: `repr` could refer to the name imported here
+ --> $DIR/ambiguous-builtin-attrs.rs:7:5
+ |
+LL | use builtin_attrs::*;
+ | ^^^^^^^^^^^^^^^^
+note: `repr` could also refer to the name defined here
+ --> $DIR/ambiguous-builtin-attrs.rs:11:19
+ |
+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
+ |
+LL | fn non_macro_expanded_location<#[repr(C)] T>() { //~ ERROR `repr` is ambiguous
+ | ^^^^ ambiguous name
+ |
+note: `repr` could refer to the name imported here
+ --> $DIR/ambiguous-builtin-attrs.rs:7:5
+ |
+LL | use builtin_attrs::*;
+ | ^^^^^^^^^^^^^^^^
+note: `repr` could also refer to the name defined here
+ --> $DIR/ambiguous-builtin-attrs.rs:33: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
+ |
+LL | #[repr(C)] //~ ERROR `repr` is ambiguous
+ | ^^^^ ambiguous name
+ |
+note: `repr` could refer to the name imported here
+ --> $DIR/ambiguous-builtin-attrs.rs:7:5
+ |
+LL | use builtin_attrs::*;
+ | ^^^^^^^^^^^^^^^^
+note: `repr` could also refer to the name defined here
+ --> $DIR/ambiguous-builtin-attrs.rs:35:11
+ |
+LL | #[repr(C)] //~ ERROR `repr` is ambiguous
+ | ^^^^
+ = note: consider adding an explicit import of `repr` to disambiguate
+
+error[E0659]: `feature` is ambiguous
+ --> $DIR/ambiguous-builtin-attrs.rs:3:4
+ |
+LL | #![feature(decl_macro)] //~ ERROR `feature` is ambiguous
+ | ^^^^^^^ ambiguous name
+ |
+note: `feature` could refer to the name imported here
+ --> $DIR/ambiguous-builtin-attrs.rs:7:5
+ |
+LL | use builtin_attrs::*;
+ | ^^^^^^^^^^^^^^^^
+note: `feature` could also refer to the name defined here
+ --> $DIR/ambiguous-builtin-attrs.rs:3:4
+ |
+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
+ |
+LL | NonExistent; //~ ERROR cannot find value `NonExistent` in this scope
+ | ^^^^^^^^^^^ not found in this scope
+
+error: aborting due to 7 previous errors
+
+Some errors occurred: E0425, E0659.
+For more information about an error, try `rustc --explain E0425`.
--- /dev/null
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// no-prefer-dynamic
+
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+use proc_macro::*;
+
+#[proc_macro_attribute]
+pub fn feature(_: TokenStream, input: TokenStream) -> TokenStream {
+ input
+}
+
+#[proc_macro_attribute]
+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()
+}
+
+#[proc_macro_attribute]
+pub fn bench(_: TokenStream, input: TokenStream) -> TokenStream {
+ "struct Bench;".parse().unwrap()
+}