From eb789de80379aacc987daceb937b2a80c94803ce Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Tue, 1 Dec 2015 20:38:40 +0300 Subject: [PATCH 1/2] Do MTWT resolution during lowering to HIR --- src/librustc/middle/check_match.rs | 2 +- src/librustc/middle/liveness.rs | 2 +- src/librustc/middle/pat_util.rs | 12 ++- src/librustc/middle/resolve_lifetime.rs | 2 +- src/librustc_driver/driver.rs | 13 +-- src/librustc_front/fold.rs | 2 +- src/librustc_front/hir.rs | 56 +++++++++++- src/librustc_front/intravisit.rs | 2 +- src/librustc_front/lowering.rs | 87 ++++++++++++------- src/librustc_front/util.rs | 2 +- src/librustc_lint/builtin.rs | 4 +- src/librustc_mir/hair/cx/expr.rs | 5 +- src/librustc_mir/hair/cx/pattern.rs | 3 +- src/librustc_resolve/lib.rs | 30 +++---- src/librustc_trans/trans/_match.rs | 11 ++- .../trans/debuginfo/create_scope_map.rs | 6 +- src/librustc_typeck/check/_match.rs | 3 +- 17 files changed, 156 insertions(+), 86 deletions(-) diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index a292c83682c..676257e3100 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -247,7 +247,7 @@ fn check_for_bindings_named_the_same_as_variants(cx: &MatchCheckCtxt, pat: &Pat) let def = cx.tcx.def_map.borrow().get(&p.id).map(|d| d.full_def()); if let Some(DefLocal(..)) = def { if edef.variants.iter().any(|variant| - variant.name == ident.node.name + variant.name == ident.node.unhygienic_name && variant.kind() == VariantKind::Unit ) { span_warn!(cx.tcx.sess, p.span, E0170, diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 2a8b1b83d22..5d4b4d77bbc 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -1596,7 +1596,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { self.ir.tcx.sess.add_lint(lint::builtin::UNUSED_VARIABLES, id, sp, format!("variable `{}` is assigned to, but never used", name)); - } else { + } else if name != "self" { self.ir.tcx.sess.add_lint(lint::builtin::UNUSED_VARIABLES, id, sp, format!("unused variable: `{}`", name)); } diff --git a/src/librustc/middle/pat_util.rs b/src/librustc/middle/pat_util.rs index e794ab39e54..23fd1b83e76 100644 --- a/src/librustc/middle/pat_util.rs +++ b/src/librustc/middle/pat_util.rs @@ -14,7 +14,6 @@ use middle::ty; use util::nodemap::FnvHashMap; use syntax::ast; -use syntax::ext::mtwt; use rustc_front::hir; use rustc_front::util::walk_pat; use syntax::codemap::{respan, Span, Spanned, DUMMY_SP}; @@ -27,8 +26,8 @@ pub type PatIdMap = FnvHashMap; // use the NodeId of their namesake in the first pattern. pub fn pat_id_map(dm: &RefCell, pat: &hir::Pat) -> PatIdMap { let mut map = FnvHashMap(); - pat_bindings_hygienic(dm, pat, |_bm, p_id, _s, path1| { - map.insert(mtwt::resolve(path1.node), p_id); + pat_bindings(dm, pat, |_bm, p_id, _s, path1| { + map.insert(path1.node, p_id); }); map } @@ -124,9 +123,8 @@ pub fn pat_bindings(dm: &RefCell, pat: &hir::Pat, mut it: I) where true }); } - -pub fn pat_bindings_hygienic(dm: &RefCell, pat: &hir::Pat, mut it: I) where - I: FnMut(hir::BindingMode, ast::NodeId, Span, &Spanned), +pub fn pat_bindings_ident(dm: &RefCell, pat: &hir::Pat, mut it: I) where + I: FnMut(hir::BindingMode, ast::NodeId, Span, &Spanned), { walk_pat(pat, |p| { match p.node { @@ -214,7 +212,7 @@ pub fn def_to_path(tcx: &ty::ctxt, id: DefId) -> hir::Path { tcx.with_path(id, |path| hir::Path { global: false, segments: path.last().map(|elem| hir::PathSegment { - identifier: ast::Ident::with_empty_ctxt(elem.name()), + identifier: hir::Ident::from_name(elem.name()), parameters: hir::PathParameters::none(), }).into_iter().collect(), span: DUMMY_SP, diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index 4425a24590c..b37b3070310 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -426,7 +426,7 @@ fn extract_labels<'v, 'a>(ctxt: &mut LifetimeContext<'a>, b: &'v hir::Block) { fn expression_label(ex: &hir::Expr) -> Option { match ex.node { hir::ExprWhile(_, _, Some(label)) | - hir::ExprLoop(_, Some(label)) => Some(label.name), + hir::ExprLoop(_, Some(label)) => Some(label.unhygienic_name), _ => None, } } diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index a8b2f382468..69e065b3e8f 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -112,6 +112,13 @@ pub fn compile_input(sess: Session, let mut hir_forest = time(sess.time_passes(), "lowering ast -> hir", || hir_map::Forest::new(lower_crate(&lcx, &expanded_crate))); + + // Discard MTWT tables that aren't required past lowering to HIR. + if !sess.opts.debugging_opts.keep_mtwt_tables && + !sess.opts.debugging_opts.save_analysis { + syntax::ext::mtwt::clear_tables(); + } + let arenas = ty::CtxtArenas::new(); let ast_map = make_map(&sess, &mut hir_forest); @@ -704,12 +711,6 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session, "resolution", || resolve::resolve_crate(sess, &ast_map, make_glob_map)); - // Discard MTWT tables that aren't required past resolution. - // FIXME: get rid of uses of MTWT tables in typeck, mir and trans and clear them - if !sess.opts.debugging_opts.keep_mtwt_tables { - // syntax::ext::mtwt::clear_tables(); - } - let named_region_map = time(time_passes, "lifetime resolution", || middle::resolve_lifetime::krate(sess, krate, &def_map.borrow())); diff --git a/src/librustc_front/fold.rs b/src/librustc_front/fold.rs index 5f39376d156..4f580c770f0 100644 --- a/src/librustc_front/fold.rs +++ b/src/librustc_front/fold.rs @@ -12,7 +12,7 @@ //! and returns a piece of the same type. use hir::*; -use syntax::ast::{Ident, Name, NodeId, DUMMY_NODE_ID, Attribute, Attribute_, MetaItem}; +use syntax::ast::{Name, NodeId, DUMMY_NODE_ID, Attribute, Attribute_, MetaItem}; use syntax::ast::{MetaWord, MetaList, MetaNameValue}; use syntax::attr::ThinAttributesExt; use hir; diff --git a/src/librustc_front/hir.rs b/src/librustc_front/hir.rs index beb7059d73c..dd4d7e28444 100644 --- a/src/librustc_front/hir.rs +++ b/src/librustc_front/hir.rs @@ -39,7 +39,7 @@ use intravisit::Visitor; use std::collections::BTreeMap; use syntax::codemap::{self, Span, Spanned, DUMMY_SP, ExpnId}; use syntax::abi::Abi; -use syntax::ast::{Name, Ident, NodeId, DUMMY_NODE_ID, TokenTree, AsmDialect}; +use syntax::ast::{Name, NodeId, DUMMY_NODE_ID, TokenTree, AsmDialect}; use syntax::ast::{Attribute, Lit, StrStyle, FloatTy, IntTy, UintTy, CrateConfig}; use syntax::attr::ThinAttributes; use syntax::owned_slice::OwnedSlice; @@ -50,7 +50,59 @@ use print::pprust; use util; use std::fmt; -use serialize::{Encodable, Encoder, Decoder}; +use std::hash::{Hash, Hasher}; +use serialize::{Encodable, Decodable, Encoder, Decoder}; + +/// Identifier in HIR +#[derive(Clone, Copy, Eq)] +pub struct Ident { + /// Hygienic name (renamed), should be used by default + pub name: Name, + /// Unhygienic name (original, not renamed), needed in few places in name resolution + pub unhygienic_name: Name, +} + +impl Ident { + pub fn from_name(name: Name) -> Ident { + Ident { name: name, unhygienic_name: name } + } +} + +impl PartialEq for Ident { + fn eq(&self, other: &Ident) -> bool { + self.name == other.name + } +} + +impl Hash for Ident { + fn hash(&self, state: &mut H) { + self.name.hash(state) + } +} + +impl fmt::Debug for Ident { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Debug::fmt(&self.name, f) + } +} + +impl fmt::Display for Ident { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Display::fmt(&self.name, f) + } +} + +impl Encodable for Ident { + fn encode(&self, s: &mut S) -> Result<(), S::Error> { + self.name.encode(s) + } +} + +impl Decodable for Ident { + fn decode(d: &mut D) -> Result { + Ok(Ident::from_name(try!(Name::decode(d)))) + } +} #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)] pub struct Lifetime { diff --git a/src/librustc_front/intravisit.rs b/src/librustc_front/intravisit.rs index 3a43feb8ba7..e93f5cbd0fb 100644 --- a/src/librustc_front/intravisit.rs +++ b/src/librustc_front/intravisit.rs @@ -26,7 +26,7 @@ //! property. use syntax::abi::Abi; -use syntax::ast::{Ident, NodeId, CRATE_NODE_ID, Name, Attribute}; +use syntax::ast::{NodeId, CRATE_NODE_ID, Name, Attribute}; use syntax::codemap::Span; use hir::*; diff --git a/src/librustc_front/lowering.rs b/src/librustc_front/lowering.rs index e8c4a6484e2..62ed8b0416a 100644 --- a/src/librustc_front/lowering.rs +++ b/src/librustc_front/lowering.rs @@ -67,10 +67,11 @@ use std::collections::BTreeMap; use std::collections::HashMap; use syntax::ast::*; use syntax::attr::{ThinAttributes, ThinAttributesExt}; +use syntax::ext::mtwt; use syntax::ptr::P; use syntax::codemap::{respan, Spanned, Span}; use syntax::owned_slice::OwnedSlice; -use syntax::parse::token::{self, str_to_ident}; +use syntax::parse::token; use syntax::std_inject; use syntax::visit::{self, Visitor}; @@ -86,7 +87,7 @@ pub struct LoweringContext<'a> { // incrementing. cached_id: Cell, // Keep track of gensym'ed idents. - gensym_cache: RefCell>, + gensym_cache: RefCell>, // A copy of cached_id, but is also set to an id while it is being cached. gensym_key: Cell, } @@ -123,23 +124,30 @@ impl<'a, 'hir> LoweringContext<'a> { cached } - fn str_to_ident(&self, s: &'static str) -> Ident { + fn str_to_ident(&self, s: &'static str) -> hir::Ident { let cached_id = self.gensym_key.get(); if cached_id == 0 { - return token::gensym_ident(s); + return hir::Ident::from_name(token::gensym(s)); } let cached = self.gensym_cache.borrow().contains_key(&(cached_id, s)); if cached { self.gensym_cache.borrow()[&(cached_id, s)] } else { - let result = token::gensym_ident(s); + let result = hir::Ident::from_name(token::gensym(s)); self.gensym_cache.borrow_mut().insert((cached_id, s), result); result } } } +pub fn lower_ident(_lctx: &LoweringContext, ident: Ident) -> hir::Ident { + hir::Ident { + name: mtwt::resolve(ident), + unhygienic_name: ident.name, + } +} + pub fn lower_view_path(lctx: &LoweringContext, view_path: &ViewPath) -> P { P(Spanned { node: match view_path.node { @@ -276,14 +284,22 @@ pub fn lower_variant(lctx: &LoweringContext, v: &Variant) -> P { }) } -pub fn lower_path(lctx: &LoweringContext, p: &Path) -> hir::Path { +// Path segments are usually unhygienic, hygienic path segments can occur only in +// identifier-like paths originating from `ExprPath`. +// Make life simpler for rustc_resolve by renaming only such segments. +pub fn lower_path_full(lctx: &LoweringContext, p: &Path, maybe_hygienic: bool) -> hir::Path { + let maybe_hygienic = maybe_hygienic && !p.global && p.segments.len() == 1; hir::Path { global: p.global, segments: p.segments .iter() .map(|&PathSegment { identifier, ref parameters }| { hir::PathSegment { - identifier: identifier, + identifier: if maybe_hygienic { + lower_ident(lctx, identifier) + } else { + hir::Ident::from_name(identifier.name) + }, parameters: lower_path_parameters(lctx, parameters), } }) @@ -292,6 +308,10 @@ pub fn lower_path(lctx: &LoweringContext, p: &Path) -> hir::Path { } } +pub fn lower_path(lctx: &LoweringContext, p: &Path) -> hir::Path { + lower_path_full(lctx, p, false) +} + pub fn lower_path_parameters(lctx: &LoweringContext, path_parameters: &PathParameters) -> hir::PathParameters { @@ -844,7 +864,7 @@ pub fn lower_pat(lctx: &LoweringContext, p: &Pat) -> P { PatWild => hir::PatWild, PatIdent(ref binding_mode, pth1, ref sub) => { hir::PatIdent(lower_binding_mode(lctx, binding_mode), - pth1, + respan(pth1.span, lower_ident(lctx, pth1.node)), sub.as_ref().map(|x| lower_pat(lctx, x))) } PatLit(ref e) => hir::PatLit(lower_expr(lctx, e)), @@ -1138,10 +1158,12 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P { hir::ExprIf(lower_expr(lctx, cond), lower_block(lctx, blk), else_opt) } ExprWhile(ref cond, ref body, opt_ident) => { - hir::ExprWhile(lower_expr(lctx, cond), lower_block(lctx, body), opt_ident) + hir::ExprWhile(lower_expr(lctx, cond), lower_block(lctx, body), + opt_ident.map(|ident| lower_ident(lctx, ident))) } ExprLoop(ref body, opt_ident) => { - hir::ExprLoop(lower_block(lctx, body), opt_ident) + hir::ExprLoop(lower_block(lctx, body), + opt_ident.map(|ident| lower_ident(lctx, ident))) } ExprMatch(ref expr, ref arms) => { hir::ExprMatch(lower_expr(lctx, expr), @@ -1176,16 +1198,20 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P { e2.as_ref().map(|x| lower_expr(lctx, x))) } ExprPath(ref qself, ref path) => { - let qself = qself.as_ref().map(|&QSelf { ref ty, position }| { + let hir_qself = qself.as_ref().map(|&QSelf { ref ty, position }| { hir::QSelf { ty: lower_ty(lctx, ty), position: position, } }); - hir::ExprPath(qself, lower_path(lctx, path)) + hir::ExprPath(hir_qself, lower_path_full(lctx, path, qself.is_none())) } - ExprBreak(opt_ident) => hir::ExprBreak(opt_ident), - ExprAgain(opt_ident) => hir::ExprAgain(opt_ident), + ExprBreak(opt_ident) => hir::ExprBreak(opt_ident.map(|sp_ident| { + respan(sp_ident.span, lower_ident(lctx, sp_ident.node)) + })), + ExprAgain(opt_ident) => hir::ExprAgain(opt_ident.map(|sp_ident| { + respan(sp_ident.span, lower_ident(lctx, sp_ident.node)) + })), ExprRet(ref e) => hir::ExprRet(e.as_ref().map(|x| lower_expr(lctx, x))), ExprInlineAsm(InlineAsm { ref inputs, @@ -1356,8 +1382,10 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P { // `[opt_ident]: loop { ... }` let loop_block = block_expr(lctx, match_expr); + let loop_expr = hir::ExprLoop(loop_block, + opt_ident.map(|ident| lower_ident(lctx, ident))); // add attributes to the outer returned expr node - expr(lctx, e.span, hir::ExprLoop(loop_block, opt_ident), e.attrs.clone()) + expr(lctx, e.span, loop_expr, e.attrs.clone()) }); } @@ -1434,10 +1462,9 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P { // `[opt_ident]: loop { ... }` let loop_block = block_expr(lctx, match_expr); - let loop_expr = expr(lctx, - e.span, - hir::ExprLoop(loop_block, opt_ident), - None); + let loop_expr = hir::ExprLoop(loop_block, + opt_ident.map(|ident| lower_ident(lctx, ident))); + let loop_expr = expr(lctx, e.span, loop_expr, None); // `mut iter => { ... }` let iter_arm = { @@ -1593,7 +1620,7 @@ fn expr_call(lctx: &LoweringContext, expr(lctx, span, hir::ExprCall(e, args), attrs) } -fn expr_ident(lctx: &LoweringContext, span: Span, id: Ident, +fn expr_ident(lctx: &LoweringContext, span: Span, id: hir::Ident, attrs: ThinAttributes) -> P { expr_path(lctx, path_ident(span, id), attrs) } @@ -1641,7 +1668,7 @@ fn expr(lctx: &LoweringContext, span: Span, node: hir::Expr_, fn stmt_let(lctx: &LoweringContext, sp: Span, mutbl: bool, - ident: Ident, + ident: hir::Ident, ex: P, attrs: ThinAttributes) -> P { @@ -1701,13 +1728,13 @@ fn pat_enum(lctx: &LoweringContext, pat(lctx, span, pt) } -fn pat_ident(lctx: &LoweringContext, span: Span, ident: Ident) -> P { +fn pat_ident(lctx: &LoweringContext, span: Span, ident: hir::Ident) -> P { pat_ident_binding_mode(lctx, span, ident, hir::BindByValue(hir::MutImmutable)) } fn pat_ident_binding_mode(lctx: &LoweringContext, span: Span, - ident: Ident, + ident: hir::Ident, bm: hir::BindingMode) -> P { let pat_ident = hir::PatIdent(bm, @@ -1731,21 +1758,21 @@ fn pat(lctx: &LoweringContext, span: Span, pat: hir::Pat_) -> P { }) } -fn path_ident(span: Span, id: Ident) -> hir::Path { +fn path_ident(span: Span, id: hir::Ident) -> hir::Path { path(span, vec![id]) } -fn path(span: Span, strs: Vec) -> hir::Path { +fn path(span: Span, strs: Vec) -> hir::Path { path_all(span, false, strs, Vec::new(), Vec::new(), Vec::new()) } -fn path_global(span: Span, strs: Vec) -> hir::Path { +fn path_global(span: Span, strs: Vec) -> hir::Path { path_all(span, true, strs, Vec::new(), Vec::new(), Vec::new()) } fn path_all(sp: Span, global: bool, - mut idents: Vec, + mut idents: Vec, lifetimes: Vec, types: Vec>, bindings: Vec>) @@ -1774,12 +1801,12 @@ fn path_all(sp: Span, } } -fn std_path(lctx: &LoweringContext, components: &[&str]) -> Vec { +fn std_path(lctx: &LoweringContext, components: &[&str]) -> Vec { let mut v = Vec::new(); if let Some(s) = lctx.crate_root { - v.push(str_to_ident(s)); + v.push(hir::Ident::from_name(token::intern(s))); } - v.extend(components.iter().map(|s| str_to_ident(s))); + v.extend(components.iter().map(|s| hir::Ident::from_name(token::intern(s)))); return v; } diff --git a/src/librustc_front/util.rs b/src/librustc_front/util.rs index 97b25dafb6d..4dc08f7a048 100644 --- a/src/librustc_front/util.rs +++ b/src/librustc_front/util.rs @@ -12,7 +12,7 @@ use hir; use hir::*; use intravisit::{self, Visitor, FnKind}; use syntax::ast_util; -use syntax::ast::{Ident, Name, NodeId, DUMMY_NODE_ID}; +use syntax::ast::{Name, NodeId, DUMMY_NODE_ID}; use syntax::codemap::Span; use syntax::ptr::P; use syntax::owned_slice::OwnedSlice; diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 739c5f12ecb..90d9bcfffee 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -170,9 +170,7 @@ impl LateLintPass for NonShorthandFieldPatterns { }); for fieldpat in field_pats { if let hir::PatIdent(_, ident, None) = fieldpat.node.pat.node { - if ident.node.name == fieldpat.node.name { - // FIXME: should this comparison really be done on the name? - // doing it on the ident will fail during compilation of libcore + if ident.node.unhygienic_name == fieldpat.node.name { cx.span_lint(NON_SHORTHAND_FIELD_PATTERNS, fieldpat.span, &format!("the `{}:` in this pattern is redundant and can \ be removed", ident.node)) diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index 24091d7dc37..08826013ebc 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -21,7 +21,6 @@ use rustc::middle::ty::{self, VariantDef, Ty}; use rustc::mir::repr::*; use rustc_front::hir; use rustc_front::util as hir_util; -use syntax::ext::mtwt; use syntax::parse::token; use syntax::ptr::P; @@ -500,8 +499,8 @@ fn convert_arm<'a, 'tcx: 'a>(cx: &mut Cx<'a, 'tcx>, arm: &'tcx hir::Arm) -> Arm< None } else { map = FnvHashMap(); - pat_util::pat_bindings_hygienic(&cx.tcx.def_map, &arm.pats[0], |_, p_id, _, path| { - map.insert(mtwt::resolve(path.node), p_id); + pat_util::pat_bindings(&cx.tcx.def_map, &arm.pats[0], |_, p_id, _, path| { + map.insert(path.node, p_id); }); Some(&map) }; diff --git a/src/librustc_mir/hair/cx/pattern.rs b/src/librustc_mir/hair/cx/pattern.rs index bea7950c33a..74fef684006 100644 --- a/src/librustc_mir/hair/cx/pattern.rs +++ b/src/librustc_mir/hair/cx/pattern.rs @@ -19,7 +19,6 @@ use rustc::middle::ty::{self, Ty}; use rustc::mir::repr::*; use rustc_front::hir; use syntax::ast; -use syntax::ext::mtwt; use syntax::ptr::P; /// When there are multiple patterns in a single arm, each one has its @@ -162,7 +161,7 @@ impl<'patcx, 'cx, 'tcx> PatCx<'patcx, 'cx, 'tcx> { { let id = match self.binding_map { None => pat.id, - Some(ref map) => map[&mtwt::resolve(ident.node)], + Some(ref map) => map[&ident.node.name], }; let var_ty = self.cx.tcx.node_id_to_type(pat.id); let region = match var_ty.sty { diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 361047df3e6..d15b3a0ccf7 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -57,7 +57,7 @@ use rustc::lint; use rustc::middle::cstore::{CrateStore, DefLike, DlDef}; use rustc::middle::def::*; use rustc::middle::def_id::DefId; -use rustc::middle::pat_util::pat_bindings_hygienic; +use rustc::middle::pat_util::pat_bindings; use rustc::middle::privacy::*; use rustc::middle::subst::{ParamSpace, FnSpace, TypeSpace}; use rustc::middle::ty::{Freevar, FreevarMap, TraitMap, GlobMap}; @@ -67,7 +67,6 @@ use syntax::ast; use syntax::ast::{CRATE_NODE_ID, Ident, Name, NodeId, CrateNum, TyIs, TyI8, TyI16, TyI32, TyI64}; use syntax::ast::{TyUs, TyU8, TyU16, TyU32, TyU64, TyF64, TyF32}; use syntax::attr::AttrMetaMethods; -use syntax::ext::mtwt; use syntax::parse::token::{self, special_names, special_idents}; use syntax::ptr::P; use syntax::codemap::{self, Span, Pos}; @@ -2315,8 +2314,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // user and one 'x' came from the macro. fn binding_mode_map(&mut self, pat: &Pat) -> BindingMap { let mut result = HashMap::new(); - pat_bindings_hygienic(&self.def_map, pat, |binding_mode, _id, sp, path1| { - let name = mtwt::resolve(path1.node); + pat_bindings(&self.def_map, pat, |binding_mode, _id, sp, path1| { + let name = path1.node; result.insert(name, BindingInfo { span: sp, @@ -2520,9 +2519,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let const_ok = mode == RefutableMode && at_rhs.is_none(); let ident = path1.node; - let renamed = mtwt::resolve(ident); + let renamed = ident.name; - match self.resolve_bare_identifier_pattern(ident.name, pattern.span) { + match self.resolve_bare_identifier_pattern(ident.unhygienic_name, + pattern.span) { FoundStructOrEnumVariant(def, lp) if const_ok => { debug!("(resolving pattern) resolving `{}` to struct or enum variant", renamed); @@ -2911,7 +2911,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // Resolve a single identifier fn resolve_identifier(&mut self, - identifier: Ident, + identifier: hir::Ident, namespace: Namespace, check_ribs: bool) -> Option { @@ -2919,7 +2919,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { if namespace == TypeNS { if let Some(&prim_ty) = self.primitive_type_table .primitive_types - .get(&identifier.name) { + .get(&identifier.unhygienic_name) { return Some(LocalDef::from_def(DefPrimTy(prim_ty))); } } @@ -2930,7 +2930,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } } - self.resolve_item_by_name_in_lexical_scope(identifier.name, namespace) + self.resolve_item_by_name_in_lexical_scope(identifier.unhygienic_name, namespace) .map(LocalDef::from_def) } @@ -3144,13 +3144,13 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } fn resolve_identifier_in_local_ribs(&mut self, - ident: Ident, + ident: hir::Ident, namespace: Namespace) -> Option { // Check the local set of ribs. let (name, ribs) = match namespace { - ValueNS => (mtwt::resolve(ident), &self.value_ribs), - TypeNS => (ident.name, &self.type_ribs), + ValueNS => (ident.name, &self.value_ribs), + TypeNS => (ident.unhygienic_name, &self.type_ribs), }; for (i, rib) in ribs.iter().enumerate().rev() { @@ -3551,8 +3551,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { { let rib = this.label_ribs.last_mut().unwrap(); - let renamed = mtwt::resolve(label); - rib.bindings.insert(renamed, def_like); + rib.bindings.insert(label.name, def_like); } intravisit::walk_expr(this, expr); @@ -3560,8 +3559,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } ExprBreak(Some(label)) | ExprAgain(Some(label)) => { - let renamed = mtwt::resolve(label.node); - match self.search_label(renamed) { + match self.search_label(label.node.name) { None => { resolve_error(self, label.span, diff --git a/src/librustc_trans/trans/_match.rs b/src/librustc_trans/trans/_match.rs index b2e989bc874..b5d8fd71f74 100644 --- a/src/librustc_trans/trans/_match.rs +++ b/src/librustc_trans/trans/_match.rs @@ -228,7 +228,6 @@ use std::fmt; use std::rc::Rc; use rustc_front::hir; use syntax::ast::{self, DUMMY_NODE_ID, NodeId}; -use syntax::ext::mtwt; use syntax::codemap::Span; use rustc_front::fold::Folder; use syntax::ptr::P; @@ -478,7 +477,7 @@ fn expand_nested_bindings<'a, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>, loop { pat = match pat.node { hir::PatIdent(_, ref path, Some(ref inner)) => { - bound_ptrs.push((mtwt::resolve(path.node), val.val)); + bound_ptrs.push((path.node.name, val.val)); &**inner }, _ => break @@ -519,7 +518,7 @@ fn enter_match<'a, 'b, 'p, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>, match this.node { hir::PatIdent(_, ref path, None) => { if pat_is_binding(&dm.borrow(), &*this) { - bound_ptrs.push((mtwt::resolve(path.node), val.val)); + bound_ptrs.push((path.node.name, val.val)); } } hir::PatVec(ref before, Some(ref slice), ref after) => { @@ -527,7 +526,7 @@ fn enter_match<'a, 'b, 'p, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>, let subslice_val = bind_subslice_pat( bcx, this.id, val, before.len(), after.len()); - bound_ptrs.push((mtwt::resolve(path.node), subslice_val)); + bound_ptrs.push((path.node.name, subslice_val)); } } _ => {} @@ -1527,8 +1526,8 @@ fn create_bindings_map<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, pat: &hir::Pat, let tcx = bcx.tcx(); let reassigned = is_discr_reassigned(bcx, discr, body); let mut bindings_map = FnvHashMap(); - pat_bindings_hygienic(&tcx.def_map, &*pat, |bm, p_id, span, path1| { - let name = mtwt::resolve(path1.node); + pat_bindings(&tcx.def_map, &*pat, |bm, p_id, span, path1| { + let name = path1.node; let variable_ty = node_id_type(bcx, p_id); let llvariable_ty = type_of::type_of(ccx, variable_ty); let tcx = bcx.tcx(); diff --git a/src/librustc_trans/trans/debuginfo/create_scope_map.rs b/src/librustc_trans/trans/debuginfo/create_scope_map.rs index 0c424de9e10..d9080b8ae90 100644 --- a/src/librustc_trans/trans/debuginfo/create_scope_map.rs +++ b/src/librustc_trans/trans/debuginfo/create_scope_map.rs @@ -47,9 +47,9 @@ pub fn create_scope_map(cx: &CrateContext, // Push argument identifiers onto the stack so arguments integrate nicely // with variable shadowing. for arg in args { - pat_util::pat_bindings(def_map, &*arg.pat, |_, node_id, _, path1| { + pat_util::pat_bindings_ident(def_map, &*arg.pat, |_, node_id, _, path1| { scope_stack.push(ScopeStackEntry { scope_metadata: fn_metadata, - name: Some(path1.node) }); + name: Some(path1.node.unhygienic_name) }); scope_map.insert(node_id, fn_metadata); }) } @@ -169,7 +169,7 @@ fn walk_pattern(cx: &CrateContext, // scope stack and maybe introduce an artificial scope if pat_util::pat_is_binding(&def_map.borrow(), &*pat) { - let name = path1.node.name; + let name = path1.node.unhygienic_name; // LLVM does not properly generate 'DW_AT_start_scope' fields // for variable DIEs. For this reason we have to introduce diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index 1a3812147d8..b17790ac061 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -26,7 +26,6 @@ use session::Session; use std::cmp; use std::collections::hash_map::Entry::{Occupied, Vacant}; use syntax::ast; -use syntax::ext::mtwt; use syntax::codemap::{Span, Spanned}; use syntax::ptr::P; @@ -187,7 +186,7 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>, // if there are multiple arms, make sure they all agree on // what the type of the binding `x` ought to be - let canon_id = *pcx.map.get(&mtwt::resolve(path.node)).unwrap(); + let canon_id = *pcx.map.get(&path.node.name).unwrap(); if canon_id != pat.id { let ct = fcx.local_ty(pat.span, canon_id); demand::eqtype(fcx, pat.span, ct, typ); From c1d3164700e76323e30cdf5c84af50c2ca46ff75 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Mon, 7 Dec 2015 20:19:36 +0300 Subject: [PATCH 2/2] Add comments for Ident::from_name and identifiers in path segments --- src/librustc_front/hir.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/librustc_front/hir.rs b/src/librustc_front/hir.rs index dd4d7e28444..3f2bb87724d 100644 --- a/src/librustc_front/hir.rs +++ b/src/librustc_front/hir.rs @@ -63,6 +63,12 @@ pub struct Ident { } impl Ident { + /// Creates a HIR identifier with both `name` and `unhygienic_name` initialized with + /// the argument. Hygiene properties of the created identifier depend entirely on this + /// argument. If the argument is a plain interned string `intern("iter")`, then the result + /// is unhygienic and can interfere with other entities named "iter". If the argument is + /// a "fresh" name created with `gensym("iter")`, then the result is hygienic and can't + /// interfere with other entities having the same string as a name. pub fn from_name(name: Name) -> Ident { Ident { name: name, unhygienic_name: name } } @@ -157,6 +163,14 @@ impl fmt::Display for Path { #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub struct PathSegment { /// The identifier portion of this path segment. + /// + /// Hygiene properties of this identifier are worth noting. + /// Most path segments are not hygienic and they are not renamed during + /// lowering from AST to HIR (see comments to `fn lower_path`). However segments from + /// unqualified paths with one segment originating from `ExprPath` (local-variable-like paths) + /// can be hygienic, so they are renamed. You should not normally care about this peculiarity + /// and just use `identifier.name` unless you modify identifier resolution code + /// (`fn resolve_identifier` and other functions called by it in `rustc_resolve`). pub identifier: Ident, /// Type/lifetime parameters attached to this path. They come in