#[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.
}
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)
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};
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) => {
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 {
}
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);
}
}
_ => {}
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| {
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);
}
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),
};
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),
};
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);
}
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);
}
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;
}
}
-#[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.
/// 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.
}
impl DefPathData {
- pub fn get_opt_name(&self) -> Option<ast::Name> {
+ pub fn get_opt_ident(&self) -> Option<Ident> {
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 |
}
}
+ pub fn get_opt_name(&self) -> Option<ast::Name> {
+ 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
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<H: ::std::hash::Hasher>(&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)
+ }
+ }
+ }
+}
}
impl_stable_hash_for!(struct hir::def::Export {
- name,
+ ident,
def,
span
});
#![feature(conservative_impl_trait)]
#![feature(const_fn)]
#![feature(core_intrinsics)]
+#![feature(discriminant_value)]
#![feature(i128_type)]
#![feature(libc)]
#![feature(never_type)]
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};
},
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
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),
});
}
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 {
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) => {
// 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 });
}
_ => {}
}
/// 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);
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 {
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");
}
}));
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);
}
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);
}
}
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)
.emit();
}
}
- reexports.push(Export { name: ident.name, def: def, span: binding.span });
+ reexports.push(Export { ident: ident.modern(), def: def, span: binding.span });
}
}
impl Encodable for Ident {
fn encode<S: Encoder>(&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: Decoder>(d: &mut D) -> Result<Ident, D::Error> {
- 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..]))
+ })
}
}