Skip to content

Commit a25c841

Browse files
committed
resolve: Split macro prelude into built-in and user-defined parts
1 parent 2d4e34c commit a25c841

File tree

3 files changed

+48
-33
lines changed

3 files changed

+48
-33
lines changed

src/librustc_resolve/build_reduced_graph.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -833,7 +833,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
833833
binding: &'a NameBinding<'a>,
834834
span: Span,
835835
allow_shadowing: bool) {
836-
if self.macro_prelude.insert(name, binding).is_some() && !allow_shadowing {
836+
if self.macro_use_prelude.insert(name, binding).is_some() && !allow_shadowing {
837837
let msg = format!("`{}` is already in scope", name);
838838
let note =
839839
"macro-expanded `#[macro_use]`s may not shadow existing macros (see RFC 1560)";

src/librustc_resolve/lib.rs

+17-6
Original file line numberDiff line numberDiff line change
@@ -1278,6 +1278,13 @@ impl<'a> NameBinding<'a> {
12781278
}
12791279
}
12801280

1281+
fn macro_kind(&self) -> Option<MacroKind> {
1282+
match self.def_ignoring_ambiguity() {
1283+
Def::Macro(_, kind) => Some(kind),
1284+
_ => None,
1285+
}
1286+
}
1287+
12811288
fn descr(&self) -> &'static str {
12821289
if self.is_extern_crate() { "extern crate" } else { self.def().kind_name() }
12831290
}
@@ -1440,7 +1447,8 @@ pub struct Resolver<'a, 'b: 'a> {
14401447

14411448
crate_loader: &'a mut CrateLoader<'b>,
14421449
macro_names: FxHashSet<Ident>,
1443-
macro_prelude: FxHashMap<Name, &'a NameBinding<'a>>,
1450+
builtin_macros: FxHashMap<Name, &'a NameBinding<'a>>,
1451+
macro_use_prelude: FxHashMap<Name, &'a NameBinding<'a>>,
14441452
unshadowable_attrs: FxHashMap<Name, &'a NameBinding<'a>>,
14451453
pub all_macros: FxHashMap<Name, Def>,
14461454
macro_map: FxHashMap<DefId, Lrc<SyntaxExtension>>,
@@ -1757,7 +1765,8 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
17571765

17581766
crate_loader,
17591767
macro_names: FxHashSet(),
1760-
macro_prelude: FxHashMap(),
1768+
builtin_macros: FxHashMap(),
1769+
macro_use_prelude: FxHashMap(),
17611770
unshadowable_attrs: FxHashMap(),
17621771
all_macros: FxHashMap(),
17631772
macro_map: FxHashMap(),
@@ -3340,10 +3349,12 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
33403349
};
33413350
}
33423351
}
3343-
let is_global = self.macro_prelude.get(&path[0].name).cloned()
3344-
.map(|binding| binding.get_macro(self).kind() == MacroKind::Bang).unwrap_or(false);
3345-
if primary_ns != MacroNS && (is_global ||
3346-
self.macro_names.contains(&path[0].modern())) {
3352+
if primary_ns != MacroNS &&
3353+
(self.macro_names.contains(&path[0].modern()) ||
3354+
self.builtin_macros.get(&path[0].name).cloned()
3355+
.and_then(NameBinding::macro_kind) == Some(MacroKind::Bang) ||
3356+
self.macro_use_prelude.get(&path[0].name).cloned()
3357+
.and_then(NameBinding::macro_kind) == Some(MacroKind::Bang)) {
33473358
// Return some dummy definition, it's enough for error reporting.
33483359
return Some(
33493360
PathResolution::new(Def::Macro(DefId::local(CRATE_DEF_INDEX), MacroKind::Bang))

src/librustc_resolve/macros.rs

+30-26
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,10 @@ impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> {
214214
vis: ty::Visibility::Invisible,
215215
expansion: Mark::root(),
216216
});
217-
self.macro_prelude.insert(ident.name, binding);
217+
if self.builtin_macros.insert(ident.name, binding).is_some() {
218+
self.session.span_err(ident.span,
219+
&format!("built-in macro `{}` was already defined", ident));
220+
}
218221
}
219222

220223
fn add_unshadowable_attr(&mut self, ident: ast::Ident, ext: Lrc<SyntaxExtension>) {
@@ -249,7 +252,7 @@ impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> {
249252
attr::mark_known(&attrs[i]);
250253
}
251254

252-
match self.macro_prelude.get(&name).cloned() {
255+
match self.builtin_macros.get(&name).cloned() {
253256
Some(binding) => match *binding.get_macro(self) {
254257
MultiModifier(..) | MultiDecorator(..) | SyntaxExtension::AttrProcMacro(..) => {
255258
return Some(attrs.remove(i))
@@ -285,7 +288,7 @@ impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> {
285288
}
286289
let trait_name = traits[j].segments[0].ident.name;
287290
let legacy_name = Symbol::intern(&format!("derive_{}", trait_name));
288-
if !self.macro_prelude.contains_key(&legacy_name) {
291+
if !self.builtin_macros.contains_key(&legacy_name) {
289292
continue
290293
}
291294
let span = traits.remove(j).span;
@@ -585,14 +588,12 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
585588
// (Macro NS)
586589
// 1. Names in modules (both normal `mod`ules and blocks), loop through hygienic parents
587590
// (open, not controlled).
588-
// 2. Macro prelude (language, standard library, user-defined legacy plugins lumped into
589-
// one set) (open, the open part is from macro expansions, not controlled).
591+
// 2. `macro_use` prelude (open, the open part is from macro expansions, not controlled).
590592
// 2a. User-defined prelude from macro-use
591593
// (open, the open part is from macro expansions, not controlled).
592-
// 2b. Standard library prelude, currently just a macro-use (closed, controlled)
593-
// 2c. Language prelude, perhaps including builtin attributes
594-
// (closed, controlled, except for legacy plugins).
595-
// 3. Builtin attributes (closed, controlled).
594+
// 2b. Standard library prelude is currently implemented as `macro-use` (closed, controlled)
595+
// 3. Language prelude: builtin macros (closed, controlled, except for legacy plugins).
596+
// 4. Language prelude: builtin attributes (closed, controlled).
596597

597598
assert!(ns == TypeNS || ns == MacroNS);
598599
assert!(force || !record_used); // `record_used` implies `force`
@@ -613,12 +614,13 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
613614

614615
enum WhereToResolve<'a> {
615616
Module(Module<'a>),
616-
MacroPrelude,
617+
MacroUsePrelude,
618+
BuiltinMacros,
617619
BuiltinAttrs,
618620
ExternPrelude,
619621
ToolPrelude,
620622
StdLibPrelude,
621-
PrimitiveTypes,
623+
BuiltinTypes,
622624
}
623625

624626
// Go through all the scopes and try to resolve the name.
@@ -639,8 +641,14 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
639641
self.current_module = orig_current_module;
640642
binding.map(|binding| (binding, FromPrelude(false)))
641643
}
642-
WhereToResolve::MacroPrelude => {
643-
match self.macro_prelude.get(&ident.name).cloned() {
644+
WhereToResolve::MacroUsePrelude => {
645+
match self.macro_use_prelude.get(&ident.name).cloned() {
646+
Some(binding) => Ok((binding, FromPrelude(true))),
647+
None => Err(Determinacy::Determined),
648+
}
649+
}
650+
WhereToResolve::BuiltinMacros => {
651+
match self.builtin_macros.get(&ident.name).cloned() {
644652
Some(binding) => Ok((binding, FromPrelude(true))),
645653
None => Err(Determinacy::Determined),
646654
}
@@ -708,7 +716,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
708716
}
709717
result
710718
}
711-
WhereToResolve::PrimitiveTypes => {
719+
WhereToResolve::BuiltinTypes => {
712720
if let Some(prim_ty) =
713721
self.primitive_type_table.primitive_types.get(&ident.name).cloned() {
714722
let binding = (Def::PrimTy(prim_ty), ty::Visibility::Public,
@@ -728,19 +736,20 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
728736
None => {
729737
use_prelude = !module.no_implicit_prelude;
730738
if ns == MacroNS {
731-
WhereToResolve::MacroPrelude
739+
WhereToResolve::MacroUsePrelude
732740
} else {
733741
WhereToResolve::ExternPrelude
734742
}
735743
}
736744
}
737745
}
738-
WhereToResolve::MacroPrelude => WhereToResolve::BuiltinAttrs,
746+
WhereToResolve::MacroUsePrelude => WhereToResolve::BuiltinMacros,
747+
WhereToResolve::BuiltinMacros => WhereToResolve::BuiltinAttrs,
739748
WhereToResolve::BuiltinAttrs => break, // nowhere else to search
740749
WhereToResolve::ExternPrelude => WhereToResolve::ToolPrelude,
741750
WhereToResolve::ToolPrelude => WhereToResolve::StdLibPrelude,
742-
WhereToResolve::StdLibPrelude => WhereToResolve::PrimitiveTypes,
743-
WhereToResolve::PrimitiveTypes => break, // nowhere else to search
751+
WhereToResolve::StdLibPrelude => WhereToResolve::BuiltinTypes,
752+
WhereToResolve::BuiltinTypes => break, // nowhere else to search
744753
};
745754

746755
continue;
@@ -958,14 +967,9 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
958967
None
959968
// Then check global macros.
960969
}.or_else(|| {
961-
// FIXME: get_macro needs an &mut Resolver, can we do it without cloning?
962-
let macro_prelude = self.macro_prelude.clone();
963-
let names = macro_prelude.iter().filter_map(|(name, binding)| {
964-
if binding.get_macro(self).kind() == kind {
965-
Some(name)
966-
} else {
967-
None
968-
}
970+
let names = self.builtin_macros.iter().chain(self.macro_use_prelude.iter())
971+
.filter_map(|(name, binding)| {
972+
if binding.macro_kind() == Some(kind) { Some(name) } else { None }
969973
});
970974
find_best_match_for_name(names, name, None)
971975
// Then check modules.

0 commit comments

Comments
 (0)