)>| {
let subclass = SingleImport {
target: Ident {
name: keywords::Underscore.name().gensymed(),
- span: source.span,
+ span: source.0.span,
},
- source,
+ source: source.0,
result: PerNS {
type_ns: Cell::new(Err(Undetermined)),
value_ns: Cell::new(Err(Undetermined)),
@@ -199,7 +199,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
this.add_import_directive(
base.into_iter().collect(),
subclass.clone(),
- source.span,
+ source.0.span,
id,
root_use_tree.span,
root_id,
@@ -210,15 +210,15 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
};
// A single simple `self::x` canary.
- emit(self, Some(Ident {
+ emit(self, Some((Ident {
name: keywords::SelfValue.name(),
- span: source.span,
- }));
+ span: source.0.span,
+ }, source.1)));
// One special unprefixed canary per block scope around
// the import, to detect items unreachable by `self::x`.
let orig_current_module = self.current_module;
- let mut span = source.span.modern();
+ let mut span = source.0.span.modern();
loop {
match self.current_module.kind {
ModuleKind::Block(..) => emit(self, None),
@@ -244,10 +244,10 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
if nested {
// Correctly handle `self`
- if source.name == keywords::SelfValue.name() {
+ if source.0.name == keywords::SelfValue.name() {
type_ns_only = true;
- let empty_prefix = module_path.last().map_or(true, |ident| {
+ let empty_prefix = module_path.last().map_or(true, |(ident, _)| {
ident.name == keywords::CrateRoot.name()
});
if empty_prefix {
@@ -263,20 +263,20 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
// Replace `use foo::self;` with `use foo;`
source = module_path.pop().unwrap();
if rename.is_none() {
- ident = source;
+ ident = source.0;
}
}
} else {
// Disallow `self`
- if source.name == keywords::SelfValue.name() {
+ if source.0.name == keywords::SelfValue.name() {
resolve_error(self,
use_tree.span,
ResolutionError::SelfImportsOnlyAllowedWithin);
}
// Disallow `use $crate;`
- if source.name == keywords::DollarCrate.name() && module_path.is_empty() {
- let crate_root = self.resolve_crate_root(source);
+ if source.0.name == keywords::DollarCrate.name() && module_path.is_empty() {
+ let crate_root = self.resolve_crate_root(source.0);
let crate_name = match crate_root.kind {
ModuleKind::Def(_, name) => name,
ModuleKind::Block(..) => unreachable!(),
@@ -286,11 +286,11 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
// while the current crate doesn't have a valid `crate_name`.
if crate_name != keywords::Invalid.name() {
// `crate_name` should not be interpreted as relative.
- module_path.push(Ident {
+ module_path.push((Ident {
name: keywords::CrateRoot.name(),
- span: source.span,
- });
- source.name = crate_name;
+ span: source.0.span,
+ }, Some(self.session.next_node_id())));
+ source.0.name = crate_name;
}
if rename.is_none() {
ident.name = crate_name;
@@ -311,7 +311,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
let subclass = SingleImport {
target: ident,
- source,
+ source: source.0,
result: PerNS {
type_ns: Cell::new(Err(Undetermined)),
value_ns: Cell::new(Err(Undetermined)),
@@ -349,13 +349,6 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
);
}
ast::UseTreeKind::Nested(ref items) => {
- let prefix = ast::Path {
- segments: module_path.into_iter()
- .map(|ident| ast::PathSegment::from_ident(ident))
- .collect(),
- span: path.span,
- };
-
// Ensure there is at most one `self` in the list
let self_spans = items.iter().filter_map(|&(ref use_tree, _)| {
if let ast::UseTreeKind::Simple(..) = use_tree.kind {
@@ -379,6 +372,17 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
}
for &(ref tree, id) in items {
+ let prefix = ast::Path {
+ segments: module_path.iter()
+ .map(|ident| {
+ let mut seg = ast::PathSegment::from_ident(ident.0);
+ seg.id = self.session.next_node_id();
+ seg
+ })
+ .collect(),
+ span: path.span,
+ };
+
self.build_reduced_graph_for_use_tree(
root_use_tree,
root_id,
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 78c518aea961d..5535882d2db4d 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -1497,8 +1497,13 @@ impl<'a, 'b: 'a, 'cl: 'b> ty::DefIdTree for &'a Resolver<'b, 'cl> {
/// This interface is used through the AST→HIR step, to embed full paths into the HIR. After that
/// the resolver is no longer needed as all the relevant information is inline.
impl<'a, 'cl> hir::lowering::Resolver for Resolver<'a, 'cl> {
- fn resolve_hir_path(&mut self, path: &mut hir::Path, is_value: bool) {
- self.resolve_hir_path_cb(path, is_value,
+ fn resolve_hir_path(
+ &mut self,
+ path: &ast::Path,
+ args: Option>,
+ is_value: bool,
+ ) -> hir::Path {
+ self.resolve_hir_path_cb(path, args, is_value,
|resolver, span, error| resolve_error(resolver, span, error))
}
@@ -1510,30 +1515,20 @@ impl<'a, 'cl> hir::lowering::Resolver for Resolver<'a, 'cl> {
args: Option
>,
is_value: bool
) -> hir::Path {
- let mut segments = iter::once(keywords::CrateRoot.ident())
+ let segments = iter::once(keywords::CrateRoot.ident())
.chain(
crate_root.into_iter()
.chain(components.iter().cloned())
.map(Ident::from_str)
- ).map(hir::PathSegment::from_ident).collect::>();
+ ).map(|i| self.new_ast_path_segment(i)).collect::>();
- if let Some(args) = args {
- let ident = segments.last().unwrap().ident;
- *segments.last_mut().unwrap() = hir::PathSegment {
- ident,
- args: Some(args),
- infer_types: true,
- };
- }
- let mut path = hir::Path {
+ let path = ast::Path {
span,
- def: Def::Err,
- segments: segments.into(),
+ segments,
};
- self.resolve_hir_path(&mut path, is_value);
- path
+ self.resolve_hir_path(&path, args, is_value)
}
fn get_resolution(&mut self, id: NodeId) -> Option {
@@ -1559,23 +1554,27 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> {
use std::iter;
let mut errored = false;
- let mut path = if path_str.starts_with("::") {
- hir::Path {
+ let path = if path_str.starts_with("::") {
+ ast::Path {
span,
- def: Def::Err,
- segments: iter::once(keywords::CrateRoot.ident()).chain({
- path_str.split("::").skip(1).map(Ident::from_str)
- }).map(hir::PathSegment::from_ident).collect(),
+ segments: iter::once(keywords::CrateRoot.ident())
+ .chain({
+ path_str.split("::").skip(1).map(Ident::from_str)
+ })
+ .map(|i| self.new_ast_path_segment(i))
+ .collect(),
}
} else {
- hir::Path {
+ ast::Path {
span,
- def: Def::Err,
- segments: path_str.split("::").map(Ident::from_str)
- .map(hir::PathSegment::from_ident).collect(),
+ segments: path_str
+ .split("::")
+ .map(Ident::from_str)
+ .map(|i| self.new_ast_path_segment(i))
+ .collect(),
}
};
- self.resolve_hir_path_cb(&mut path, is_value, |_, _, _| errored = true);
+ let path = self.resolve_hir_path_cb(&path, None, is_value, |_, _, _| errored = true);
if errored || path.def == Def::Err {
Err(())
} else {
@@ -1584,38 +1583,67 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> {
}
/// resolve_hir_path, but takes a callback in case there was an error
- fn resolve_hir_path_cb(&mut self, path: &mut hir::Path, is_value: bool, error_callback: F)
+ fn resolve_hir_path_cb(
+ &mut self,
+ path: &ast::Path,
+ args: Option>,
+ is_value: bool,
+ error_callback: F,
+ ) -> hir::Path
where F: for<'c, 'b> FnOnce(&'c mut Resolver, Span, ResolutionError<'b>)
{
let namespace = if is_value { ValueNS } else { TypeNS };
- let hir::Path { ref segments, span, ref mut def } = *path;
- let path: Vec<_> = segments.iter().map(|seg| seg.ident).collect();
+ let span = path.span;
+ let segments = &path.segments;
+ let path: Vec<_> = segments.iter().map(|seg| (seg.ident, Some(seg.id))).collect();
// FIXME (Manishearth): Intra doc links won't get warned of epoch changes
- match self.resolve_path(None, &path, Some(namespace), true, span, CrateLint::No) {
+ let def = match self.resolve_path(None, &path, Some(namespace), true, span, CrateLint::No) {
PathResult::Module(ModuleOrUniformRoot::Module(module)) =>
- *def = module.def().unwrap(),
+ module.def().unwrap(),
PathResult::NonModule(path_res) if path_res.unresolved_segments() == 0 =>
- *def = path_res.base_def(),
- PathResult::NonModule(..) => match self.resolve_path(
- None,
- &path,
- None,
- true,
- span,
- CrateLint::No,
- ) {
- PathResult::Failed(span, msg, _) => {
- error_callback(self, span, ResolutionError::FailedToResolve(&msg));
+ path_res.base_def(),
+ PathResult::NonModule(..) => {
+ match self.resolve_path(
+ None,
+ &path,
+ None,
+ true,
+ span,
+ CrateLint::No,
+ ) {
+ PathResult::Failed(span, msg, _) => {
+ error_callback(self, span, ResolutionError::FailedToResolve(&msg));
+ }
+ _ => {}
}
- _ => {}
- },
+ Def::Err
+ }
PathResult::Module(ModuleOrUniformRoot::UniformRoot(_)) |
PathResult::Indeterminate => unreachable!(),
PathResult::Failed(span, msg, _) => {
error_callback(self, span, ResolutionError::FailedToResolve(&msg));
+ Def::Err
}
+ };
+
+ let mut segments: Vec<_> = segments.iter().map(|seg| {
+ let mut hir_seg = hir::PathSegment::from_ident(seg.ident);
+ hir_seg.def = Some(self.def_map.get(&seg.id).map_or(Def::Err, |p| p.base_def()));
+ hir_seg
+ }).collect();
+ segments.last_mut().unwrap().args = args;
+ hir::Path {
+ span,
+ def,
+ segments: segments.into(),
}
}
+
+ fn new_ast_path_segment(&self, ident: Ident) -> ast::PathSegment {
+ let mut seg = ast::PathSegment::from_ident(ident);
+ seg.id = self.session.next_node_id();
+ seg
+ }
}
impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
@@ -2432,7 +2460,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
let mut new_id = None;
if let Some(trait_ref) = opt_trait_ref {
let path: Vec<_> = trait_ref.path.segments.iter()
- .map(|seg| seg.ident)
+ .map(|seg| (seg.ident, Some(seg.id)))
.collect();
let def = self.smart_resolve_path_fragment(
trait_ref.ref_id,
@@ -2915,7 +2943,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
crate_lint: CrateLint
) -> PathResolution {
let segments = &path.segments.iter()
- .map(|seg| seg.ident)
+ .map(|seg| (seg.ident, Some(seg.id)))
.collect::>();
self.smart_resolve_path_fragment(id, qself, segments, path.span, source, crate_lint)
}
@@ -2923,12 +2951,12 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
fn smart_resolve_path_fragment(&mut self,
id: NodeId,
qself: Option<&QSelf>,
- path: &[Ident],
+ path: &[(Ident, Option)],
span: Span,
source: PathSource,
crate_lint: CrateLint)
-> PathResolution {
- let ident_span = path.last().map_or(span, |ident| ident.span);
+ let ident_span = path.last().map_or(span, |ident| ident.0.span);
let ns = source.namespace();
let is_expected = &|def| source.is_expected(def);
let is_enum_variant = &|def| if let Def::Variant(..) = def { true } else { false };
@@ -2937,18 +2965,18 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
let report_errors = |this: &mut Self, def: Option| {
// Make the base error.
let expected = source.descr_expected();
- let path_str = names_to_string(path);
+ let path_str = names_and_ids_to_string(path);
let code = source.error_code(def.is_some());
let (base_msg, fallback_label, base_span) = if let Some(def) = def {
(format!("expected {}, found {} `{}`", expected, def.kind_name(), path_str),
format!("not a {}", expected),
span)
} else {
- let item_str = path[path.len() - 1];
- let item_span = path[path.len() - 1].span;
+ let item_str = path[path.len() - 1].0;
+ let item_span = path[path.len() - 1].0.span;
let (mod_prefix, mod_str) = if path.len() == 1 {
(String::new(), "this scope".to_string())
- } else if path.len() == 2 && path[0].name == keywords::CrateRoot.name() {
+ } else if path.len() == 2 && path[0].0.name == keywords::CrateRoot.name() {
(String::new(), "the crate root".to_string())
} else {
let mod_path = &path[..path.len() - 1];
@@ -2958,7 +2986,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
module.def(),
_ => None,
}.map_or(String::new(), |def| format!("{} ", def.kind_name()));
- (mod_prefix, format!("`{}`", names_to_string(mod_path)))
+ (mod_prefix, format!("`{}`", names_and_ids_to_string(mod_path)))
};
(format!("cannot find {} `{}` in {}{}", expected, item_str, mod_prefix, mod_str),
format!("not found in {}", mod_str),
@@ -2988,7 +3016,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
}
// Try to lookup the name in more relaxed fashion for better error reporting.
- let ident = *path.last().unwrap();
+ let ident = path.last().unwrap().0;
let candidates = this.lookup_import_candidates(ident.name, ns, is_expected);
if candidates.is_empty() && is_expected(Def::Enum(DefId::local(CRATE_DEF_INDEX))) {
let enum_candidates =
@@ -3011,7 +3039,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
}
if path.len() == 1 && this.self_type_is_available(span) {
if let Some(candidate) = this.lookup_assoc_candidate(ident, ns, is_expected) {
- let self_is_available = this.self_value_is_available(path[0].span, span);
+ let self_is_available = this.self_value_is_available(path[0].0.span, span);
match candidate {
AssocSuggestion::Field => {
err.span_suggestion(span, "try",
@@ -3202,7 +3230,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
// or `::A::B`. If `B` should be resolved in value namespace then
// it needs to be added to the trait map.
if ns == ValueNS {
- let item_name = *path.last().unwrap();
+ let item_name = path.last().unwrap().0;
let traits = self.get_traits_containing_item(item_name, ns);
self.trait_map.insert(id, traits);
}
@@ -3269,7 +3297,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
fn resolve_qpath_anywhere(&mut self,
id: NodeId,
qself: Option<&QSelf>,
- path: &[Ident],
+ path: &[(Ident, Option)],
primary_ns: Namespace,
span: Span,
defer_to_typeck: bool,
@@ -3290,10 +3318,10 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
};
}
}
- let is_global = self.macro_prelude.get(&path[0].name).cloned()
+ let is_global = self.macro_prelude.get(&path[0].0.name).cloned()
.map(|binding| binding.get_macro(self).kind() == MacroKind::Bang).unwrap_or(false);
if primary_ns != MacroNS && (is_global ||
- self.macro_names.contains(&path[0].modern())) {
+ self.macro_names.contains(&path[0].0.modern())) {
// Return some dummy definition, it's enough for error reporting.
return Some(
PathResolution::new(Def::Macro(DefId::local(CRATE_DEF_INDEX), MacroKind::Bang))
@@ -3306,7 +3334,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
fn resolve_qpath(&mut self,
id: NodeId,
qself: Option<&QSelf>,
- path: &[Ident],
+ path: &[(Ident, Option)],
ns: Namespace,
span: Span,
global_by_default: bool,
@@ -3396,8 +3424,8 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
PathResult::Failed(..)
if (ns == TypeNS || path.len() > 1) &&
self.primitive_type_table.primitive_types
- .contains_key(&path[0].name) => {
- let prim = self.primitive_type_table.primitive_types[&path[0].name];
+ .contains_key(&path[0].0.name) => {
+ let prim = self.primitive_type_table.primitive_types[&path[0].0.name];
PathResolution::with_unresolved_segments(Def::PrimTy(prim), path.len() - 1)
}
PathResult::Module(ModuleOrUniformRoot::Module(module)) =>
@@ -3412,8 +3440,8 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
};
if path.len() > 1 && !global_by_default && result.base_def() != Def::Err &&
- path[0].name != keywords::CrateRoot.name() &&
- path[0].name != keywords::DollarCrate.name() {
+ path[0].0.name != keywords::CrateRoot.name() &&
+ path[0].0.name != keywords::DollarCrate.name() {
let unqualified_result = {
match self.resolve_path(
None,
@@ -3441,7 +3469,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
fn resolve_path(
&mut self,
base_module: Option>,
- path: &[Ident],
+ path: &[(Ident, Option)],
opt_ns: Option, // `None` indicates a module path
record_used: bool,
path_span: Span,
@@ -3461,7 +3489,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
crate_lint,
);
- for (i, &ident) in path.iter().enumerate() {
+ for (i, &(ident, id)) in path.iter().enumerate() {
debug!("resolve_path ident {} {:?}", i, ident);
let is_last = i == path.len() - 1;
let ns = if is_last { opt_ns.unwrap_or(TypeNS) } else { TypeNS };
@@ -3523,7 +3551,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
} else {
format!("`{}`", name)
};
- let msg = if i == 1 && path[0].name == keywords::CrateRoot.name() {
+ let msg = if i == 1 && path[0].0.name == keywords::CrateRoot.name() {
format!("global paths cannot start with {}", name_str)
} else {
format!("{} in paths can only be used in start position", name_str)
@@ -3563,6 +3591,12 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
let maybe_assoc = opt_ns != Some(MacroNS) && PathSource::Type.is_expected(def);
if let Some(next_module) = binding.module() {
module = Some(ModuleOrUniformRoot::Module(next_module));
+ if !is_last && record_used {
+ if let Some(id) = id {
+ assert!(id != ast::DUMMY_NODE_ID, "Trying to resolve dummy id");
+ self.record_def(id, PathResolution::new(def));
+ }
+ }
} else if def == Def::ToolMod && i + 1 != path.len() {
let def = Def::NonMacroAttr(NonMacroAttrKind::Tool);
return PathResult::NonModule(PathResolution::new(def));
@@ -3612,7 +3646,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
} else if i == 0 {
format!("Use of undeclared type or module `{}`", ident)
} else {
- format!("Could not find `{}` in `{}`", ident, path[i - 1])
+ format!("Could not find `{}` in `{}`", ident, path[i - 1].0)
};
return PathResult::Failed(ident.span, msg, is_last);
}
@@ -3630,7 +3664,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
fn lint_if_path_starts_with_module(
&self,
crate_lint: CrateLint,
- path: &[Ident],
+ path: &[(Ident, Option)],
path_span: Span,
second_binding: Option<&NameBinding>,
) {
@@ -3653,7 +3687,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
};
let first_name = match path.get(0) {
- Some(ident) => ident.name,
+ Some(ident) => ident.0.name,
None => return,
};
@@ -3665,7 +3699,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
match path.get(1) {
// If this import looks like `crate::...` it's already good
- Some(ident) if ident.name == keywords::Crate.name() => return,
+ Some((ident, _)) if ident.name == keywords::Crate.name() => return,
// Otherwise go below to see if it's an extern crate
Some(_) => {}
// If the path has length one (and it's `CrateRoot` most likely)
@@ -3858,7 +3892,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
}
fn lookup_typo_candidate(&mut self,
- path: &[Ident],
+ path: &[(Ident, Option)],
ns: Namespace,
filter_fn: FilterFn,
span: Span)
@@ -3922,7 +3956,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
}
}
- let name = path[path.len() - 1].name;
+ let name = path[path.len() - 1].0.name;
// Make sure error reporting is deterministic.
names.sort_by_cached_key(|name| name.as_str());
match find_best_match_for_name(names.iter(), &name.as_str(), None) {
@@ -4443,7 +4477,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
ast::VisibilityKind::Restricted { ref path, id, .. } => {
// Visibilities are resolved as global by default, add starting root segment.
let segments = path.make_root().iter().chain(path.segments.iter())
- .map(|seg| seg.ident)
+ .map(|seg| (seg.ident, Some(seg.id)))
.collect::>();
let def = self.smart_resolve_path_fragment(
id,
@@ -4681,12 +4715,12 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
}
}
-fn is_self_type(path: &[Ident], namespace: Namespace) -> bool {
- namespace == TypeNS && path.len() == 1 && path[0].name == keywords::SelfType.name()
+fn is_self_type(path: &[(Ident, Option)], namespace: Namespace) -> bool {
+ namespace == TypeNS && path.len() == 1 && path[0].0.name == keywords::SelfType.name()
}
-fn is_self_value(path: &[Ident], namespace: Namespace) -> bool {
- namespace == ValueNS && path.len() == 1 && path[0].name == keywords::SelfValue.name()
+fn is_self_value(path: &[(Ident, Option)], namespace: Namespace) -> bool {
+ namespace == ValueNS && path.len() == 1 && path[0].0.name == keywords::SelfValue.name()
}
fn names_to_string(idents: &[Ident]) -> String {
@@ -4702,6 +4736,12 @@ fn names_to_string(idents: &[Ident]) -> String {
result
}
+fn names_and_ids_to_string(segments: &[(Ident, Option)]) -> String {
+ names_to_string(&segments.iter()
+ .map(|seg| seg.0)
+ .collect::>())
+}
+
fn path_names_to_string(path: &Path) -> String {
names_to_string(&path.segments.iter()
.map(|seg| seg.ident)
diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index 879b4ea3fe579..6c230a477eff8 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -423,16 +423,16 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
derives_in_scope: &[ast::Path], force: bool)
-> Result {
let ast::Path { ref segments, span } = *path;
- let mut path: Vec<_> = segments.iter().map(|seg| seg.ident).collect();
+ let mut path: Vec<_> = segments.iter().map(|seg| (seg.ident, Some(seg.id))).collect();
let invocation = self.invocations[&scope];
let module = invocation.module.get();
self.current_module = if module.is_trait() { module.parent.unwrap() } else { module };
// Possibly apply the macro helper hack
if kind == MacroKind::Bang && path.len() == 1 &&
- path[0].span.ctxt().outer().expn_info().map_or(false, |info| info.local_inner_macros) {
- let root = Ident::new(keywords::DollarCrate.name(), path[0].span);
- path.insert(0, root);
+ path[0].0.span.ctxt().outer().expn_info().map_or(false, |info| info.local_inner_macros) {
+ let root = Ident::new(keywords::DollarCrate.name(), path[0].0.span);
+ path.insert(0, (root, None));
}
if path.len() > 1 {
@@ -457,16 +457,24 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
Err(Determinacy::Determined)
},
};
- self.current_module.nearest_item_scope().macro_resolutions.borrow_mut()
- .push((path.into_boxed_slice(), span));
+ self.current_module
+ .nearest_item_scope()
+ .macro_resolutions
+ .borrow_mut()
+ .push((path
+ .iter()
+ .map(|(ident, _)| *ident)
+ .collect::>()
+ .into_boxed_slice(), span));
return def;
}
- let legacy_resolution = self.resolve_legacy_scope(&invocation.legacy_scope, path[0], false);
+ let legacy_resolution =
+ self.resolve_legacy_scope(&invocation.legacy_scope, path[0].0, false);
let result = if let Some((legacy_binding, _)) = legacy_resolution {
Ok(legacy_binding.def())
} else {
- match self.resolve_lexical_macro_path_segment(path[0], MacroNS, false, force,
+ match self.resolve_lexical_macro_path_segment(path[0].0, MacroNS, false, force,
kind == MacroKind::Attr, span) {
Ok((binding, _)) => Ok(binding.def_ignoring_ambiguity()),
Err(Determinacy::Undetermined) => return Err(Determinacy::Undetermined),
@@ -478,7 +486,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
};
self.current_module.nearest_item_scope().legacy_macro_resolutions.borrow_mut()
- .push((scope, path[0], kind, result.ok()));
+ .push((scope, path[0].0, kind, result.ok()));
if let Ok(Def::NonMacroAttr(NonMacroAttrKind::Custom)) = result {} else {
return result;
@@ -499,7 +507,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
for derive in derives_in_scope {
match self.resolve_macro_path(derive, MacroKind::Derive, scope, &[], force) {
Ok(ext) => if let SyntaxExtension::ProcMacroDerive(_, ref inert_attrs, _) = *ext {
- if inert_attrs.contains(&path[0].name) {
+ if inert_attrs.contains(&path[0].0.name) {
convert_to_derive_helper = ConvertToDeriveHelper::Yes;
break
}
@@ -811,6 +819,10 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
pub fn finalize_current_module_macro_resolutions(&mut self) {
let module = self.current_module;
for &(ref path, span) in module.macro_resolutions.borrow().iter() {
+ let path = path
+ .iter()
+ .map(|ident| (*ident, None))
+ .collect::)>>();
match self.resolve_path(None, &path, Some(MacroNS), true, span, CrateLint::No) {
PathResult::NonModule(_) => {},
PathResult::Failed(span, msg, _) => {
@@ -919,7 +931,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
}
};
let ident = Ident::new(Symbol::intern(name), span);
- self.lookup_typo_candidate(&[ident], MacroNS, is_macro, span)
+ self.lookup_typo_candidate(&[(ident, None)], MacroNS, is_macro, span)
});
if let Some(suggestion) = suggestion {
diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs
index c60f9293d58e7..f6aeffebf951f 100644
--- a/src/librustc_resolve/resolve_imports.rs
+++ b/src/librustc_resolve/resolve_imports.rs
@@ -14,7 +14,7 @@ use {AmbiguityError, CrateLint, Module, ModuleOrUniformRoot, PerNS};
use Namespace::{self, TypeNS, MacroNS};
use {NameBinding, NameBindingKind, ToNameBinding, PathResult, PrivacyError};
use Resolver;
-use {names_to_string, module_to_string};
+use {names_to_string, names_and_ids_to_string, module_to_string};
use {resolve_error, ResolutionError};
use rustc_data_structures::ptr_key::PtrKey;
@@ -86,7 +86,7 @@ pub struct ImportDirective<'a> {
pub root_span: Span,
pub parent: Module<'a>,
- pub module_path: Vec,
+ pub module_path: Vec<(Ident, Option)>,
/// The resolution of `module_path`.
pub imported_module: Cell