提交 a25c841e 编写于 作者: V Vadim Petrochenkov

resolve: Split macro prelude into built-in and user-defined parts

上级 2d4e34ca
...@@ -833,7 +833,7 @@ fn legacy_import_macro(&mut self, ...@@ -833,7 +833,7 @@ fn legacy_import_macro(&mut self,
binding: &'a NameBinding<'a>, binding: &'a NameBinding<'a>,
span: Span, span: Span,
allow_shadowing: bool) { allow_shadowing: bool) {
if self.macro_prelude.insert(name, binding).is_some() && !allow_shadowing { if self.macro_use_prelude.insert(name, binding).is_some() && !allow_shadowing {
let msg = format!("`{}` is already in scope", name); let msg = format!("`{}` is already in scope", name);
let note = let note =
"macro-expanded `#[macro_use]`s may not shadow existing macros (see RFC 1560)"; "macro-expanded `#[macro_use]`s may not shadow existing macros (see RFC 1560)";
......
...@@ -1278,6 +1278,13 @@ fn is_macro_def(&self) -> bool { ...@@ -1278,6 +1278,13 @@ fn is_macro_def(&self) -> bool {
} }
} }
fn macro_kind(&self) -> Option<MacroKind> {
match self.def_ignoring_ambiguity() {
Def::Macro(_, kind) => Some(kind),
_ => None,
}
}
fn descr(&self) -> &'static str { fn descr(&self) -> &'static str {
if self.is_extern_crate() { "extern crate" } else { self.def().kind_name() } if self.is_extern_crate() { "extern crate" } else { self.def().kind_name() }
} }
...@@ -1440,7 +1447,8 @@ pub struct Resolver<'a, 'b: 'a> { ...@@ -1440,7 +1447,8 @@ pub struct Resolver<'a, 'b: 'a> {
crate_loader: &'a mut CrateLoader<'b>, crate_loader: &'a mut CrateLoader<'b>,
macro_names: FxHashSet<Ident>, macro_names: FxHashSet<Ident>,
macro_prelude: FxHashMap<Name, &'a NameBinding<'a>>, builtin_macros: FxHashMap<Name, &'a NameBinding<'a>>,
macro_use_prelude: FxHashMap<Name, &'a NameBinding<'a>>,
unshadowable_attrs: FxHashMap<Name, &'a NameBinding<'a>>, unshadowable_attrs: FxHashMap<Name, &'a NameBinding<'a>>,
pub all_macros: FxHashMap<Name, Def>, pub all_macros: FxHashMap<Name, Def>,
macro_map: FxHashMap<DefId, Lrc<SyntaxExtension>>, macro_map: FxHashMap<DefId, Lrc<SyntaxExtension>>,
...@@ -1757,7 +1765,8 @@ pub fn new(session: &'a Session, ...@@ -1757,7 +1765,8 @@ pub fn new(session: &'a Session,
crate_loader, crate_loader,
macro_names: FxHashSet(), macro_names: FxHashSet(),
macro_prelude: FxHashMap(), builtin_macros: FxHashMap(),
macro_use_prelude: FxHashMap(),
unshadowable_attrs: FxHashMap(), unshadowable_attrs: FxHashMap(),
all_macros: FxHashMap(), all_macros: FxHashMap(),
macro_map: FxHashMap(), macro_map: FxHashMap(),
...@@ -3340,10 +3349,12 @@ fn resolve_qpath_anywhere(&mut self, ...@@ -3340,10 +3349,12 @@ fn resolve_qpath_anywhere(&mut self,
}; };
} }
} }
let is_global = self.macro_prelude.get(&path[0].name).cloned() if primary_ns != MacroNS &&
.map(|binding| binding.get_macro(self).kind() == MacroKind::Bang).unwrap_or(false); (self.macro_names.contains(&path[0].modern()) ||
if primary_ns != MacroNS && (is_global || self.builtin_macros.get(&path[0].name).cloned()
self.macro_names.contains(&path[0].modern())) { .and_then(NameBinding::macro_kind) == Some(MacroKind::Bang) ||
self.macro_use_prelude.get(&path[0].name).cloned()
.and_then(NameBinding::macro_kind) == Some(MacroKind::Bang)) {
// Return some dummy definition, it's enough for error reporting. // Return some dummy definition, it's enough for error reporting.
return Some( return Some(
PathResolution::new(Def::Macro(DefId::local(CRATE_DEF_INDEX), MacroKind::Bang)) PathResolution::new(Def::Macro(DefId::local(CRATE_DEF_INDEX), MacroKind::Bang))
......
...@@ -214,7 +214,10 @@ fn add_builtin(&mut self, ident: ast::Ident, ext: Lrc<SyntaxExtension>) { ...@@ -214,7 +214,10 @@ fn add_builtin(&mut self, ident: ast::Ident, ext: Lrc<SyntaxExtension>) {
vis: ty::Visibility::Invisible, vis: ty::Visibility::Invisible,
expansion: Mark::root(), expansion: Mark::root(),
}); });
self.macro_prelude.insert(ident.name, binding); if self.builtin_macros.insert(ident.name, binding).is_some() {
self.session.span_err(ident.span,
&format!("built-in macro `{}` was already defined", ident));
}
} }
fn add_unshadowable_attr(&mut self, ident: ast::Ident, ext: Lrc<SyntaxExtension>) { fn add_unshadowable_attr(&mut self, ident: ast::Ident, ext: Lrc<SyntaxExtension>) {
...@@ -249,7 +252,7 @@ fn find_legacy_attr_invoc(&mut self, attrs: &mut Vec<ast::Attribute>, allow_deri ...@@ -249,7 +252,7 @@ fn find_legacy_attr_invoc(&mut self, attrs: &mut Vec<ast::Attribute>, allow_deri
attr::mark_known(&attrs[i]); attr::mark_known(&attrs[i]);
} }
match self.macro_prelude.get(&name).cloned() { match self.builtin_macros.get(&name).cloned() {
Some(binding) => match *binding.get_macro(self) { Some(binding) => match *binding.get_macro(self) {
MultiModifier(..) | MultiDecorator(..) | SyntaxExtension::AttrProcMacro(..) => { MultiModifier(..) | MultiDecorator(..) | SyntaxExtension::AttrProcMacro(..) => {
return Some(attrs.remove(i)) return Some(attrs.remove(i))
...@@ -285,7 +288,7 @@ fn find_legacy_attr_invoc(&mut self, attrs: &mut Vec<ast::Attribute>, allow_deri ...@@ -285,7 +288,7 @@ fn find_legacy_attr_invoc(&mut self, attrs: &mut Vec<ast::Attribute>, allow_deri
} }
let trait_name = traits[j].segments[0].ident.name; let trait_name = traits[j].segments[0].ident.name;
let legacy_name = Symbol::intern(&format!("derive_{}", trait_name)); let legacy_name = Symbol::intern(&format!("derive_{}", trait_name));
if !self.macro_prelude.contains_key(&legacy_name) { if !self.builtin_macros.contains_key(&legacy_name) {
continue continue
} }
let span = traits.remove(j).span; let span = traits.remove(j).span;
...@@ -585,14 +588,12 @@ enum ConvertToDeriveHelper { Yes, No, DontKnow } ...@@ -585,14 +588,12 @@ enum ConvertToDeriveHelper { Yes, No, DontKnow }
// (Macro NS) // (Macro NS)
// 1. Names in modules (both normal `mod`ules and blocks), loop through hygienic parents // 1. Names in modules (both normal `mod`ules and blocks), loop through hygienic parents
// (open, not controlled). // (open, not controlled).
// 2. Macro prelude (language, standard library, user-defined legacy plugins lumped into // 2. `macro_use` prelude (open, the open part is from macro expansions, not controlled).
// one set) (open, the open part is from macro expansions, not controlled).
// 2a. User-defined prelude from macro-use // 2a. User-defined prelude from macro-use
// (open, the open part is from macro expansions, not controlled). // (open, the open part is from macro expansions, not controlled).
// 2b. Standard library prelude, currently just a macro-use (closed, controlled) // 2b. Standard library prelude is currently implemented as `macro-use` (closed, controlled)
// 2c. Language prelude, perhaps including builtin attributes // 3. Language prelude: builtin macros (closed, controlled, except for legacy plugins).
// (closed, controlled, except for legacy plugins). // 4. Language prelude: builtin attributes (closed, controlled).
// 3. Builtin attributes (closed, controlled).
assert!(ns == TypeNS || ns == MacroNS); assert!(ns == TypeNS || ns == MacroNS);
assert!(force || !record_used); // `record_used` implies `force` assert!(force || !record_used); // `record_used` implies `force`
...@@ -613,12 +614,13 @@ enum ConvertToDeriveHelper { Yes, No, DontKnow } ...@@ -613,12 +614,13 @@ enum ConvertToDeriveHelper { Yes, No, DontKnow }
enum WhereToResolve<'a> { enum WhereToResolve<'a> {
Module(Module<'a>), Module(Module<'a>),
MacroPrelude, MacroUsePrelude,
BuiltinMacros,
BuiltinAttrs, BuiltinAttrs,
ExternPrelude, ExternPrelude,
ToolPrelude, ToolPrelude,
StdLibPrelude, StdLibPrelude,
PrimitiveTypes, BuiltinTypes,
} }
// Go through all the scopes and try to resolve the name. // Go through all the scopes and try to resolve the name.
...@@ -639,8 +641,14 @@ enum WhereToResolve<'a> { ...@@ -639,8 +641,14 @@ enum WhereToResolve<'a> {
self.current_module = orig_current_module; self.current_module = orig_current_module;
binding.map(|binding| (binding, FromPrelude(false))) binding.map(|binding| (binding, FromPrelude(false)))
} }
WhereToResolve::MacroPrelude => { WhereToResolve::MacroUsePrelude => {
match self.macro_prelude.get(&ident.name).cloned() { match self.macro_use_prelude.get(&ident.name).cloned() {
Some(binding) => Ok((binding, FromPrelude(true))),
None => Err(Determinacy::Determined),
}
}
WhereToResolve::BuiltinMacros => {
match self.builtin_macros.get(&ident.name).cloned() {
Some(binding) => Ok((binding, FromPrelude(true))), Some(binding) => Ok((binding, FromPrelude(true))),
None => Err(Determinacy::Determined), None => Err(Determinacy::Determined),
} }
...@@ -708,7 +716,7 @@ enum WhereToResolve<'a> { ...@@ -708,7 +716,7 @@ enum WhereToResolve<'a> {
} }
result result
} }
WhereToResolve::PrimitiveTypes => { WhereToResolve::BuiltinTypes => {
if let Some(prim_ty) = if let Some(prim_ty) =
self.primitive_type_table.primitive_types.get(&ident.name).cloned() { self.primitive_type_table.primitive_types.get(&ident.name).cloned() {
let binding = (Def::PrimTy(prim_ty), ty::Visibility::Public, let binding = (Def::PrimTy(prim_ty), ty::Visibility::Public,
...@@ -728,19 +736,20 @@ enum WhereToResolve<'a> { ...@@ -728,19 +736,20 @@ enum WhereToResolve<'a> {
None => { None => {
use_prelude = !module.no_implicit_prelude; use_prelude = !module.no_implicit_prelude;
if ns == MacroNS { if ns == MacroNS {
WhereToResolve::MacroPrelude WhereToResolve::MacroUsePrelude
} else { } else {
WhereToResolve::ExternPrelude WhereToResolve::ExternPrelude
} }
} }
} }
} }
WhereToResolve::MacroPrelude => WhereToResolve::BuiltinAttrs, WhereToResolve::MacroUsePrelude => WhereToResolve::BuiltinMacros,
WhereToResolve::BuiltinMacros => WhereToResolve::BuiltinAttrs,
WhereToResolve::BuiltinAttrs => break, // nowhere else to search WhereToResolve::BuiltinAttrs => break, // nowhere else to search
WhereToResolve::ExternPrelude => WhereToResolve::ToolPrelude, WhereToResolve::ExternPrelude => WhereToResolve::ToolPrelude,
WhereToResolve::ToolPrelude => WhereToResolve::StdLibPrelude, WhereToResolve::ToolPrelude => WhereToResolve::StdLibPrelude,
WhereToResolve::StdLibPrelude => WhereToResolve::PrimitiveTypes, WhereToResolve::StdLibPrelude => WhereToResolve::BuiltinTypes,
WhereToResolve::PrimitiveTypes => break, // nowhere else to search WhereToResolve::BuiltinTypes => break, // nowhere else to search
}; };
continue; continue;
...@@ -958,14 +967,9 @@ fn suggest_macro_name(&mut self, name: &str, kind: MacroKind, ...@@ -958,14 +967,9 @@ fn suggest_macro_name(&mut self, name: &str, kind: MacroKind,
None None
// Then check global macros. // Then check global macros.
}.or_else(|| { }.or_else(|| {
// FIXME: get_macro needs an &mut Resolver, can we do it without cloning? let names = self.builtin_macros.iter().chain(self.macro_use_prelude.iter())
let macro_prelude = self.macro_prelude.clone(); .filter_map(|(name, binding)| {
let names = macro_prelude.iter().filter_map(|(name, binding)| { if binding.macro_kind() == Some(kind) { Some(name) } else { None }
if binding.get_macro(self).kind() == kind {
Some(name)
} else {
None
}
}); });
find_best_match_for_name(names, name, None) find_best_match_for_name(names, name, None)
// Then check modules. // Then check modules.
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册