Skip to content

Commit 9c88650

Browse files
committedNov 17, 2016
Add feature use_extern_macros.
1 parent b25c063 commit 9c88650

File tree

6 files changed

+238
-135
lines changed

6 files changed

+238
-135
lines changed
 

‎src/librustc_resolve/build_reduced_graph.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -504,9 +504,11 @@ impl<'b> Resolver<'b> {
504504
})
505505
}
506506

507-
pub fn get_macro(&mut self, def: Def) -> Rc<SyntaxExtension> {
508-
let def_id = match def {
509-
Def::Macro(def_id) => def_id,
507+
pub fn get_macro(&mut self, binding: &'b NameBinding<'b>) -> Rc<SyntaxExtension> {
508+
let def_id = match binding.kind {
509+
NameBindingKind::Def(Def::Macro(def_id)) => def_id,
510+
NameBindingKind::Import { binding, .. } => return self.get_macro(binding),
511+
NameBindingKind::Ambiguity { b1, .. } => return self.get_macro(b1),
510512
_ => panic!("Expected Def::Macro(..)"),
511513
};
512514
if let Some(ext) = self.macro_map.get(&def_id) {
@@ -579,7 +581,7 @@ impl<'b> Resolver<'b> {
579581
});
580582
} else {
581583
for (name, span) in legacy_imports.imports {
582-
let result = self.resolve_name_in_module(module, name, MacroNS, false, None);
584+
let result = self.resolve_name_in_module(module, name, MacroNS, false, false, None);
583585
if let Success(binding) = result {
584586
self.legacy_import_macro(name, binding, span, allow_shadowing);
585587
} else {
@@ -589,7 +591,7 @@ impl<'b> Resolver<'b> {
589591
}
590592
for (name, span) in legacy_imports.reexports {
591593
self.used_crates.insert(module.def_id().unwrap().krate);
592-
let result = self.resolve_name_in_module(module, name, MacroNS, false, None);
594+
let result = self.resolve_name_in_module(module, name, MacroNS, false, false, None);
593595
if let Success(binding) = result {
594596
self.macro_exports.push(Export { name: name, def: binding.def() });
595597
} else {

‎src/librustc_resolve/lib.rs

Lines changed: 41 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,7 @@ pub enum Namespace {
540540
pub struct PerNS<T> {
541541
value_ns: T,
542542
type_ns: T,
543+
macro_ns: Option<T>,
543544
}
544545

545546
impl<T> ::std::ops::Index<Namespace> for PerNS<T> {
@@ -548,7 +549,7 @@ impl<T> ::std::ops::Index<Namespace> for PerNS<T> {
548549
match ns {
549550
ValueNS => &self.value_ns,
550551
TypeNS => &self.type_ns,
551-
MacroNS => unreachable!(),
552+
MacroNS => self.macro_ns.as_ref().unwrap(),
552553
}
553554
}
554555
}
@@ -558,7 +559,7 @@ impl<T> ::std::ops::IndexMut<Namespace> for PerNS<T> {
558559
match ns {
559560
ValueNS => &mut self.value_ns,
560561
TypeNS => &mut self.type_ns,
561-
MacroNS => unreachable!(),
562+
MacroNS => self.macro_ns.as_mut().unwrap(),
562563
}
563564
}
564565
}
@@ -675,22 +676,14 @@ impl<'a> Visitor for Resolver<'a> {
675676

676677
pub type ErrorMessage = Option<(Span, String)>;
677678

678-
#[derive(Clone, PartialEq, Eq)]
679+
#[derive(Clone, PartialEq, Eq, Debug)]
679680
pub enum ResolveResult<T> {
680681
Failed(ErrorMessage), // Failed to resolve the name, optional helpful error message.
681682
Indeterminate, // Couldn't determine due to unresolved globs.
682683
Success(T), // Successfully resolved the import.
683684
}
684685

685686
impl<T> ResolveResult<T> {
686-
fn and_then<U, F: FnOnce(T) -> ResolveResult<U>>(self, f: F) -> ResolveResult<U> {
687-
match self {
688-
Failed(msg) => Failed(msg),
689-
Indeterminate => Indeterminate,
690-
Success(t) => f(t),
691-
}
692-
}
693-
694687
fn success(self) -> Option<T> {
695688
match self {
696689
Success(t) => Some(t),
@@ -825,6 +818,7 @@ pub struct ModuleS<'a> {
825818
normal_ancestor_id: Option<NodeId>,
826819

827820
resolutions: RefCell<FxHashMap<(Name, Namespace), &'a RefCell<NameResolution<'a>>>>,
821+
legacy_macro_resolutions: RefCell<Vec<(Mark, Name, Span)>>,
828822

829823
// Macro invocations that can expand into items in this module.
830824
unresolved_invocations: RefCell<FxHashSet<Mark>>,
@@ -852,6 +846,7 @@ impl<'a> ModuleS<'a> {
852846
kind: kind,
853847
normal_ancestor_id: None,
854848
resolutions: RefCell::new(FxHashMap()),
849+
legacy_macro_resolutions: RefCell::new(Vec::new()),
855850
unresolved_invocations: RefCell::new(FxHashSet()),
856851
no_implicit_prelude: false,
857852
glob_importers: RefCell::new(Vec::new()),
@@ -943,6 +938,7 @@ struct PrivacyError<'a>(Span, Name, &'a NameBinding<'a>);
943938
struct AmbiguityError<'a> {
944939
span: Span,
945940
name: Name,
941+
lexical: bool,
946942
b1: &'a NameBinding<'a>,
947943
b2: &'a NameBinding<'a>,
948944
}
@@ -1001,7 +997,7 @@ impl<'a> NameBinding<'a> {
1001997
fn is_glob_import(&self) -> bool {
1002998
match self.kind {
1003999
NameBindingKind::Import { directive, .. } => directive.is_glob(),
1004-
NameBindingKind::Ambiguity { .. } => true,
1000+
NameBindingKind::Ambiguity { b1, .. } => b1.is_glob_import(),
10051001
_ => false,
10061002
}
10071003
}
@@ -1136,6 +1132,7 @@ pub struct Resolver<'a> {
11361132
arenas: &'a ResolverArenas<'a>,
11371133
dummy_binding: &'a NameBinding<'a>,
11381134
new_import_semantics: bool, // true if `#![feature(item_like_imports)]`
1135+
use_extern_macros: bool, // true if `#![feature(use_extern_macros)]`
11391136

11401137
pub exported_macros: Vec<ast::MacroDef>,
11411138
crate_loader: &'a mut CrateLoader,
@@ -1300,6 +1297,7 @@ impl<'a> Resolver<'a> {
13001297
ribs: PerNS {
13011298
value_ns: vec![Rib::new(ModuleRibKind(graph_root))],
13021299
type_ns: vec![Rib::new(ModuleRibKind(graph_root))],
1300+
macro_ns: None,
13031301
},
13041302
label_ribs: Vec::new(),
13051303

@@ -1336,6 +1334,7 @@ impl<'a> Resolver<'a> {
13361334
vis: ty::Visibility::Public,
13371335
}),
13381336
new_import_semantics: session.features.borrow().item_like_imports,
1337+
use_extern_macros: session.features.borrow().use_extern_macros,
13391338

13401339
exported_macros: Vec::new(),
13411340
crate_loader: crate_loader,
@@ -1365,6 +1364,10 @@ impl<'a> Resolver<'a> {
13651364
PerNS {
13661365
type_ns: f(self, TypeNS),
13671366
value_ns: f(self, ValueNS),
1367+
macro_ns: match self.use_extern_macros {
1368+
true => Some(f(self, MacroNS)),
1369+
false => None,
1370+
},
13681371
}
13691372
}
13701373

@@ -1403,8 +1406,9 @@ impl<'a> Resolver<'a> {
14031406
}
14041407
NameBindingKind::Import { .. } => false,
14051408
NameBindingKind::Ambiguity { b1, b2 } => {
1406-
let ambiguity_error = AmbiguityError { span: span, name: name, b1: b1, b2: b2 };
1407-
self.ambiguity_errors.push(ambiguity_error);
1409+
self.ambiguity_errors.push(AmbiguityError {
1410+
span: span, name: name, lexical: false, b1: b1, b2: b2,
1411+
});
14081412
true
14091413
}
14101414
_ => false
@@ -1438,7 +1442,7 @@ impl<'a> Resolver<'a> {
14381442
-> ResolveResult<Module<'a>> {
14391443
fn search_parent_externals<'a>(this: &mut Resolver<'a>, needle: Name, module: Module<'a>)
14401444
-> Option<Module<'a>> {
1441-
match this.resolve_name_in_module(module, needle, TypeNS, false, None) {
1445+
match this.resolve_name_in_module(module, needle, TypeNS, false, false, None) {
14421446
Success(binding) if binding.is_extern_crate() => Some(module),
14431447
_ => if let (&ModuleKind::Def(..), Some(parent)) = (&module.kind, module.parent) {
14441448
search_parent_externals(this, needle, parent)
@@ -1456,7 +1460,7 @@ impl<'a> Resolver<'a> {
14561460
// modules as we go.
14571461
while index < module_path_len {
14581462
let name = module_path[index].name;
1459-
match self.resolve_name_in_module(search_module, name, TypeNS, false, span) {
1463+
match self.resolve_name_in_module(search_module, name, TypeNS, false, false, span) {
14601464
Failed(_) => {
14611465
let segment_name = name.as_str();
14621466
let module_name = module_to_string(search_module);
@@ -1613,7 +1617,7 @@ impl<'a> Resolver<'a> {
16131617

16141618
if let ModuleRibKind(module) = self.ribs[ns][i].kind {
16151619
let name = ident.name;
1616-
let item = self.resolve_name_in_module(module, name, ns, true, record_used);
1620+
let item = self.resolve_name_in_module(module, name, ns, true, false, record_used);
16171621
if let Success(binding) = item {
16181622
// The ident resolves to an item.
16191623
return Some(LexicalScopeBinding::Item(binding));
@@ -1622,7 +1626,7 @@ impl<'a> Resolver<'a> {
16221626
if let ModuleKind::Block(..) = module.kind { // We can see through blocks
16231627
} else if !module.no_implicit_prelude {
16241628
return self.prelude.and_then(|prelude| {
1625-
self.resolve_name_in_module(prelude, name, ns, false, None).success()
1629+
self.resolve_name_in_module(prelude, name, ns, false, false, None).success()
16261630
}).map(LexicalScopeBinding::Item)
16271631
} else {
16281632
return None;
@@ -1717,6 +1721,7 @@ impl<'a> Resolver<'a> {
17171721
self.ribs[ValueNS].push(Rib::new(ModuleRibKind(module)));
17181722
self.ribs[TypeNS].push(Rib::new(ModuleRibKind(module)));
17191723

1724+
self.finalize_current_module_macro_resolutions();
17201725
f(self);
17211726

17221727
self.current_module = orig_module;
@@ -2221,6 +2226,7 @@ impl<'a> Resolver<'a> {
22212226
self.ribs[ValueNS].push(Rib::new(ModuleRibKind(anonymous_module)));
22222227
self.ribs[TypeNS].push(Rib::new(ModuleRibKind(anonymous_module)));
22232228
self.current_module = anonymous_module;
2229+
self.finalize_current_module_macro_resolutions();
22242230
} else {
22252231
self.ribs[ValueNS].push(Rib::new(NormalRibKind));
22262232
}
@@ -2754,23 +2760,19 @@ impl<'a> Resolver<'a> {
27542760
let module_path =
27552761
segments.split_last().unwrap().1.iter().map(|ps| ps.identifier).collect::<Vec<_>>();
27562762

2757-
let containing_module;
2758-
match self.resolve_module_path(&module_path, UseLexicalScope, Some(span)) {
2763+
let module = match self.resolve_module_path(&module_path, UseLexicalScope, Some(span)) {
27592764
Failed(err) => {
27602765
if let Some((span, msg)) = err {
27612766
resolve_error(self, span, ResolutionError::FailedToResolve(&msg));
27622767
}
27632768
return Err(true);
27642769
}
27652770
Indeterminate => return Err(false),
2766-
Success(resulting_module) => {
2767-
containing_module = resulting_module;
2768-
}
2769-
}
2771+
Success(module) => module,
2772+
};
27702773

27712774
let name = segments.last().unwrap().identifier.name;
2772-
let result =
2773-
self.resolve_name_in_module(containing_module, name, namespace, false, Some(span));
2775+
let result = self.resolve_name_in_module(module, name, namespace, false, false, Some(span));
27742776
result.success().ok_or(false)
27752777
}
27762778

@@ -2782,10 +2784,9 @@ impl<'a> Resolver<'a> {
27822784
where T: Named,
27832785
{
27842786
let module_path = segments.split_last().unwrap().1.iter().map(T::ident).collect::<Vec<_>>();
2785-
let root_module = self.graph_root;
2787+
let root = self.graph_root;
27862788

2787-
let containing_module;
2788-
match self.resolve_module_path_from_root(root_module, &module_path, 0, Some(span)) {
2789+
let module = match self.resolve_module_path_from_root(root, &module_path, 0, Some(span)) {
27892790
Failed(err) => {
27902791
if let Some((span, msg)) = err {
27912792
resolve_error(self, span, ResolutionError::FailedToResolve(&msg));
@@ -2795,14 +2796,11 @@ impl<'a> Resolver<'a> {
27952796

27962797
Indeterminate => return Err(false),
27972798

2798-
Success(resulting_module) => {
2799-
containing_module = resulting_module;
2800-
}
2801-
}
2799+
Success(module) => module,
2800+
};
28022801

28032802
let name = segments.last().unwrap().ident().name;
2804-
let result =
2805-
self.resolve_name_in_module(containing_module, name, namespace, false, Some(span));
2803+
let result = self.resolve_name_in_module(module, name, namespace, false, false, Some(span));
28062804
result.success().ok_or(false)
28072805
}
28082806

@@ -3383,14 +3381,18 @@ impl<'a> Resolver<'a> {
33833381
self.report_shadowing_errors();
33843382
let mut reported_spans = FxHashSet();
33853383

3386-
for &AmbiguityError { span, name, b1, b2 } in &self.ambiguity_errors {
3384+
for &AmbiguityError { span, name, b1, b2, lexical } in &self.ambiguity_errors {
33873385
if !reported_spans.insert(span) { continue }
33883386
let msg1 = format!("`{}` could resolve to the name imported here", name);
33893387
let msg2 = format!("`{}` could also resolve to the name imported here", name);
33903388
self.session.struct_span_err(span, &format!("`{}` is ambiguous", name))
33913389
.span_note(b1.span, &msg1)
33923390
.span_note(b2.span, &msg2)
3393-
.note(&format!("Consider adding an explicit import of `{}` to disambiguate", name))
3391+
.note(&if lexical || !b1.is_glob_import() {
3392+
"macro-expanded macro imports do not shadow".to_owned()
3393+
} else {
3394+
format!("consider adding an explicit import of `{}` to disambiguate", name)
3395+
})
33943396
.emit();
33953397
}
33963398

@@ -3413,12 +3415,12 @@ impl<'a> Resolver<'a> {
34133415

34143416
fn report_shadowing_errors(&mut self) {
34153417
for (name, scope) in replace(&mut self.lexical_macro_resolutions, Vec::new()) {
3416-
self.resolve_macro_name(scope, name);
3418+
self.resolve_legacy_scope(scope, name, true);
34173419
}
34183420

34193421
let mut reported_errors = FxHashSet();
34203422
for binding in replace(&mut self.disallowed_shadowing, Vec::new()) {
3421-
if self.resolve_macro_name(binding.parent, binding.name).is_some() &&
3423+
if self.resolve_legacy_scope(binding.parent, binding.name, false).is_some() &&
34223424
reported_errors.insert((binding.name, binding.span)) {
34233425
let msg = format!("`{}` is already in scope", binding.name);
34243426
self.session.struct_span_err(binding.span, &msg)

‎src/librustc_resolve/macros.rs

Lines changed: 122 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
use {Module, ModuleKind, NameBinding, NameBindingKind, Resolver};
11+
use {Module, ModuleKind, NameBinding, NameBindingKind, Resolver, AmbiguityError};
12+
use Namespace::{self, MacroNS};
13+
use ResolveResult::{Success, Indeterminate, Failed};
1214
use build_reduced_graph::BuildReducedGraphVisitor;
1315
use resolve_imports::ImportResolver;
1416
use rustc::hir::def_id::{DefId, BUILTIN_MACROS_CRATE, CRATE_DEF_INDEX, DefIndex};
@@ -17,7 +19,7 @@ use rustc::hir::map::{self, DefCollector};
1719
use rustc::ty;
1820
use std::cell::Cell;
1921
use std::rc::Rc;
20-
use syntax::ast;
22+
use syntax::ast::{self, Name};
2123
use syntax::errors::DiagnosticBuilder;
2224
use syntax::ext::base::{self, Determinacy, MultiModifier, MultiDecorator};
2325
use syntax::ext::base::{NormalTT, SyntaxExtension};
@@ -85,6 +87,11 @@ pub struct LegacyBinding<'a> {
8587
pub span: Span,
8688
}
8789

90+
pub enum MacroBinding<'a> {
91+
Legacy(&'a LegacyBinding<'a>),
92+
Modern(&'a NameBinding<'a>),
93+
}
94+
8895
impl<'a> base::Resolver for Resolver<'a> {
8996
fn next_node_id(&mut self) -> ast::NodeId {
9097
self.session.next_node_id()
@@ -140,6 +147,7 @@ impl<'a> base::Resolver for Resolver<'a> {
140147
expansion: mark,
141148
};
142149
expansion.visit_with(&mut visitor);
150+
self.current_module.unresolved_invocations.borrow_mut().remove(&mark);
143151
invocation.expansion.set(visitor.legacy_scope);
144152
}
145153

@@ -201,7 +209,7 @@ impl<'a> base::Resolver for Resolver<'a> {
201209
for i in 0..attrs.len() {
202210
let name = intern(&attrs[i].name());
203211
match self.builtin_macros.get(&name).cloned() {
204-
Some(binding) => match *self.get_macro(binding.def()) {
212+
Some(binding) => match *self.get_macro(binding) {
205213
MultiModifier(..) | MultiDecorator(..) | SyntaxExtension::AttrProcMacro(..) => {
206214
return Some(attrs.remove(i))
207215
}
@@ -225,25 +233,77 @@ impl<'a> base::Resolver for Resolver<'a> {
225233
if let LegacyScope::Expansion(parent) = invocation.legacy_scope.get() {
226234
invocation.legacy_scope.set(LegacyScope::simplify_expansion(parent));
227235
}
228-
self.resolve_macro_name(invocation.legacy_scope.get(), name).ok_or_else(|| {
229-
if force {
230-
let msg = format!("macro undefined: '{}!'", name);
231-
let mut err = self.session.struct_span_err(path.span, &msg);
232-
self.suggest_macro_name(&name.as_str(), &mut err);
233-
err.emit();
234-
Determinacy::Determined
235-
} else {
236-
Determinacy::Undetermined
237-
}
238-
})
236+
237+
self.current_module = invocation.module.get();
238+
let result = match self.resolve_legacy_scope(invocation.legacy_scope.get(), name, false) {
239+
Some(MacroBinding::Legacy(binding)) => Ok(binding.ext.clone()),
240+
Some(MacroBinding::Modern(binding)) => Ok(self.get_macro(binding)),
241+
None => match self.resolve_in_item_lexical_scope(name, MacroNS, None) {
242+
Some(binding) => Ok(self.get_macro(binding)),
243+
None => return Err(if force {
244+
let msg = format!("macro undefined: '{}!'", name);
245+
let mut err = self.session.struct_span_err(path.span, &msg);
246+
self.suggest_macro_name(&name.as_str(), &mut err);
247+
err.emit();
248+
Determinacy::Determined
249+
} else {
250+
Determinacy::Undetermined
251+
}),
252+
},
253+
};
254+
255+
if self.use_extern_macros {
256+
self.current_module.legacy_macro_resolutions.borrow_mut()
257+
.push((scope, name, path.span));
258+
}
259+
result
239260
}
240261
}
241262

242263
impl<'a> Resolver<'a> {
243-
pub fn resolve_macro_name(&mut self, mut scope: LegacyScope<'a>, name: ast::Name)
244-
-> Option<Rc<SyntaxExtension>> {
264+
// Resolve the name in the module's lexical scope, excluding non-items.
265+
fn resolve_in_item_lexical_scope(
266+
&mut self, name: Name, ns: Namespace, record_used: Option<Span>,
267+
) -> Option<&'a NameBinding<'a>> {
268+
let mut module = self.current_module;
269+
let mut potential_expanded_shadower = None;
270+
loop {
271+
// Since expanded macros may not shadow the lexical scope (enforced below),
272+
// we can ignore unresolved invocations (indicated by the penultimate argument).
273+
match self.resolve_name_in_module(module, name, ns, true, true, record_used) {
274+
Success(binding) => {
275+
let span = match record_used {
276+
Some(span) => span,
277+
None => return Some(binding),
278+
};
279+
if let Some(shadower) = potential_expanded_shadower {
280+
self.ambiguity_errors.push(AmbiguityError {
281+
span: span, name: name, b1: shadower, b2: binding, lexical: true,
282+
});
283+
return Some(shadower);
284+
} else if binding.expansion == Mark::root() {
285+
return Some(binding);
286+
} else {
287+
potential_expanded_shadower = Some(binding);
288+
}
289+
},
290+
Indeterminate => return None,
291+
Failed(..) => {}
292+
}
293+
294+
match module.kind {
295+
ModuleKind::Block(..) => module = module.parent.unwrap(),
296+
ModuleKind::Def(..) => return potential_expanded_shadower,
297+
}
298+
}
299+
}
300+
301+
pub fn resolve_legacy_scope(
302+
&mut self, mut scope: LegacyScope<'a>, name: ast::Name, record_used: bool,
303+
) -> Option<MacroBinding<'a>> {
245304
let mut possible_time_travel = None;
246305
let mut relative_depth: u32 = 0;
306+
let mut binding = None;
247307
loop {
248308
scope = match scope {
249309
LegacyScope::Empty => break,
@@ -262,25 +322,59 @@ impl<'a> Resolver<'a> {
262322
relative_depth = relative_depth.saturating_sub(1);
263323
invocation.legacy_scope.get()
264324
}
265-
LegacyScope::Binding(binding) => {
266-
if binding.name == name {
267-
if let Some(scope) = possible_time_travel {
268-
// Check for disallowed shadowing later
269-
self.lexical_macro_resolutions.push((name, scope));
270-
} else if relative_depth > 0 {
271-
self.disallowed_shadowing.push(binding);
325+
LegacyScope::Binding(potential_binding) => {
326+
if potential_binding.name == name {
327+
if (!self.use_extern_macros || record_used) && relative_depth > 0 {
328+
self.disallowed_shadowing.push(potential_binding);
272329
}
273-
return Some(binding.ext.clone());
330+
binding = Some(potential_binding);
331+
break
274332
}
275-
binding.parent
333+
potential_binding.parent
276334
}
277335
};
278336
}
279337

280-
if let Some(scope) = possible_time_travel {
281-
self.lexical_macro_resolutions.push((name, scope));
338+
let binding = match binding {
339+
Some(binding) => MacroBinding::Legacy(binding),
340+
None => match self.builtin_macros.get(&name).cloned() {
341+
Some(binding) => MacroBinding::Modern(binding),
342+
None => return None,
343+
},
344+
};
345+
346+
if !self.use_extern_macros {
347+
if let Some(scope) = possible_time_travel {
348+
// Check for disallowed shadowing later
349+
self.lexical_macro_resolutions.push((name, scope));
350+
}
351+
}
352+
353+
Some(binding)
354+
}
355+
356+
pub fn finalize_current_module_macro_resolutions(&mut self) {
357+
let module = self.current_module;
358+
for &(mark, name, span) in module.legacy_macro_resolutions.borrow().iter() {
359+
let legacy_scope = self.invocations[&mark].legacy_scope.get();
360+
let legacy_resolution = self.resolve_legacy_scope(legacy_scope, name, true);
361+
let resolution = self.resolve_in_item_lexical_scope(name, MacroNS, Some(span));
362+
let (legacy_resolution, resolution) = match (legacy_resolution, resolution) {
363+
(Some(legacy_resolution), Some(resolution)) => (legacy_resolution, resolution),
364+
_ => continue,
365+
};
366+
let (legacy_span, participle) = match legacy_resolution {
367+
MacroBinding::Modern(binding) if binding.def() == resolution.def() => continue,
368+
MacroBinding::Modern(binding) => (binding.span, "imported"),
369+
MacroBinding::Legacy(binding) => (binding.span, "defined"),
370+
};
371+
let msg1 = format!("`{}` could resolve to the macro {} here", name, participle);
372+
let msg2 = format!("`{}` could also resolve to the macro imported here", name);
373+
self.session.struct_span_err(span, &format!("`{}` is ambiguous", name))
374+
.span_note(legacy_span, &msg1)
375+
.span_note(resolution.span, &msg2)
376+
.emit();
282377
}
283-
self.builtin_macros.get(&name).cloned().map(|binding| self.get_macro(binding.def()))
284378
}
285379

286380
fn suggest_macro_name(&mut self, name: &str, err: &mut DiagnosticBuilder<'a>) {

‎src/librustc_resolve/resolve_imports.rs

Lines changed: 64 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
use self::ImportDirectiveSubclass::*;
1212

1313
use {Module, PerNS};
14-
use Namespace::{self, TypeNS};
14+
use Namespace::{self, TypeNS, MacroNS};
1515
use {NameBinding, NameBindingKind, PrivacyError, ToNameBinding};
1616
use ResolveResult;
1717
use ResolveResult::*;
@@ -142,6 +142,7 @@ impl<'a> Resolver<'a> {
142142
name: Name,
143143
ns: Namespace,
144144
allow_private_imports: bool,
145+
ignore_unresolved_invocations: bool,
145146
record_used: Option<Span>)
146147
-> ResolveResult<&'a NameBinding<'a>> {
147148
self.populate_module_if_necessary(module);
@@ -175,70 +176,65 @@ impl<'a> Resolver<'a> {
175176
return resolution.binding.map(Success).unwrap_or(Failed(None));
176177
}
177178

178-
// If the resolution doesn't depend on glob definability, check privacy and return.
179-
if let Some(result) = self.try_result(&resolution, module, ns) {
180-
return result.and_then(|binding| {
181-
if self.is_accessible(binding.vis) && !is_disallowed_private_import(binding) ||
182-
binding.is_extern_crate() { // c.f. issue #37020
183-
Success(binding)
184-
} else {
185-
Failed(None)
186-
}
187-
});
188-
}
179+
let check_usable = |this: &mut Self, binding: &'a NameBinding<'a>| {
180+
let usable =
181+
this.is_accessible(binding.vis) && !is_disallowed_private_import(binding) ||
182+
binding.is_extern_crate(); // c.f. issue #37020
183+
if usable { Success(binding) } else { Failed(None) }
184+
};
189185

190-
// Check if the globs are determined
191-
for directive in module.globs.borrow().iter() {
192-
if self.is_accessible(directive.vis.get()) {
193-
if let Some(module) = directive.imported_module.get() {
194-
let result = self.resolve_name_in_module(module, name, ns, true, None);
195-
if let Indeterminate = result {
196-
return Indeterminate;
197-
}
198-
} else {
199-
return Indeterminate;
200-
}
186+
// Items and single imports are not shadowable.
187+
if let Some(binding) = resolution.binding {
188+
if !binding.is_glob_import() {
189+
return check_usable(self, binding);
201190
}
202191
}
203192

204-
Failed(None)
205-
}
206-
207-
// Returns Some(the resolution of the name), or None if the resolution depends
208-
// on whether more globs can define the name.
209-
fn try_result(&mut self, resolution: &NameResolution<'a>, module: Module<'a>, ns: Namespace)
210-
-> Option<ResolveResult<&'a NameBinding<'a>>> {
211-
match resolution.binding {
212-
Some(binding) if !binding.is_glob_import() =>
213-
return Some(Success(binding)), // Items and single imports are not shadowable.
214-
_ => {}
215-
};
216-
217193
// Check if a single import can still define the name.
218194
match resolution.single_imports {
219-
SingleImports::AtLeastOne => return Some(Indeterminate),
195+
SingleImports::AtLeastOne => return Indeterminate,
220196
SingleImports::MaybeOne(directive) if self.is_accessible(directive.vis.get()) => {
221197
let module = match directive.imported_module.get() {
222198
Some(module) => module,
223-
None => return Some(Indeterminate),
199+
None => return Indeterminate,
224200
};
225201
let name = match directive.subclass {
226202
SingleImport { source, .. } => source,
227203
_ => unreachable!(),
228204
};
229-
match self.resolve_name_in_module(module, name, ns, true, None) {
205+
match self.resolve_name_in_module(module, name, ns, true, false, None) {
230206
Failed(_) => {}
231-
_ => return Some(Indeterminate),
207+
_ => return Indeterminate,
232208
}
233209
}
234210
SingleImports::MaybeOne(_) | SingleImports::None => {},
235211
}
236212

237-
if !module.unresolved_invocations.borrow().is_empty() {
238-
return Some(Indeterminate);
213+
let no_unresolved_invocations =
214+
ignore_unresolved_invocations || module.unresolved_invocations.borrow().is_empty();
215+
match resolution.binding {
216+
// In `MacroNS`, expanded bindings do not shadow (enforced in `try_define`).
217+
Some(binding) if no_unresolved_invocations || ns == MacroNS =>
218+
return check_usable(self, binding),
219+
None if no_unresolved_invocations => {}
220+
_ => return Indeterminate,
239221
}
240222

241-
resolution.binding.map(Success)
223+
// Check if the globs are determined
224+
for directive in module.globs.borrow().iter() {
225+
if self.is_accessible(directive.vis.get()) {
226+
if let Some(module) = directive.imported_module.get() {
227+
let result = self.resolve_name_in_module(module, name, ns, true, false, None);
228+
if let Indeterminate = result {
229+
return Indeterminate;
230+
}
231+
} else {
232+
return Indeterminate;
233+
}
234+
}
235+
}
236+
237+
Failed(None)
242238
}
243239

244240
// Add an import directive to the current module.
@@ -315,29 +311,26 @@ impl<'a> Resolver<'a> {
315311
self.update_resolution(module, name, ns, |this, resolution| {
316312
if let Some(old_binding) = resolution.binding {
317313
if binding.is_glob_import() {
318-
if !this.new_import_semantics || !old_binding.is_glob_import() {
314+
if !this.new_import_semantics {
319315
resolution.duplicate_globs.push(binding);
316+
} else if !old_binding.is_glob_import() &&
317+
!(ns == MacroNS && old_binding.expansion != Mark::root()) {
320318
} else if binding.def() != old_binding.def() {
321-
resolution.binding = Some(this.arenas.alloc_name_binding(NameBinding {
322-
kind: NameBindingKind::Ambiguity {
323-
b1: old_binding,
324-
b2: binding,
325-
},
326-
vis: if old_binding.vis.is_at_least(binding.vis, this) {
327-
old_binding.vis
328-
} else {
329-
binding.vis
330-
},
331-
span: old_binding.span,
332-
expansion: Mark::root(),
333-
}));
319+
resolution.binding = Some(this.ambiguity(old_binding, binding));
334320
} else if !old_binding.vis.is_at_least(binding.vis, this) {
335321
// We are glob-importing the same item but with greater visibility.
336322
resolution.binding = Some(binding);
337323
}
338324
} else if old_binding.is_glob_import() {
339-
resolution.duplicate_globs.push(old_binding);
340-
resolution.binding = Some(binding);
325+
if !this.new_import_semantics {
326+
resolution.duplicate_globs.push(old_binding);
327+
resolution.binding = Some(binding);
328+
} else if ns == MacroNS && binding.expansion != Mark::root() &&
329+
binding.def() != old_binding.def() {
330+
resolution.binding = Some(this.ambiguity(binding, old_binding));
331+
} else {
332+
resolution.binding = Some(binding);
333+
}
341334
} else {
342335
return Err(old_binding);
343336
}
@@ -349,6 +342,16 @@ impl<'a> Resolver<'a> {
349342
})
350343
}
351344

345+
pub fn ambiguity(&mut self, b1: &'a NameBinding<'a>, b2: &'a NameBinding<'a>)
346+
-> &'a NameBinding<'a> {
347+
self.arenas.alloc_name_binding(NameBinding {
348+
kind: NameBindingKind::Ambiguity { b1: b1, b2: b2 },
349+
vis: if b1.vis.is_at_least(b2.vis, self) { b1.vis } else { b2.vis },
350+
span: b1.span,
351+
expansion: Mark::root(),
352+
})
353+
}
354+
352355
// Use `f` to mutate the resolution of the name in the module.
353356
// If the resolution becomes a success, define it in the module's glob importers.
354357
fn update_resolution<T, F>(&mut self, module: Module<'a>, name: Name, ns: Namespace, f: F) -> T
@@ -525,7 +528,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
525528
self.per_ns(|this, ns| {
526529
if let Err(Undetermined) = result[ns].get() {
527530
result[ns].set({
528-
match this.resolve_name_in_module(module, source, ns, false, None) {
531+
match this.resolve_name_in_module(module, source, ns, false, false, None) {
529532
Success(binding) => Ok(binding),
530533
Indeterminate => Err(Undetermined),
531534
Failed(_) => Err(Determined),
@@ -621,7 +624,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
621624
if all_ns_err {
622625
let mut all_ns_failed = true;
623626
self.per_ns(|this, ns| {
624-
match this.resolve_name_in_module(module, name, ns, false, Some(span)) {
627+
match this.resolve_name_in_module(module, name, ns, false, false, Some(span)) {
625628
Success(_) => all_ns_failed = false,
626629
_ => {}
627630
}

‎src/libsyntax/feature_gate.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,8 @@ declare_features! (
314314

315315
// Allows #[link(..., cfg(..))]
316316
(active, link_cfg, "1.14.0", Some(37406)),
317+
318+
(active, use_extern_macros, "1.15.0", Some(35896)),
317319
);
318320

319321
declare_features! (

‎src/test/compile-fail/imports/duplicate.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,9 @@ mod g {
4646
fn main() {
4747
e::foo();
4848
f::foo(); //~ ERROR `foo` is ambiguous
49-
//~| NOTE Consider adding an explicit import of `foo` to disambiguate
49+
//~| NOTE consider adding an explicit import of `foo` to disambiguate
5050
g::foo(); //~ ERROR `foo` is ambiguous
51-
//~| NOTE Consider adding an explicit import of `foo` to disambiguate
51+
//~| NOTE consider adding an explicit import of `foo` to disambiguate
5252
}
5353

5454
mod ambiguous_module_errors {

0 commit comments

Comments
 (0)
Please sign in to comment.