diff --git a/src/librustc/hir/def.rs b/src/librustc/hir/def.rs index 771031db0c0..feded417ce1 100644 --- a/src/librustc/hir/def.rs +++ b/src/librustc/hir/def.rs @@ -117,7 +117,7 @@ pub type ExportMap = NodeMap>; #[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable)] pub struct Export { - pub name: ast::Name, // The name of the target. + pub ident: ast::Ident, // The name of the target. pub def: Def, // The definition of the target. pub span: Span, // The span of the target definition. } diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 5ef278207ed..91cfbc38aa0 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -2662,7 +2662,7 @@ impl<'a> LoweringContext<'a> { let parent_def = self.parent_def.unwrap(); let def_id = { let defs = self.resolver.definitions(); - let def_path_data = DefPathData::Binding(name.as_str()); + let def_path_data = DefPathData::Binding(Ident::with_empty_ctxt(name)); let def_index = defs .create_def_with_parent(parent_def, id, def_path_data, REGULAR_SPACE, Mark::root()); DefId::local(def_index) diff --git a/src/librustc/hir/map/def_collector.rs b/src/librustc/hir/map/def_collector.rs index f834c744f95..cb25b462b6e 100644 --- a/src/librustc/hir/map/def_collector.rs +++ b/src/librustc/hir/map/def_collector.rs @@ -14,7 +14,7 @@ use hir::def_id::{CRATE_DEF_INDEX, DefIndex, DefIndexAddressSpace}; use syntax::ast::*; use syntax::ext::hygiene::Mark; use syntax::visit; -use syntax::symbol::{Symbol, keywords}; +use syntax::symbol::keywords; use hir::map::{ITEM_LIKE_SPACE, REGULAR_SPACE}; @@ -103,14 +103,14 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> { DefPathData::Impl, ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..) | ItemKind::Trait(..) | ItemKind::ExternCrate(..) | ItemKind::ForeignMod(..) | ItemKind::Ty(..) => - DefPathData::TypeNs(i.ident.name.as_str()), + DefPathData::TypeNs(i.ident.modern()), ItemKind::Mod(..) if i.ident == keywords::Invalid.ident() => { return visit::walk_item(self, i); } - ItemKind::Mod(..) => DefPathData::Module(i.ident.name.as_str()), + ItemKind::Mod(..) => DefPathData::Module(i.ident.modern()), ItemKind::Static(..) | ItemKind::Const(..) | ItemKind::Fn(..) => - DefPathData::ValueNs(i.ident.name.as_str()), - ItemKind::MacroDef(..) => DefPathData::MacroDef(i.ident.name.as_str()), + DefPathData::ValueNs(i.ident.modern()), + ItemKind::MacroDef(..) => DefPathData::MacroDef(i.ident.modern()), ItemKind::Mac(..) => return self.visit_macro_invoc(i.id, false), ItemKind::GlobalAsm(..) => DefPathData::Misc, ItemKind::Use(ref view_path) => { @@ -138,15 +138,13 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> { for v in &enum_definition.variants { let variant_def_index = this.create_def(v.node.data.id(), - DefPathData::EnumVariant(v.node.name.name.as_str()), + DefPathData::EnumVariant(v.node.name.modern()), REGULAR_SPACE); this.with_parent(variant_def_index, |this| { for (index, field) in v.node.data.fields().iter().enumerate() { - let name = field.ident.map(|ident| ident.name) - .unwrap_or_else(|| Symbol::intern(&index.to_string())); - this.create_def(field.id, - DefPathData::Field(name.as_str()), - REGULAR_SPACE); + let ident = field.ident.map(Ident::modern) + .unwrap_or_else(|| Ident::from_str(&index.to_string())); + this.create_def(field.id, DefPathData::Field(ident), REGULAR_SPACE); } if let Some(ref expr) = v.node.disr_expr { @@ -164,9 +162,9 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> { } for (index, field) in struct_def.fields().iter().enumerate() { - let name = field.ident.map(|ident| ident.name.as_str()) - .unwrap_or(Symbol::intern(&index.to_string()).as_str()); - this.create_def(field.id, DefPathData::Field(name), REGULAR_SPACE); + let ident = field.ident.map(Ident::modern) + .unwrap_or_else(|| Ident::from_str(&index.to_string())); + this.create_def(field.id, DefPathData::Field(ident), REGULAR_SPACE); } } _ => {} @@ -177,7 +175,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> { fn visit_foreign_item(&mut self, foreign_item: &'a ForeignItem) { let def = self.create_def(foreign_item.id, - DefPathData::ValueNs(foreign_item.ident.name.as_str()), + DefPathData::ValueNs(foreign_item.ident.modern()), REGULAR_SPACE); self.with_parent(def, |this| { @@ -188,7 +186,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> { fn visit_generics(&mut self, generics: &'a Generics) { for ty_param in generics.ty_params.iter() { self.create_def(ty_param.id, - DefPathData::TypeParam(ty_param.ident.name.as_str()), + DefPathData::TypeParam(ty_param.ident.modern()), REGULAR_SPACE); } @@ -198,8 +196,8 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> { fn visit_trait_item(&mut self, ti: &'a TraitItem) { let def_data = match ti.node { TraitItemKind::Method(..) | TraitItemKind::Const(..) => - DefPathData::ValueNs(ti.ident.name.as_str()), - TraitItemKind::Type(..) => DefPathData::TypeNs(ti.ident.name.as_str()), + DefPathData::ValueNs(ti.ident.modern()), + TraitItemKind::Type(..) => DefPathData::TypeNs(ti.ident.modern()), TraitItemKind::Macro(..) => return self.visit_macro_invoc(ti.id, false), }; @@ -216,8 +214,8 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> { fn visit_impl_item(&mut self, ii: &'a ImplItem) { let def_data = match ii.node { ImplItemKind::Method(..) | ImplItemKind::Const(..) => - DefPathData::ValueNs(ii.ident.name.as_str()), - ImplItemKind::Type(..) => DefPathData::TypeNs(ii.ident.name.as_str()), + DefPathData::ValueNs(ii.ident.modern()), + ImplItemKind::Type(..) => DefPathData::TypeNs(ii.ident.modern()), ImplItemKind::Macro(..) => return self.visit_macro_invoc(ii.id, false), }; @@ -238,7 +236,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> { PatKind::Mac(..) => return self.visit_macro_invoc(pat.id, false), PatKind::Ident(_, id, _) => { let def = self.create_def(pat.id, - DefPathData::Binding(id.node.name.as_str()), + DefPathData::Binding(id.node.modern()), REGULAR_SPACE); self.parent_def = Some(def); } @@ -283,7 +281,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> { fn visit_lifetime_def(&mut self, def: &'a LifetimeDef) { self.create_def(def.lifetime.id, - DefPathData::LifetimeDef(def.lifetime.ident.name.as_str()), + DefPathData::LifetimeDef(def.lifetime.ident.modern()), REGULAR_SPACE); } diff --git a/src/librustc/hir/map/definitions.rs b/src/librustc/hir/map/definitions.rs index 4a7fe05df8a..c86b140fbc6 100644 --- a/src/librustc/hir/map/definitions.rs +++ b/src/librustc/hir/map/definitions.rs @@ -23,8 +23,8 @@ use rustc_data_structures::stable_hasher::StableHasher; use serialize::{Encodable, Decodable, Encoder, Decoder}; use std::fmt::Write; use std::hash::Hash; -use syntax::ast; -use syntax::ext::hygiene::Mark; +use syntax::ast::{self, Ident}; +use syntax::ext::hygiene::{Mark, SyntaxContext}; use syntax::symbol::{Symbol, InternedString}; use ty::TyCtxt; use util::nodemap::NodeMap; @@ -327,7 +327,7 @@ impl DefPath { } } -#[derive(Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)] +#[derive(Clone, Debug, RustcEncodable, RustcDecodable)] pub enum DefPathData { // Root: these should only be used for the root nodes, because // they are treated specially by the `def_path` function. @@ -341,31 +341,31 @@ pub enum DefPathData { /// An impl Impl, /// Something in the type NS - TypeNs(InternedString), + TypeNs(Ident), /// Something in the value NS - ValueNs(InternedString), + ValueNs(Ident), /// A module declaration - Module(InternedString), + Module(Ident), /// A macro rule - MacroDef(InternedString), + MacroDef(Ident), /// A closure expression ClosureExpr, // Subportions of items /// A type parameter (generic parameter) - TypeParam(InternedString), + TypeParam(Ident), /// A lifetime definition - LifetimeDef(InternedString), + LifetimeDef(Ident), /// A variant of a enum - EnumVariant(InternedString), + EnumVariant(Ident), /// A struct field - Field(InternedString), + Field(Ident), /// Implicit ctor for a tuple-like struct StructCtor, /// Initializer for a const Initializer, /// Pattern binding - Binding(InternedString), + Binding(Ident), /// An `impl Trait` type node. ImplTrait, /// A `typeof` type node. @@ -551,18 +551,18 @@ impl Definitions { } impl DefPathData { - pub fn get_opt_name(&self) -> Option { + pub fn get_opt_ident(&self) -> Option { use self::DefPathData::*; match *self { - TypeNs(ref name) | - ValueNs(ref name) | - Module(ref name) | - MacroDef(ref name) | - TypeParam(ref name) | - LifetimeDef(ref name) | - EnumVariant(ref name) | - Binding(ref name) | - Field(ref name) => Some(Symbol::intern(name)), + TypeNs(ident) | + ValueNs(ident) | + Module(ident) | + MacroDef(ident) | + TypeParam(ident) | + LifetimeDef(ident) | + EnumVariant(ident) | + Binding(ident) | + Field(ident) => Some(ident), Impl | CrateRoot | @@ -575,19 +575,23 @@ impl DefPathData { } } + pub fn get_opt_name(&self) -> Option { + self.get_opt_ident().map(|ident| ident.name) + } + pub fn as_interned_str(&self) -> InternedString { use self::DefPathData::*; let s = match *self { - TypeNs(ref name) | - ValueNs(ref name) | - Module(ref name) | - MacroDef(ref name) | - TypeParam(ref name) | - LifetimeDef(ref name) | - EnumVariant(ref name) | - Binding(ref name) | - Field(ref name) => { - return name.clone(); + TypeNs(ident) | + ValueNs(ident) | + Module(ident) | + MacroDef(ident) | + TypeParam(ident) | + LifetimeDef(ident) | + EnumVariant(ident) | + Binding(ident) | + Field(ident) => { + return ident.name.as_str(); } // note that this does not show up in user printouts @@ -609,3 +613,25 @@ impl DefPathData { self.as_interned_str().to_string() } } + +impl Eq for DefPathData {} +impl PartialEq for DefPathData { + fn eq(&self, other: &DefPathData) -> bool { + ::std::mem::discriminant(self) == ::std::mem::discriminant(other) && + self.get_opt_ident() == other.get_opt_ident() + } +} + +impl ::std::hash::Hash for DefPathData { + fn hash(&self, hasher: &mut H) { + ::std::mem::discriminant(self).hash(hasher); + if let Some(ident) = self.get_opt_ident() { + if ident.ctxt == SyntaxContext::empty() && ident.name == ident.name.interned() { + ident.name.as_str().hash(hasher) + } else { + // FIXME(jseyfried) implement stable hashing for idents with macros 2.0 hygiene info + ident.hash(hasher) + } + } + } +} diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs index 86965723f30..dbe91e2725d 100644 --- a/src/librustc/ich/impls_hir.rs +++ b/src/librustc/ich/impls_hir.rs @@ -1118,7 +1118,7 @@ impl<'a, 'tcx> HashStable> for hir::def_id::DefIn } impl_stable_hash_for!(struct hir::def::Export { - name, + ident, def, span }); diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 2b4b5cc7333..d1d9dd4853d 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -28,6 +28,7 @@ #![feature(conservative_impl_trait)] #![feature(const_fn)] #![feature(core_intrinsics)] +#![feature(discriminant_value)] #![feature(i128_type)] #![feature(libc)] #![feature(never_type)] diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index d8826d87d4d..1db5821f318 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -39,7 +39,7 @@ use std::u32; use rustc_serialize::{Decodable, Decoder, SpecializedDecoder, opaque}; use syntax::attr; -use syntax::ast; +use syntax::ast::{self, Ident}; use syntax::codemap; use syntax::ext::base::MacroKind; use syntax_pos::{self, Span, BytePos, Pos, DUMMY_SP, NO_EXPANSION}; @@ -667,7 +667,8 @@ impl<'a, 'tcx> CrateMetadata { }, ext.kind() ); - callback(def::Export { name: name, def: def, span: DUMMY_SP }); + let ident = Ident::with_empty_ctxt(name); + callback(def::Export { ident: ident, def: def, span: DUMMY_SP }); } } return @@ -703,7 +704,7 @@ impl<'a, 'tcx> CrateMetadata { if let Some(def) = self.get_def(child_index) { callback(def::Export { def: def, - name: self.item_name(child_index), + ident: Ident::with_empty_ctxt(self.item_name(child_index)), span: self.entry(child_index).span.decode(self), }); } @@ -720,7 +721,8 @@ impl<'a, 'tcx> CrateMetadata { let span = child.span.decode(self); if let (Some(def), Some(name)) = (self.get_def(child_index), def_key.disambiguated_data.data.get_opt_name()) { - callback(def::Export { def: def, name: name, span: span }); + let ident = Ident::with_empty_ctxt(name); + callback(def::Export { def: def, ident: ident, span: span }); // For non-reexport structs and variants add their constructors to children. // Reexport lists automatically contain constructors when necessary. match def { @@ -728,7 +730,7 @@ impl<'a, 'tcx> CrateMetadata { if let Some(ctor_def_id) = self.get_struct_ctor_def_id(child_index) { let ctor_kind = self.get_ctor_kind(child_index); let ctor_def = Def::StructCtor(ctor_def_id, ctor_kind); - callback(def::Export { def: ctor_def, name: name, span: span }); + callback(def::Export { def: ctor_def, ident: ident, span: span }); } } Def::Variant(def_id) => { @@ -736,7 +738,7 @@ impl<'a, 'tcx> CrateMetadata { // value namespace, they are reserved for possible future use. let ctor_kind = self.get_ctor_kind(child_index); let ctor_def = Def::VariantCtor(def_id, ctor_kind); - callback(def::Export { def: ctor_def, name: name, span: span }); + callback(def::Export { def: ctor_def, ident: ident, span: span }); } _ => {} } diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 72f555b47cc..597a62f8688 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -439,7 +439,7 @@ impl<'a> Resolver<'a> { /// Builds the reduced graph for a single item in an external crate. fn build_reduced_graph_for_external_crate_def(&mut self, parent: Module<'a>, child: Export) { - let ident = Ident::with_empty_ctxt(child.name); + let ident = child.ident; let def = child.def; let def_id = def.def_id(); let vis = self.session.cstore.visibility(def_id); @@ -480,9 +480,8 @@ impl<'a> Resolver<'a> { for child in self.session.cstore.item_children(def_id) { let ns = if let Def::AssociatedTy(..) = child.def { TypeNS } else { ValueNS }; - let ident = Ident::with_empty_ctxt(child.name); - self.define(module, ident, ns, (child.def, ty::Visibility::Public, - DUMMY_SP, expansion)); + self.define(module, child.ident, ns, + (child.def, ty::Visibility::Public, DUMMY_SP, expansion)); if self.session.cstore.associated_item_cloned(child.def.def_id()) .method_has_self_argument { @@ -643,7 +642,7 @@ impl<'a> Resolver<'a> { let ident = Ident::with_empty_ctxt(name); let result = self.resolve_ident_in_module(module, ident, MacroNS, false, false, span); if let Ok(binding) = result { - self.macro_exports.push(Export { name: name, def: binding.def(), span: span }); + self.macro_exports.push(Export { ident: ident, def: binding.def(), span: span }); } else { span_err!(self.session, span, E0470, "reexported macro not found"); } diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 8957312e152..9a37df76232 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -726,7 +726,8 @@ impl<'a> Resolver<'a> { })); if attr::contains_name(&item.attrs, "macro_export") { let def = Def::Macro(def_id, MacroKind::Bang); - self.macro_exports.push(Export { name: ident.name, def: def, span: item.span }); + self.macro_exports + .push(Export { ident: ident.modern(), def: def, span: item.span }); } else { self.unused_macros.insert(def_id); } diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index f304aad4638..c077f507932 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -803,7 +803,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { if module as *const _ == self.graph_root as *const _ { let macro_exports = mem::replace(&mut self.macro_exports, Vec::new()); for export in macro_exports.into_iter().rev() { - if exported_macro_names.insert(export.name, export.span).is_none() { + if exported_macro_names.insert(export.ident.modern(), export.span).is_none() { reexports.push(export); } } @@ -824,7 +824,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { self.session.cstore.export_macros(def.def_id().krate); } if let Def::Macro(..) = def { - if let Some(&span) = exported_macro_names.get(&ident.name) { + if let Some(&span) = exported_macro_names.get(&ident.modern()) { let msg = format!("a macro named `{}` has already been exported", ident); self.session.struct_span_err(span, &msg) @@ -833,7 +833,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> { .emit(); } } - reexports.push(Export { name: ident.name, def: def, span: binding.span }); + reexports.push(Export { ident: ident.modern(), def: def, span: binding.span }); } } diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index 17de8129f99..73c0256f2c1 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -54,13 +54,24 @@ impl fmt::Display for Ident { impl Encodable for Ident { fn encode(&self, s: &mut S) -> Result<(), S::Error> { - self.name.encode(s) + if self.ctxt.modern() == SyntaxContext::empty() { + s.emit_str(&self.name.as_str()) + } else { // FIXME(jseyfried) intercrate hygiene + let mut string = "#".to_owned(); + string.push_str(&self.name.as_str()); + s.emit_str(&string) + } } } impl Decodable for Ident { fn decode(d: &mut D) -> Result { - Ok(Ident::with_empty_ctxt(Symbol::decode(d)?)) + let string = d.read_str()?; + Ok(if !string.starts_with('#') { + Ident::from_str(&string) + } else { // FIXME(jseyfried) intercrate hygiene + Ident::with_empty_ctxt(Symbol::gensym(&string[1..])) + }) } }