提交 59de7f8f 编写于 作者: J Jeffrey Seyfried

Add `ident.unhygienize()` and use `Ident` more instead of `Name` in `resolve`.

上级 83ab9f7f
......@@ -28,7 +28,7 @@
use std::cell::Cell;
use std::rc::Rc;
use syntax::ast::Name;
use syntax::ast::{Name, Ident};
use syntax::attr;
use syntax::ast::{self, Block, ForeignItem, ForeignItemKind, Item, ItemKind};
......@@ -76,12 +76,12 @@ struct LegacyMacroImports {
impl<'b> Resolver<'b> {
/// Defines `name` in namespace `ns` of module `parent` to be `def` if it is not yet defined;
/// otherwise, reports an error.
fn define<T>(&mut self, parent: Module<'b>, name: Name, ns: Namespace, def: T)
fn define<T>(&mut self, parent: Module<'b>, ident: Ident, ns: Namespace, def: T)
where T: ToNameBinding<'b>,
{
let binding = def.to_name_binding();
if let Err(old_binding) = self.try_define(parent, name, ns, binding.clone()) {
self.report_conflict(parent, name, ns, old_binding, &binding);
if let Err(old_binding) = self.try_define(parent, ident, ns, binding.clone()) {
self.report_conflict(parent, ident, ns, old_binding, &binding);
}
}
......@@ -102,7 +102,7 @@ fn insert_field_names(&mut self, def_id: DefId, field_names: Vec<Name>) {
/// Constructs the reduced graph for one item.
fn build_reduced_graph_for_item(&mut self, item: &Item, expansion: Mark) {
let parent = self.current_module;
let name = item.ident.name;
let ident = item.ident;
let sp = item.span;
let vis = self.resolve_visibility(&item.vis);
......@@ -157,8 +157,8 @@ fn build_reduced_graph_for_item(&mut self, item: &Item, expansion: Mark) {
}
let subclass = SingleImport {
target: binding.name,
source: source.name,
target: binding,
source: source,
result: self.per_ns(|_, _| Cell::new(Err(Undetermined))),
};
self.add_import_directive(
......@@ -187,13 +187,13 @@ fn build_reduced_graph_for_item(&mut self, item: &Item, expansion: Mark) {
for source_item in source_items {
let node = source_item.node;
let (module_path, name, rename) = {
let (module_path, ident, rename) = {
if node.name.name != keywords::SelfValue.name() {
let rename = node.rename.unwrap_or(node.name).name;
(module_path.clone(), node.name.name, rename)
let rename = node.rename.unwrap_or(node.name);
(module_path.clone(), node.name, rename)
} else {
let name = match module_path.last() {
Some(ident) => ident.name,
let ident = match module_path.last() {
Some(&ident) => ident,
None => {
resolve_error(
self,
......@@ -205,13 +205,13 @@ fn build_reduced_graph_for_item(&mut self, item: &Item, expansion: Mark) {
}
};
let module_path = module_path.split_last().unwrap().1;
let rename = node.rename.map(|i| i.name).unwrap_or(name);
(module_path.to_vec(), name, rename)
let rename = node.rename.unwrap_or(ident);
(module_path.to_vec(), ident, rename)
}
};
let subclass = SingleImport {
target: rename,
source: name,
source: ident,
result: self.per_ns(|_, _| Cell::new(Err(Undetermined))),
};
let id = source_item.node.id;
......@@ -251,7 +251,7 @@ fn build_reduced_graph_for_item(&mut self, item: &Item, expansion: Mark) {
expansion: expansion,
});
let imported_binding = self.import(binding, directive);
self.define(parent, name, TypeNS, imported_binding);
self.define(parent, ident, TypeNS, imported_binding);
self.populate_module_if_necessary(module);
self.process_legacy_macro_imports(item, module, expansion);
}
......@@ -265,9 +265,9 @@ fn build_reduced_graph_for_item(&mut self, item: &Item, expansion: Mark) {
attr::contains_name(&item.attrs, "no_implicit_prelude")
},
normal_ancestor_id: Some(item.id),
..ModuleS::new(Some(parent), ModuleKind::Def(def, name))
..ModuleS::new(Some(parent), ModuleKind::Def(def, ident.name))
});
self.define(parent, name, TypeNS, (module, vis, sp, expansion));
self.define(parent, ident, TypeNS, (module, vis, sp, expansion));
self.module_map.insert(item.id, module);
// Descend into the module.
......@@ -280,27 +280,27 @@ fn build_reduced_graph_for_item(&mut self, item: &Item, expansion: Mark) {
ItemKind::Static(_, m, _) => {
let mutbl = m == Mutability::Mutable;
let def = Def::Static(self.definitions.local_def_id(item.id), mutbl);
self.define(parent, name, ValueNS, (def, vis, sp, expansion));
self.define(parent, ident, ValueNS, (def, vis, sp, expansion));
}
ItemKind::Const(..) => {
let def = Def::Const(self.definitions.local_def_id(item.id));
self.define(parent, name, ValueNS, (def, vis, sp, expansion));
self.define(parent, ident, ValueNS, (def, vis, sp, expansion));
}
ItemKind::Fn(..) => {
let def = Def::Fn(self.definitions.local_def_id(item.id));
self.define(parent, name, ValueNS, (def, vis, sp, expansion));
self.define(parent, ident, ValueNS, (def, vis, sp, expansion));
}
// These items live in the type namespace.
ItemKind::Ty(..) => {
let def = Def::TyAlias(self.definitions.local_def_id(item.id));
self.define(parent, name, TypeNS, (def, vis, sp, expansion));
self.define(parent, ident, TypeNS, (def, vis, sp, expansion));
}
ItemKind::Enum(ref enum_definition, _) => {
let def = Def::Enum(self.definitions.local_def_id(item.id));
let module = self.new_module(parent, ModuleKind::Def(def, name), true);
self.define(parent, name, TypeNS, (module, vis, sp, expansion));
let module = self.new_module(parent, ModuleKind::Def(def, ident.name), true);
self.define(parent, ident, TypeNS, (module, vis, sp, expansion));
for variant in &(*enum_definition).variants {
self.build_reduced_graph_for_variant(variant, module, vis, expansion);
......@@ -311,14 +311,14 @@ fn build_reduced_graph_for_item(&mut self, item: &Item, expansion: Mark) {
ItemKind::Struct(ref struct_def, _) => {
// Define a name in the type namespace.
let def = Def::Struct(self.definitions.local_def_id(item.id));
self.define(parent, name, TypeNS, (def, vis, sp, expansion));
self.define(parent, ident, TypeNS, (def, vis, sp, expansion));
// If this is a tuple or unit struct, define a name
// in the value namespace as well.
if !struct_def.is_struct() {
let ctor_def = Def::StructCtor(self.definitions.local_def_id(struct_def.id()),
CtorKind::from_ast(struct_def));
self.define(parent, name, ValueNS, (ctor_def, vis, sp, expansion));
self.define(parent, ident, ValueNS, (ctor_def, vis, sp, expansion));
}
// Record field names for error reporting.
......@@ -332,7 +332,7 @@ fn build_reduced_graph_for_item(&mut self, item: &Item, expansion: Mark) {
ItemKind::Union(ref vdata, _) => {
let def = Def::Union(self.definitions.local_def_id(item.id));
self.define(parent, name, TypeNS, (def, vis, sp, expansion));
self.define(parent, ident, TypeNS, (def, vis, sp, expansion));
// Record field names for error reporting.
let field_names = vdata.fields().iter().filter_map(|field| {
......@@ -350,8 +350,8 @@ fn build_reduced_graph_for_item(&mut self, item: &Item, expansion: Mark) {
// Add all the items within to a new module.
let module =
self.new_module(parent, ModuleKind::Def(Def::Trait(def_id), name), true);
self.define(parent, name, TypeNS, (module, vis, sp, expansion));
self.new_module(parent, ModuleKind::Def(Def::Trait(def_id), ident.name), true);
self.define(parent, ident, TypeNS, (module, vis, sp, expansion));
self.current_module = module;
}
ItemKind::Mac(_) => panic!("unexpanded macro in resolve!"),
......@@ -365,26 +365,23 @@ fn build_reduced_graph_for_variant(&mut self,
parent: Module<'b>,
vis: ty::Visibility,
expansion: Mark) {
let name = variant.node.name.name;
let ident = variant.node.name;
let def_id = self.definitions.local_def_id(variant.node.data.id());
// Define a name in the type namespace.
let def = Def::Variant(def_id);
self.define(parent, name, TypeNS, (def, vis, variant.span, expansion));
self.define(parent, ident, TypeNS, (def, vis, variant.span, expansion));
// Define a constructor name in the value namespace.
// Braced variants, unlike structs, generate unusable names in
// value namespace, they are reserved for possible future use.
let ctor_kind = CtorKind::from_ast(&variant.node.data);
let ctor_def = Def::VariantCtor(def_id, ctor_kind);
self.define(parent, name, ValueNS, (ctor_def, vis, variant.span, expansion));
self.define(parent, ident, ValueNS, (ctor_def, vis, variant.span, expansion));
}
/// Constructs the reduced graph for one foreign item.
fn build_reduced_graph_for_foreign_item(&mut self, item: &ForeignItem, expansion: Mark) {
let parent = self.current_module;
let name = item.ident.name;
let def = match item.node {
ForeignItemKind::Fn(..) => {
Def::Fn(self.definitions.local_def_id(item.id))
......@@ -393,8 +390,9 @@ fn build_reduced_graph_for_foreign_item(&mut self, item: &ForeignItem, expansion
Def::Static(self.definitions.local_def_id(item.id), m)
}
};
let parent = self.current_module;
let vis = self.resolve_visibility(&item.vis);
self.define(parent, name, ValueNS, (def, vis, item.span, expansion));
self.define(parent, item.ident, ValueNS, (def, vis, item.span, expansion));
}
fn build_reduced_graph_for_block(&mut self, block: &Block) {
......@@ -414,7 +412,7 @@ fn build_reduced_graph_for_block(&mut self, block: &Block) {
/// Builds the reduced graph for a single item in an external crate.
fn build_reduced_graph_for_external_crate_def(&mut self, parent: Module<'b>, child: Export) {
let name = child.name;
let ident = Ident::with_empty_ctxt(child.name);
let def = child.def;
let def_id = def.def_id();
let vis = match def {
......@@ -425,25 +423,25 @@ fn build_reduced_graph_for_external_crate_def(&mut self, parent: Module<'b>, chi
match def {
Def::Mod(..) | Def::Enum(..) => {
let module = self.new_module(parent, ModuleKind::Def(def, name), false);
self.define(parent, name, TypeNS, (module, vis, DUMMY_SP, Mark::root()));
let module = self.new_module(parent, ModuleKind::Def(def, ident.name), false);
self.define(parent, ident, TypeNS, (module, vis, DUMMY_SP, Mark::root()));
}
Def::Variant(..) => {
self.define(parent, name, TypeNS, (def, vis, DUMMY_SP, Mark::root()));
self.define(parent, ident, TypeNS, (def, vis, DUMMY_SP, Mark::root()));
}
Def::VariantCtor(..) => {
self.define(parent, name, ValueNS, (def, vis, DUMMY_SP, Mark::root()));
self.define(parent, ident, ValueNS, (def, vis, DUMMY_SP, Mark::root()));
}
Def::Fn(..) |
Def::Static(..) |
Def::Const(..) |
Def::AssociatedConst(..) |
Def::Method(..) => {
self.define(parent, name, ValueNS, (def, vis, DUMMY_SP, Mark::root()));
self.define(parent, ident, ValueNS, (def, vis, DUMMY_SP, Mark::root()));
}
Def::Trait(..) => {
let module = self.new_module(parent, ModuleKind::Def(def, name), false);
self.define(parent, name, TypeNS, (module, vis, DUMMY_SP, Mark::root()));
let module = self.new_module(parent, ModuleKind::Def(def, ident.name), false);
self.define(parent, ident, TypeNS, (module, vis, DUMMY_SP, Mark::root()));
// If this is a trait, add all the trait item names to the trait info.
let trait_item_def_ids = self.session.cstore.associated_item_def_ids(def_id);
......@@ -455,27 +453,27 @@ fn build_reduced_graph_for_external_crate_def(&mut self, parent: Module<'b>, chi
}
}
Def::TyAlias(..) | Def::AssociatedTy(..) => {
self.define(parent, name, TypeNS, (def, vis, DUMMY_SP, Mark::root()));
self.define(parent, ident, TypeNS, (def, vis, DUMMY_SP, Mark::root()));
}
Def::Struct(..) => {
self.define(parent, name, TypeNS, (def, vis, DUMMY_SP, Mark::root()));
self.define(parent, ident, TypeNS, (def, vis, DUMMY_SP, Mark::root()));
// Record field names for error reporting.
let field_names = self.session.cstore.struct_field_names(def_id);
self.insert_field_names(def_id, field_names);
}
Def::StructCtor(..) => {
self.define(parent, name, ValueNS, (def, vis, DUMMY_SP, Mark::root()));
self.define(parent, ident, ValueNS, (def, vis, DUMMY_SP, Mark::root()));
}
Def::Union(..) => {
self.define(parent, name, TypeNS, (def, vis, DUMMY_SP, Mark::root()));
self.define(parent, ident, TypeNS, (def, vis, DUMMY_SP, Mark::root()));
// Record field names for error reporting.
let field_names = self.session.cstore.struct_field_names(def_id);
self.insert_field_names(def_id, field_names);
}
Def::Macro(..) => {
self.define(parent, name, MacroNS, (def, vis, DUMMY_SP, Mark::root()));
self.define(parent, ident, MacroNS, (def, vis, DUMMY_SP, Mark::root()));
}
Def::Local(..) |
Def::PrimTy(..) |
......@@ -574,12 +572,13 @@ fn process_legacy_macro_imports(&mut self, item: &Item, module: Module<'b>, expa
}
if let Some(span) = legacy_imports.import_all {
module.for_each_child(|name, ns, binding| if ns == MacroNS {
self.legacy_import_macro(name, binding, span, allow_shadowing);
module.for_each_child(|ident, ns, binding| if ns == MacroNS {
self.legacy_import_macro(ident.name, binding, span, allow_shadowing);
});
} else {
for (name, span) in legacy_imports.imports {
let result = self.resolve_name_in_module(module, name, MacroNS, false, None);
let ident = Ident::with_empty_ctxt(name);
let result = self.resolve_ident_in_module(module, ident, MacroNS, false, None);
if let Ok(binding) = result {
self.legacy_import_macro(name, binding, span, allow_shadowing);
} else {
......@@ -591,7 +590,8 @@ fn process_legacy_macro_imports(&mut self, item: &Item, module: Module<'b>, expa
let krate = module.def_id().unwrap().krate;
self.used_crates.insert(krate);
self.session.cstore.export_macros(krate);
let result = self.resolve_name_in_module(module, name, MacroNS, false, None);
let ident = Ident::with_empty_ctxt(name);
let result = self.resolve_ident_in_module(module, ident, MacroNS, false, None);
if let Ok(binding) = result {
self.macro_exports.push(Export { name: name, def: binding.def() });
} else {
......@@ -759,7 +759,7 @@ fn visit_trait_item(&mut self, item: &'a TraitItem) {
self.resolver.trait_item_map.insert((item.ident.name, def_id), is_static_method);
let vis = ty::Visibility::Public;
self.resolver.define(parent, item.ident.name, ns, (def, vis, item.span, self.expansion));
self.resolver.define(parent, item.ident, ns, (def, vis, item.span, self.expansion));
self.resolver.current_module = parent.parent.unwrap(); // nearest normal ancestor
visit::walk_trait_item(self, item);
......
......@@ -781,8 +781,8 @@ pub struct ModuleS<'a> {
// The node id of the closest normal module (`mod`) ancestor (including this module).
normal_ancestor_id: Option<NodeId>,
resolutions: RefCell<FxHashMap<(Name, Namespace), &'a RefCell<NameResolution<'a>>>>,
legacy_macro_resolutions: RefCell<Vec<(Mark, Name, Span)>>,
resolutions: RefCell<FxHashMap<(Ident, Namespace), &'a RefCell<NameResolution<'a>>>>,
legacy_macro_resolutions: RefCell<Vec<(Mark, Ident, Span)>>,
macro_resolutions: RefCell<Vec<(Box<[Ident]>, PathScope, Span)>>,
// Macro invocations that can expand into items in this module.
......@@ -794,7 +794,7 @@ pub struct ModuleS<'a> {
globs: RefCell<Vec<&'a ImportDirective<'a>>>,
// Used to memoize the traits in this module for faster searches through all traits in scope.
traits: RefCell<Option<Box<[(Name, &'a NameBinding<'a>)]>>>,
traits: RefCell<Option<Box<[(Ident, &'a NameBinding<'a>)]>>>,
// Whether this module is populated. If not populated, any attempt to
// access the children must be preceded with a
......@@ -822,9 +822,9 @@ fn new(parent: Option<Module<'a>>, kind: ModuleKind) -> Self {
}
}
fn for_each_child<F: FnMut(Name, Namespace, &'a NameBinding<'a>)>(&self, mut f: F) {
for (&(name, ns), name_resolution) in self.resolutions.borrow().iter() {
name_resolution.borrow().binding.map(|binding| f(name, ns, binding));
fn for_each_child<F: FnMut(Ident, Namespace, &'a NameBinding<'a>)>(&self, mut f: F) {
for (&(ident, ns), name_resolution) in self.resolutions.borrow().iter() {
name_resolution.borrow().binding.map(|binding| f(ident, ns, binding));
}
}
......@@ -1334,7 +1334,7 @@ fn new_module(&self, parent: Module<'a>, kind: ModuleKind, local: bool) -> Modul
})
}
fn record_use(&mut self, name: Name, ns: Namespace, binding: &'a NameBinding<'a>, span: Span)
fn record_use(&mut self, ident: Ident, ns: Namespace, binding: &'a NameBinding<'a>, span: Span)
-> bool /* true if an error was reported */ {
// track extern crates for unused_extern_crate lint
if let Some(DefId { krate, .. }) = binding.module().and_then(ModuleS::def_id) {
......@@ -1345,13 +1345,13 @@ fn record_use(&mut self, name: Name, ns: Namespace, binding: &'a NameBinding<'a>
NameBindingKind::Import { directive, binding, ref used } if !used.get() => {
used.set(true);
self.used_imports.insert((directive.id, ns));
self.add_to_glob_map(directive.id, name);
self.record_use(name, ns, binding, span)
self.add_to_glob_map(directive.id, ident);
self.record_use(ident, ns, binding, span)
}
NameBindingKind::Import { .. } => false,
NameBindingKind::Ambiguity { b1, b2 } => {
self.ambiguity_errors.push(AmbiguityError {
span: span, name: name, lexical: false, b1: b1, b2: b2,
span: span, name: ident.name, lexical: false, b1: b1, b2: b2,
});
true
}
......@@ -1359,9 +1359,9 @@ fn record_use(&mut self, name: Name, ns: Namespace, binding: &'a NameBinding<'a>
}
}
fn add_to_glob_map(&mut self, id: NodeId, name: Name) {
fn add_to_glob_map(&mut self, id: NodeId, ident: Ident) {
if self.make_glob_map {
self.glob_map.entry(id).or_insert_with(FxHashSet).insert(name);
self.glob_map.entry(id).or_insert_with(FxHashSet).insert(ident.name);
}
}
......@@ -1388,7 +1388,7 @@ fn resolve_ident_in_lexical_scope(&mut self,
record_used: Option<Span>)
-> Option<LexicalScopeBinding<'a>> {
if ns == TypeNS {
ident = Ident::with_empty_ctxt(ident.name);
ident = ident.unhygienize();
}
// Walk backwards up the ribs in scope.
......@@ -1403,8 +1403,7 @@ fn resolve_ident_in_lexical_scope(&mut self,
}
if let ModuleRibKind(module) = self.ribs[ns][i].kind {
let name = ident.name;
let item = self.resolve_name_in_module(module, name, ns, false, record_used);
let item = self.resolve_ident_in_module(module, ident, ns, false, record_used);
if let Ok(binding) = item {
// The ident resolves to an item.
return Some(LexicalScopeBinding::Item(binding));
......@@ -1413,7 +1412,7 @@ fn resolve_ident_in_lexical_scope(&mut self,
if let ModuleKind::Block(..) = module.kind { // We can see through blocks
} else if !module.no_implicit_prelude {
return self.prelude.and_then(|prelude| {
self.resolve_name_in_module(prelude, name, ns, false, None).ok()
self.resolve_ident_in_module(prelude, ident, ns, false, None).ok()
}).map(LexicalScopeBinding::Item)
} else {
return None;
......@@ -2183,8 +2182,7 @@ fn resolve_pattern(&mut self,
Def::VariantCtor(_, CtorKind::Const) |
Def::Const(..) if !always_binding => {
// A unit struct/variant or constant pattern.
let name = ident.node.name;
self.record_use(name, ValueNS, binding.unwrap(), ident.span);
self.record_use(ident.node, ValueNS, binding.unwrap(), ident.span);
Some(PathResolution::new(def))
}
Def::StructCtor(..) | Def::VariantCtor(..) |
......@@ -2363,9 +2361,9 @@ fn resolve_path(&mut self,
allow_super = false;
let binding = if let Some(module) = module {
self.resolve_name_in_module(module, ident.name, ns, false, record_used)
self.resolve_ident_in_module(module, ident, ns, false, record_used)
} else if opt_ns == Some(MacroNS) {
self.resolve_lexical_macro_path_segment(ident.name, ns, record_used)
self.resolve_lexical_macro_path_segment(ident, ns, record_used)
} else {
match self.resolve_ident_in_lexical_scope(ident, ns, record_used) {
Some(LexicalScopeBinding::Item(binding)) => Ok(binding),
......@@ -2953,16 +2951,15 @@ fn lookup_candidates<FilterFn>(&mut self,
in_module_is_extern)) = worklist.pop() {
self.populate_module_if_necessary(in_module);
in_module.for_each_child(|name, ns, name_binding| {
in_module.for_each_child(|ident, ns, name_binding| {
// avoid imports entirely
if name_binding.is_import() && !name_binding.is_extern_crate() { return; }
// collect results based on the filter function
if name == lookup_name && ns == namespace {
if ident.name == lookup_name && ns == namespace {
if filter_fn(name_binding.def()) {
// create the path
let ident = Ident::with_empty_ctxt(name);
let params = PathParameters::none();
let segment = PathSegment {
identifier: ident,
......@@ -2994,7 +2991,7 @@ fn lookup_candidates<FilterFn>(&mut self,
// form the path
let mut path_segments = path_segments.clone();
path_segments.push(PathSegment {
identifier: Ident::with_empty_ctxt(name),
identifier: ident,
parameters: PathParameters::none(),
});
......@@ -3124,13 +3121,13 @@ fn report_shadowing_errors(&mut self) {
fn report_conflict(&mut self,
parent: Module,
name: Name,
ident: Ident,
ns: Namespace,
binding: &NameBinding,
old_binding: &NameBinding) {
// Error on the second of two conflicting names
if old_binding.span.lo > binding.span.lo {
return self.report_conflict(parent, name, ns, old_binding, binding);
return self.report_conflict(parent, ident, ns, old_binding, binding);
}
let container = match parent.kind {
......@@ -3145,7 +3142,7 @@ fn report_conflict(&mut self,
false => ("defined", "definition"),
};
let span = binding.span;
let (name, span) = (ident.name, binding.span);
if let Some(s) = self.name_already_seen.get(&name) {
if s == &span {
......
......@@ -19,7 +19,7 @@
use rustc::ty;
use std::cell::Cell;
use std::rc::Rc;
use syntax::ast::{self, Name};
use syntax::ast::{self, Name, Ident};
use syntax::errors::DiagnosticBuilder;
use syntax::ext::base::{self, Determinacy, MultiModifier, MultiDecorator};
use syntax::ext::base::{NormalTT, SyntaxExtension};
......@@ -246,7 +246,7 @@ fn resolve_macro(&mut self, scope: Mark, path: &ast::Path, force: bool)
let result = match self.resolve_legacy_scope(&invocation.legacy_scope, name, false) {
Some(MacroBinding::Legacy(binding)) => Ok(binding.ext.clone()),
Some(MacroBinding::Modern(binding)) => Ok(binding.get_macro(self)),
None => match self.resolve_lexical_macro_path_segment(name, MacroNS, None) {
None => match self.resolve_lexical_macro_path_segment(path[0], MacroNS, None) {
Ok(binding) => Ok(binding.get_macro(self)),
Err(Determinacy::Undetermined) if !force => return Err(Determinacy::Undetermined),
_ => {
......@@ -260,7 +260,7 @@ fn resolve_macro(&mut self, scope: Mark, path: &ast::Path, force: bool)
};
if self.use_extern_macros {
self.current_module.legacy_macro_resolutions.borrow_mut().push((scope, name, span));
self.current_module.legacy_macro_resolutions.borrow_mut().push((scope, path[0], span));
}
result
}
......@@ -269,7 +269,7 @@ fn resolve_macro(&mut self, scope: Mark, path: &ast::Path, force: bool)
impl<'a> Resolver<'a> {
// Resolve the initial segment of a non-global macro path (e.g. `foo` in `foo::bar!();`)
pub fn resolve_lexical_macro_path_segment(&mut self,
name: Name,
ident: Ident,
ns: Namespace,
record_used: Option<Span>)
-> Result<&'a NameBinding<'a>, Determinacy> {
......@@ -278,7 +278,7 @@ pub fn resolve_lexical_macro_path_segment(&mut self,
loop {
// Since expanded macros may not shadow the lexical scope (enforced below),
// we can ignore unresolved invocations (indicated by the penultimate argument).
match self.resolve_name_in_module(module, name, ns, true, record_used) {
match self.resolve_ident_in_module(module, ident, ns, true, record_used) {
Ok(binding) => {
let span = match record_used {
Some(span) => span,
......@@ -286,6 +286,7 @@ pub fn resolve_lexical_macro_path_segment(&mut self,
};
match potential_expanded_shadower {
Some(shadower) if shadower.def() != binding.def() => {
let name = ident.name;
self.ambiguity_errors.push(AmbiguityError {
span: span, name: name, b1: shadower, b2: binding, lexical: true,
});
......@@ -383,10 +384,10 @@ pub fn finalize_current_module_macro_resolutions(&mut self) {
}
}
for &(mark, name, span) in module.legacy_macro_resolutions.borrow().iter() {
for &(mark, ident, span) in module.legacy_macro_resolutions.borrow().iter() {
let legacy_scope = &self.invocations[&mark].legacy_scope;
let legacy_resolution = self.resolve_legacy_scope(legacy_scope, name, true);
let resolution = self.resolve_lexical_macro_path_segment(name, MacroNS, Some(span));
let legacy_resolution = self.resolve_legacy_scope(legacy_scope, ident.name, true);
let resolution = self.resolve_lexical_macro_path_segment(ident, MacroNS, Some(span));
let (legacy_resolution, resolution) = match (legacy_resolution, resolution) {
(Some(legacy_resolution), Ok(resolution)) => (legacy_resolution, resolution),
_ => continue,
......@@ -396,9 +397,9 @@ pub fn finalize_current_module_macro_resolutions(&mut self) {
MacroBinding::Modern(binding) => (binding.span, "imported"),
MacroBinding::Legacy(binding) => (binding.span, "defined"),
};
let msg1 = format!("`{}` could resolve to the macro {} here", name, participle);
let msg2 = format!("`{}` could also resolve to the macro imported here", name);
self.session.struct_span_err(span, &format!("`{}` is ambiguous", name))
let msg1 = format!("`{}` could resolve to the macro {} here", ident, participle);
let msg2 = format!("`{}` could also resolve to the macro imported here", ident);
self.session.struct_span_err(span, &format!("`{}` is ambiguous", ident))
.span_note(legacy_span, &msg1)
.span_note(resolution.span, &msg2)
.emit();
......
......@@ -21,7 +21,7 @@
use rustc::lint::builtin::PRIVATE_IN_PUBLIC;
use rustc::hir::def::*;
use syntax::ast::{Ident, NodeId, Name};
use syntax::ast::{Ident, NodeId};
use syntax::ext::base::Determinacy::{self, Determined, Undetermined};
use syntax::ext::hygiene::Mark;
use syntax::symbol::keywords;
......@@ -35,8 +35,8 @@
#[derive(Clone, Debug)]
pub enum ImportDirectiveSubclass<'a> {
SingleImport {
target: Name,
source: Name,
target: Ident,
source: Ident,
result: PerNS<Cell<Result<&'a NameBinding<'a>, Determinacy>>>,
},
GlobImport {
......@@ -126,31 +126,32 @@ fn binding(&self) -> Option<&'a NameBinding<'a>> {
}
impl<'a> Resolver<'a> {
fn resolution(&self, module: Module<'a>, name: Name, ns: Namespace)
fn resolution(&self, module: Module<'a>, ident: Ident, ns: Namespace)
-> &'a RefCell<NameResolution<'a>> {
*module.resolutions.borrow_mut().entry((name, ns))
*module.resolutions.borrow_mut().entry((ident, ns))
.or_insert_with(|| self.arenas.alloc_name_resolution())
}
/// Attempts to resolve the supplied name in the given module for the given namespace.
/// If successful, returns the binding corresponding to the name.
/// Attempts to resolve `ident` in namespaces `ns` of `module`.
/// Invariant: if `record_used` is `Some`, import resolution must be complete.
pub fn resolve_name_in_module(&mut self,
module: Module<'a>,
name: Name,
ns: Namespace,
ignore_unresolved_invocations: bool,
record_used: Option<Span>)
-> Result<&'a NameBinding<'a>, Determinacy> {
pub fn resolve_ident_in_module(&mut self,
module: Module<'a>,
ident: Ident,
ns: Namespace,
ignore_unresolved_invocations: bool,
record_used: Option<Span>)
-> Result<&'a NameBinding<'a>, Determinacy> {
let ident = ident.unhygienize();
self.populate_module_if_necessary(module);
let resolution = self.resolution(module, name, ns)
let resolution = self.resolution(module, ident, ns)
.try_borrow_mut()
.map_err(|_| Determined)?; // This happens when there is a cycle of imports
if let Some(span) = record_used {
if let Some(binding) = resolution.binding {
if let Some(shadowed_glob) = resolution.shadows_glob {
let name = ident.name;
// If we ignore unresolved invocations, we must forbid
// expanded shadowing to avoid time travel.
if ignore_unresolved_invocations &&
......@@ -162,11 +163,11 @@ pub fn resolve_name_in_module(&mut self,
});
}
}
if self.record_use(name, ns, binding, span) {
if self.record_use(ident, ns, binding, span) {
return Ok(self.dummy_binding);
}
if !self.is_accessible(binding.vis) {
self.privacy_errors.push(PrivacyError(span, name, binding));
self.privacy_errors.push(PrivacyError(span, ident.name, binding));
}
}
......@@ -194,11 +195,11 @@ pub fn resolve_name_in_module(&mut self,
Some(module) => module,
None => return Err(Undetermined),
};
let name = match directive.subclass {
let ident = match directive.subclass {
SingleImport { source, .. } => source,
_ => unreachable!(),
};
match self.resolve_name_in_module(module, name, ns, false, None) {
match self.resolve_ident_in_module(module, ident, ns, false, None) {
Err(Determined) => {}
_ => return Err(Undetermined),
}
......@@ -220,7 +221,7 @@ pub fn resolve_name_in_module(&mut self,
for directive in module.globs.borrow().iter() {
if self.is_accessible(directive.vis.get()) {
if let Some(module) = directive.imported_module.get() {
let result = self.resolve_name_in_module(module, name, ns, false, None);
let result = self.resolve_ident_in_module(module, ident, ns, false, None);
if let Err(Undetermined) = result {
return Err(Undetermined);
}
......@@ -299,12 +300,13 @@ pub fn import(&mut self, binding: &'a NameBinding<'a>, directive: &'a ImportDire
}
// Define the name or return the existing binding if there is a collision.
pub fn try_define<T>(&mut self, module: Module<'a>, name: Name, ns: Namespace, binding: T)
pub fn try_define<T>(&mut self, module: Module<'a>, ident: Ident, ns: Namespace, binding: T)
-> Result<(), &'a NameBinding<'a>>
where T: ToNameBinding<'a>
{
let ident = ident.unhygienize();
let binding = self.arenas.alloc_name_binding(binding.to_name_binding());
self.update_resolution(module, name, ns, |this, resolution| {
self.update_resolution(module, ident, ns, |this, resolution| {
if let Some(old_binding) = resolution.binding {
if binding.is_glob_import() {
if !old_binding.is_glob_import() &&
......@@ -347,13 +349,14 @@ pub fn ambiguity(&mut self, b1: &'a NameBinding<'a>, b2: &'a NameBinding<'a>)
// Use `f` to mutate the resolution of the name in the module.
// If the resolution becomes a success, define it in the module's glob importers.
fn update_resolution<T, F>(&mut self, module: Module<'a>, name: Name, ns: Namespace, f: F) -> T
fn update_resolution<T, F>(&mut self, module: Module<'a>, ident: Ident, ns: Namespace, f: F)
-> T
where F: FnOnce(&mut Resolver<'a>, &mut NameResolution<'a>) -> T
{
// Ensure that `resolution` isn't borrowed when defining in the module's glob importers,
// during which the resolution might end up getting re-defined via a glob cycle.
let (binding, t) = {
let mut resolution = &mut *self.resolution(module, name, ns).borrow_mut();
let mut resolution = &mut *self.resolution(module, ident, ns).borrow_mut();
let old_binding = resolution.binding();
let t = f(self, resolution);
......@@ -372,7 +375,7 @@ fn update_resolution<T, F>(&mut self, module: Module<'a>, name: Name, ns: Namesp
for directive in module.glob_importers.borrow_mut().iter() {
if self.is_accessible_from(binding.vis, directive.parent) {
let imported_binding = self.import(binding, directive);
let _ = self.try_define(directive.parent, name, ns, imported_binding);
let _ = self.try_define(directive.parent, ident, ns, imported_binding);
}
}
......@@ -508,7 +511,7 @@ fn resolve_import(&mut self, directive: &'b ImportDirective<'b>) -> bool {
let mut indeterminate = false;
self.per_ns(|this, ns| {
if let Err(Undetermined) = result[ns].get() {
result[ns].set(this.resolve_name_in_module(module, source, ns, false, None));
result[ns].set(this.resolve_ident_in_module(module, source, ns, false, None));
} else {
return
};
......@@ -564,7 +567,7 @@ fn finalize_import(&mut self, directive: &'b ImportDirective<'b>) -> Option<Stri
_ => return None,
};
let (name, result) = match directive.subclass {
let (ident, result) = match directive.subclass {
SingleImport { source, ref result, .. } => (source, result),
GlobImport { .. } if module.def_id() == directive.parent.def_id() => {
// Importing a module into itself is not allowed.
......@@ -586,8 +589,8 @@ fn finalize_import(&mut self, directive: &'b ImportDirective<'b>) -> Option<Stri
self.per_ns(|this, ns| {
if let Ok(binding) = result[ns].get() {
all_ns_err = false;
if this.record_use(name, ns, binding, directive.span) {
this.resolution(module, name, ns).borrow_mut().binding =
if this.record_use(ident, ns, binding, directive.span) {
this.resolution(module, ident, ns).borrow_mut().binding =
Some(this.dummy_binding);
}
}
......@@ -596,7 +599,7 @@ fn finalize_import(&mut self, directive: &'b ImportDirective<'b>) -> Option<Stri
if all_ns_err {
let mut all_ns_failed = true;
self.per_ns(|this, ns| {
match this.resolve_name_in_module(module, name, ns, false, Some(span)) {
match this.resolve_ident_in_module(module, ident, ns, false, Some(span)) {
Ok(_) => all_ns_failed = false,
_ => {}
}
......@@ -604,27 +607,28 @@ fn finalize_import(&mut self, directive: &'b ImportDirective<'b>) -> Option<Stri
return if all_ns_failed {
let resolutions = module.resolutions.borrow();
let names = resolutions.iter().filter_map(|(&(ref n, _), resolution)| {
if *n == name { return None; } // Never suggest the same name
let names = resolutions.iter().filter_map(|(&(ref i, _), resolution)| {
if *i == ident { return None; } // Never suggest the same name
match *resolution.borrow() {
NameResolution { binding: Some(_), .. } => Some(n),
NameResolution { binding: Some(_), .. } => Some(&i.name),
NameResolution { single_imports: SingleImports::None, .. } => None,
_ => Some(n),
_ => Some(&i.name),
}
});
let lev_suggestion = match find_best_match_for_name(names, &name.as_str(), None) {
Some(name) => format!(". Did you mean to use `{}`?", name),
None => "".to_owned(),
};
let lev_suggestion =
match find_best_match_for_name(names, &ident.name.as_str(), None) {
Some(name) => format!(". Did you mean to use `{}`?", name),
None => "".to_owned(),
};
let module_str = module_to_string(module);
let msg = if &module_str == "???" {
format!("no `{}` in the root{}", name, lev_suggestion)
format!("no `{}` in the root{}", ident, lev_suggestion)
} else {
format!("no `{}` in `{}`{}", name, module_str, lev_suggestion)
format!("no `{}` in `{}`{}", ident, module_str, lev_suggestion)
};
Some(msg)
} else {
// `resolve_name_in_module` reported a privacy error.
// `resolve_ident_in_module` reported a privacy error.
self.import_dummy_binding(directive);
None
}
......@@ -649,18 +653,18 @@ fn finalize_import(&mut self, directive: &'b ImportDirective<'b>) -> Option<Stri
if ns == TypeNS && binding.is_extern_crate() {
let msg = format!("extern crate `{}` is private, and cannot be reexported \
(error E0364), consider declaring with `pub`",
name);
ident);
self.session.add_lint(PRIVATE_IN_PUBLIC, directive.id, directive.span, msg);
} else if ns == TypeNS {
struct_span_err!(self.session, directive.span, E0365,
"`{}` is private, and cannot be reexported", name)
.span_label(directive.span, &format!("reexport of private `{}`", name))
.note(&format!("consider declaring type or module `{}` with `pub`", name))
"`{}` is private, and cannot be reexported", ident)
.span_label(directive.span, &format!("reexport of private `{}`", ident))
.note(&format!("consider declaring type or module `{}` with `pub`", ident))
.emit();
} else {
let msg = format!("`{}` is private, and cannot be reexported", name);
let msg = format!("`{}` is private, and cannot be reexported", ident);
let note_msg =
format!("consider marking `{}` as `pub` in the imported module", name);
format!("consider marking `{}` as `pub` in the imported module", ident);
struct_span_err!(self.session, directive.span, E0364, "{}", &msg)
.span_note(directive.span, &note_msg)
.emit();
......@@ -697,13 +701,13 @@ fn resolve_glob_import(&mut self, directive: &'b ImportDirective<'b>) {
// Ensure that `resolutions` isn't borrowed during `try_define`,
// since it might get updated via a glob cycle.
let bindings = module.resolutions.borrow().iter().filter_map(|(name, resolution)| {
resolution.borrow().binding().map(|binding| (*name, binding))
let bindings = module.resolutions.borrow().iter().filter_map(|(&ident, resolution)| {
resolution.borrow().binding().map(|binding| (ident, binding))
}).collect::<Vec<_>>();
for ((name, ns), binding) in bindings {
for ((ident, ns), binding) in bindings {
if binding.pseudo_vis() == ty::Visibility::Public || self.is_accessible(binding.vis) {
let imported_binding = self.import(binding, directive);
let _ = self.try_define(directive.parent, name, ns, imported_binding);
let _ = self.try_define(directive.parent, ident, ns, imported_binding);
}
}
......@@ -722,7 +726,7 @@ fn finalize_resolutions_in(&mut self, module: Module<'b>) {
reexports = mem::replace(&mut self.macro_exports, Vec::new());
}
for (&(name, ns), resolution) in module.resolutions.borrow().iter() {
for (&(ident, ns), resolution) in module.resolutions.borrow().iter() {
let resolution = resolution.borrow();
let binding = match resolution.binding {
Some(binding) => binding,
......@@ -736,7 +740,7 @@ fn finalize_resolutions_in(&mut self, module: Module<'b>) {
if !def.def_id().is_local() {
self.session.cstore.export_macros(def.def_id().krate);
}
reexports.push(Export { name: name, def: def });
reexports.push(Export { name: ident.name, def: def });
}
}
......@@ -745,7 +749,7 @@ fn finalize_resolutions_in(&mut self, module: Module<'b>) {
!orig_binding.vis.is_at_least(binding.vis, self) {
let msg = format!("variant `{}` is private, and cannot be reexported \
(error E0364), consider declaring its enum as `pub`",
name);
ident);
self.session.add_lint(PRIVATE_IN_PUBLIC, directive.id, binding.span, msg);
}
}
......
......@@ -47,10 +47,14 @@ pub const fn with_empty_ctxt(name: Name) -> Ident {
Ident { name: name, ctxt: SyntaxContext::empty() }
}
/// Maps a string to an identifier with an empty syntax context.
pub fn from_str(s: &str) -> Ident {
Ident::with_empty_ctxt(Symbol::intern(s))
}
/// Maps a string to an identifier with an empty syntax context.
pub fn from_str(s: &str) -> Ident {
Ident::with_empty_ctxt(Symbol::intern(s))
}
pub fn unhygienize(&self) -> Ident {
Ident { name: self.name, ctxt: SyntaxContext::empty() }
}
}
impl fmt::Debug for Ident {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册