Skip to content

Commit

Permalink
Hygienize librustc_typeck.
Browse files Browse the repository at this point in the history
  • Loading branch information
jseyfried committed May 25, 2017
1 parent 1f175fa commit bfa2ef6
Show file tree
Hide file tree
Showing 14 changed files with 170 additions and 61 deletions.
47 changes: 30 additions & 17 deletions src/librustc/hir/lowering.rs
Expand Up @@ -47,7 +47,7 @@ use hir::def_id::{DefIndex, DefId, CRATE_DEF_INDEX};
use hir::def::{Def, PathResolution};
use rustc_data_structures::indexed_vec::IndexVec;
use session::Session;
use util::nodemap::{DefIdMap, NodeMap};
use util::nodemap::{DefIdMap, FxHashMap, NodeMap};

use std::collections::BTreeMap;
use std::fmt::Debug;
Expand Down Expand Up @@ -77,6 +77,7 @@ pub struct LoweringContext<'a> {
// a definition, then we can properly create the def id.
parent_def: Option<DefIndex>,
resolver: &'a mut Resolver,
name_map: FxHashMap<Ident, Name>,

/// The items being lowered are collected here.
items: BTreeMap<NodeId, hir::Item>,
Expand Down Expand Up @@ -126,6 +127,7 @@ pub fn lower_crate(sess: &Session,
sess: sess,
parent_def: None,
resolver: resolver,
name_map: FxHashMap(),
items: BTreeMap::new(),
trait_items: BTreeMap::new(),
impl_items: BTreeMap::new(),
Expand Down Expand Up @@ -495,6 +497,14 @@ impl<'a> LoweringContext<'a> {
}
}

fn lower_ident(&mut self, ident: Ident) -> Name {
let ident = ident.modern();
if ident.ctxt == SyntaxContext::empty() {
return ident.name;
}
*self.name_map.entry(ident).or_insert_with(|| Symbol::from_ident(ident))
}

fn lower_opt_sp_ident(&mut self, o_id: Option<Spanned<Ident>>) -> Option<Spanned<Name>> {
o_id.map(|sp_ident| respan(sp_ident.span, sp_ident.node.name))
}
Expand Down Expand Up @@ -546,7 +556,7 @@ impl<'a> LoweringContext<'a> {
fn lower_ty_binding(&mut self, b: &TypeBinding) -> hir::TypeBinding {
hir::TypeBinding {
id: self.lower_node_id(b.id),
name: b.ident.name,
name: self.lower_ident(b.ident),
ty: self.lower_ty(&b.ty),
span: b.span,
}
Expand Down Expand Up @@ -844,7 +854,7 @@ impl<'a> LoweringContext<'a> {
}

hir::PathSegment {
name: segment.identifier.name,
name: self.lower_ident(segment.identifier),
parameters: parameters,
}
}
Expand Down Expand Up @@ -941,7 +951,7 @@ impl<'a> LoweringContext<'a> {
}

fn lower_ty_param(&mut self, tp: &TyParam, add_bounds: &[TyParamBound]) -> hir::TyParam {
let mut name = tp.ident.name;
let mut name = self.lower_ident(tp.ident);

// Don't expose `Self` (recovered "keyword used as ident" parse error).
// `rustc::ty` expects `Self` to be only used for a trait's `Self`.
Expand Down Expand Up @@ -1137,7 +1147,11 @@ impl<'a> LoweringContext<'a> {
hir::StructField {
span: f.span,
id: self.lower_node_id(f.id),
name: f.ident.map(|ident| ident.name).unwrap_or(Symbol::intern(&index.to_string())),
name: self.lower_ident(match f.ident {
Some(ident) => ident,
// FIXME(jseyfried) positional field hygiene
None => Ident { name: Symbol::intern(&index.to_string()), ctxt: f.span.ctxt },
}),
vis: self.lower_visibility(&f.vis, None),
ty: self.lower_ty(&f.ty),
attrs: self.lower_attrs(&f.attrs),
Expand All @@ -1146,7 +1160,7 @@ impl<'a> LoweringContext<'a> {

fn lower_field(&mut self, f: &Field) -> hir::Field {
hir::Field {
name: respan(f.ident.span, f.ident.node.name),
name: respan(f.ident.span, self.lower_ident(f.ident.node)),
expr: P(self.lower_expr(&f.expr)),
span: f.span,
is_shorthand: f.is_shorthand,
Expand Down Expand Up @@ -1371,7 +1385,7 @@ impl<'a> LoweringContext<'a> {
self.with_parent_def(i.id, |this| {
hir::TraitItem {
id: this.lower_node_id(i.id),
name: i.ident.name,
name: this.lower_ident(i.ident),
attrs: this.lower_attrs(&i.attrs),
node: match i.node {
TraitItemKind::Const(ref ty, ref default) => {
Expand Down Expand Up @@ -1421,7 +1435,7 @@ impl<'a> LoweringContext<'a> {
};
hir::TraitItemRef {
id: hir::TraitItemId { node_id: i.id },
name: i.ident.name,
name: self.lower_ident(i.ident),
span: i.span,
defaultness: self.lower_defaultness(Defaultness::Default, has_default),
kind: kind,
Expand All @@ -1432,7 +1446,7 @@ impl<'a> LoweringContext<'a> {
self.with_parent_def(i.id, |this| {
hir::ImplItem {
id: this.lower_node_id(i.id),
name: i.ident.name,
name: this.lower_ident(i.ident),
attrs: this.lower_attrs(&i.attrs),
vis: this.lower_visibility(&i.vis, None),
defaultness: this.lower_defaultness(i.defaultness, true /* [1] */),
Expand Down Expand Up @@ -1461,7 +1475,7 @@ impl<'a> LoweringContext<'a> {
fn lower_impl_item_ref(&mut self, i: &ImplItem) -> hir::ImplItemRef {
hir::ImplItemRef {
id: hir::ImplItemId { node_id: i.id },
name: i.ident.name,
name: self.lower_ident(i.ident),
span: i.span,
vis: self.lower_visibility(&i.vis, Some(i.id)),
defaultness: self.lower_defaultness(i.defaultness, true /* [1] */),
Expand Down Expand Up @@ -1655,7 +1669,7 @@ impl<'a> LoweringContext<'a> {
Spanned {
span: f.span,
node: hir::FieldPat {
name: f.node.ident.name,
name: self.lower_ident(f.node.ident),
pat: self.lower_pat(&f.node.pat),
is_shorthand: f.node.is_shorthand,
},
Expand Down Expand Up @@ -1825,7 +1839,7 @@ impl<'a> LoweringContext<'a> {
ExprKind::MethodCall(i, ref tps, ref args) => {
let tps = tps.iter().map(|x| self.lower_ty(x)).collect();
let args = args.iter().map(|x| self.lower_expr(x)).collect();
hir::ExprMethodCall(respan(i.span, i.node.name), tps, args)
hir::ExprMethodCall(respan(i.span, self.lower_ident(i.node)), tps, args)
}
ExprKind::Binary(binop, ref lhs, ref rhs) => {
let binop = self.lower_binop(binop);
Expand Down Expand Up @@ -1924,7 +1938,8 @@ impl<'a> LoweringContext<'a> {
P(self.lower_expr(er)))
}
ExprKind::Field(ref el, ident) => {
hir::ExprField(P(self.lower_expr(el)), respan(ident.span, ident.node.name))
hir::ExprField(P(self.lower_expr(el)),
respan(ident.span, self.lower_ident(ident.node)))
}
ExprKind::TupField(ref el, ident) => {
hir::ExprTupField(P(self.lower_expr(el)), ident)
Expand Down Expand Up @@ -2643,10 +2658,8 @@ impl<'a> LoweringContext<'a> {
let def_id = {
let defs = self.resolver.definitions();
let def_path_data = DefPathData::Binding(name.as_str());
let def_index = defs.create_def_with_parent(parent_def,
id,
def_path_data,
REGULAR_SPACE);
let def_index = defs
.create_def_with_parent(parent_def, id, def_path_data, REGULAR_SPACE, Mark::root());
DefId::local(def_index)
};

Expand Down
7 changes: 5 additions & 2 deletions src/librustc/hir/map/def_collector.rs
Expand Up @@ -22,6 +22,7 @@ use hir::map::{ITEM_LIKE_SPACE, REGULAR_SPACE};
pub struct DefCollector<'a> {
definitions: &'a mut Definitions,
parent_def: Option<DefIndex>,
expansion: Mark,
pub visit_macro_invoc: Option<&'a mut FnMut(MacroInvocationData)>,
}

Expand All @@ -32,9 +33,10 @@ pub struct MacroInvocationData {
}

impl<'a> DefCollector<'a> {
pub fn new(definitions: &'a mut Definitions) -> Self {
pub fn new(definitions: &'a mut Definitions, expansion: Mark) -> Self {
DefCollector {
definitions: definitions,
expansion: expansion,
parent_def: None,
visit_macro_invoc: None,
}
Expand All @@ -54,7 +56,8 @@ impl<'a> DefCollector<'a> {
-> DefIndex {
let parent_def = self.parent_def.unwrap();
debug!("create_def(node_id={:?}, data={:?}, parent_def={:?})", node_id, data, parent_def);
self.definitions.create_def_with_parent(parent_def, node_id, data, address_space)
self.definitions
.create_def_with_parent(parent_def, node_id, data, address_space, self.expansion)
}

pub fn with_parent<F: FnOnce(&mut Self)>(&mut self, parent_def: DefIndex, f: F) {
Expand Down
23 changes: 22 additions & 1 deletion src/librustc/hir/map/definitions.rs
Expand Up @@ -24,6 +24,7 @@ use serialize::{Encodable, Decodable, Encoder, Decoder};
use std::fmt::Write;
use std::hash::Hash;
use syntax::ast;
use syntax::ext::hygiene::Mark;
use syntax::symbol::{Symbol, InternedString};
use ty::TyCtxt;
use util::nodemap::NodeMap;
Expand Down Expand Up @@ -180,6 +181,8 @@ pub struct Definitions {
node_to_def_index: NodeMap<DefIndex>,
def_index_to_node: [Vec<ast::NodeId>; 2],
pub(super) node_to_hir_id: IndexVec<ast::NodeId, hir::HirId>,
macro_def_scopes: FxHashMap<Mark, DefId>,
expansions: FxHashMap<DefIndex, Mark>,
}

// Unfortunately we have to provide a manual impl of Clone because of the
Expand All @@ -194,6 +197,8 @@ impl Clone for Definitions {
self.def_index_to_node[1].clone(),
],
node_to_hir_id: self.node_to_hir_id.clone(),
macro_def_scopes: self.macro_def_scopes.clone(),
expansions: self.expansions.clone(),
}
}
}
Expand Down Expand Up @@ -379,6 +384,8 @@ impl Definitions {
node_to_def_index: NodeMap(),
def_index_to_node: [vec![], vec![]],
node_to_hir_id: IndexVec::new(),
macro_def_scopes: FxHashMap(),
expansions: FxHashMap(),
}
}

Expand Down Expand Up @@ -472,7 +479,8 @@ impl Definitions {
parent: DefIndex,
node_id: ast::NodeId,
data: DefPathData,
address_space: DefIndexAddressSpace)
address_space: DefIndexAddressSpace,
expansion: Mark)
-> DefIndex {
debug!("create_def_with_parent(parent={:?}, node_id={:?}, data={:?})",
parent, node_id, data);
Expand Down Expand Up @@ -510,6 +518,7 @@ impl Definitions {
assert_eq!(index.as_array_index(),
self.def_index_to_node[address_space.index()].len());
self.def_index_to_node[address_space.index()].push(node_id);
self.expansions.insert(index, expansion);

debug!("create_def_with_parent: def_index_to_node[{:?} <-> {:?}", index, node_id);
self.node_to_def_index.insert(node_id, index);
Expand All @@ -525,6 +534,18 @@ impl Definitions {
"Trying initialize NodeId -> HirId mapping twice");
self.node_to_hir_id = mapping;
}

pub fn expansion(&self, index: DefIndex) -> Mark {
self.expansions[&index]
}

pub fn macro_def_scope(&self, mark: Mark) -> DefId {
self.macro_def_scopes[&mark]
}

pub fn add_macro_def_scope(&mut self, mark: Mark, scope: DefId) {
self.macro_def_scopes.insert(mark, scope);
}
}

impl DefPathData {
Expand Down
7 changes: 4 additions & 3 deletions src/librustc/hir/map/mod.rs
Expand Up @@ -637,14 +637,15 @@ impl<'hir> Map<'hir> {

/// Returns the NodeId of `id`'s nearest module parent, or `id` itself if no
/// module parent is in this map.
pub fn get_module_parent(&self, id: NodeId) -> NodeId {
match self.walk_parent_nodes(id, |node| match *node {
pub fn get_module_parent(&self, id: NodeId) -> DefId {
let id = match self.walk_parent_nodes(id, |node| match *node {
NodeItem(&Item { node: Item_::ItemMod(_), .. }) => true,
_ => false,
}) {
Ok(id) => id,
Err(id) => id,
}
};
self.local_def_id(id)
}

/// Returns the nearest enclosing scope. A scope is an item or block.
Expand Down
48 changes: 33 additions & 15 deletions src/librustc/ty/mod.rs
Expand Up @@ -45,8 +45,9 @@ use std::rc::Rc;
use std::slice;
use std::vec::IntoIter;
use std::mem;
use syntax::ast::{self, DUMMY_NODE_ID, Name, NodeId};
use syntax::ast::{self, DUMMY_NODE_ID, Name, Ident, NodeId};
use syntax::attr;
use syntax::ext::hygiene::{Mark, SyntaxContext};
use syntax::symbol::{Symbol, InternedString};
use syntax_pos::{DUMMY_SP, Span};
use rustc_const_math::ConstInt;
Expand Down Expand Up @@ -268,7 +269,7 @@ impl Visibility {
def => Visibility::Restricted(def.def_id()),
},
hir::Inherited => {
Visibility::Restricted(tcx.hir.local_def_id(tcx.hir.get_module_parent(id)))
Visibility::Restricted(tcx.hir.get_module_parent(id))
}
}
}
Expand Down Expand Up @@ -1823,17 +1824,22 @@ impl<'a, 'gcx, 'tcx> AdtDef {

impl<'a, 'gcx, 'tcx> VariantDef {
#[inline]
pub fn find_field_named(&self,
name: ast::Name)
-> Option<&FieldDef> {
self.fields.iter().find(|f| f.name == name)
pub fn find_field_named(&self, name: ast::Name) -> Option<&FieldDef> {
self.index_of_field_named(name).map(|index| &self.fields[index])
}

#[inline]
pub fn index_of_field_named(&self,
name: ast::Name)
-> Option<usize> {
self.fields.iter().position(|f| f.name == name)
pub fn index_of_field_named(&self, name: ast::Name) -> Option<usize> {
if let Some(index) = self.fields.iter().position(|f| f.name == name) {
return Some(index);
}
let mut ident = name.to_ident();
while ident.ctxt != SyntaxContext::empty() {
ident.ctxt.remove_mark();
if let Some(field) = self.fields.iter().position(|f| f.name.to_ident() == ident) {
return Some(field);
}
}
None
}

#[inline]
Expand Down Expand Up @@ -2257,10 +2263,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
}
}

pub fn vis_is_accessible_from(self, vis: Visibility, block: NodeId) -> bool {
vis.is_accessible_from(self.hir.local_def_id(self.hir.get_module_parent(block)), self)
}

pub fn item_name(self, id: DefId) -> ast::Name {
if let Some(id) = self.hir.as_local_node_id(id) {
self.hir.name(id)
Expand Down Expand Up @@ -2372,6 +2374,22 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
Err(self.sess.cstore.crate_name(impl_did.krate))
}
}

pub fn adjust(self, name: Name, scope: DefId, block: NodeId) -> (Ident, DefId) {
self.adjust_ident(name.to_ident(), scope, block)
}

pub fn adjust_ident(self, mut ident: Ident, scope: DefId, block: NodeId) -> (Ident, DefId) {
let expansion = match scope.krate {
LOCAL_CRATE => self.hir.definitions().expansion(scope.index),
_ => Mark::root(),
};
let scope = match ident.ctxt.adjust(expansion) {
Some(macro_def) => self.hir.definitions().macro_def_scope(macro_def),
None => self.hir.get_module_parent(block),
};
(ident, scope)
}
}

impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
Expand Down
6 changes: 3 additions & 3 deletions src/librustc_const_eval/check_match.rs
Expand Up @@ -154,7 +154,7 @@ impl<'a, 'tcx> MatchVisitor<'a, 'tcx> {
}
}

let module = self.tcx.hir.local_def_id(self.tcx.hir.get_module_parent(scrut.id));
let module = self.tcx.hir.get_module_parent(scrut.id);
MatchCheckCtxt::create_and_enter(self.tcx, module, |ref mut cx| {
let mut have_errors = false;

Expand Down Expand Up @@ -182,7 +182,7 @@ impl<'a, 'tcx> MatchVisitor<'a, 'tcx> {
// Then, if the match has no arms, check whether the scrutinee
// is uninhabited.
let pat_ty = self.tables.node_id_to_type(scrut.id);
let module = self.tcx.hir.local_def_id(self.tcx.hir.get_module_parent(scrut.id));
let module = self.tcx.hir.get_module_parent(scrut.id);
if inlined_arms.is_empty() {
let scrutinee_is_uninhabited = if self.tcx.sess.features.borrow().never_type {
pat_ty.is_uninhabited_from(module, self.tcx)
Expand Down Expand Up @@ -231,7 +231,7 @@ impl<'a, 'tcx> MatchVisitor<'a, 'tcx> {
"local binding"
};

let module = self.tcx.hir.local_def_id(self.tcx.hir.get_module_parent(pat.id));
let module = self.tcx.hir.get_module_parent(pat.id);
MatchCheckCtxt::create_and_enter(self.tcx, module, |ref mut cx| {
let mut patcx = PatternContext::new(self.tcx, self.tables);
let pattern = patcx.lower_pattern(pat);
Expand Down

0 comments on commit bfa2ef6

Please sign in to comment.