diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 30296cb318617af1fdc0a544374596a44e5a37c8..3e7c491252745e4f86fc205fed12df1146827d4e 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -902,12 +902,10 @@ fn get_lints(&self) -> LintArray { fn check_pat(&mut self, cx: &Context, p: &ast::Pat) { // Lint for constants that look like binding identifiers (#7526) match (&p.node, cx.tcx.def_map.borrow().find(&p.id)) { - (&ast::PatIdent(_, ref path, _), Some(&def::DefStatic(_, false))) => { - // last identifier alone is right choice for this lint. - let ident = path.segments.last().unwrap().identifier; - let s = token::get_ident(ident); + (&ast::PatIdent(_, ref path1, _), Some(&def::DefStatic(_, false))) => { + let s = token::get_ident(path1.node); if s.get().chars().any(|c| c.is_lowercase()) { - cx.span_lint(NON_UPPERCASE_PATTERN_STATICS, path.span, + cx.span_lint(NON_UPPERCASE_PATTERN_STATICS, path1.span, format!("static constant in pattern `{}` should have an uppercase \ name such as `{}`", s.get(), s.get().chars().map(|c| c.to_uppercase()) @@ -931,15 +929,13 @@ fn get_lints(&self) -> LintArray { fn check_pat(&mut self, cx: &Context, p: &ast::Pat) { match &p.node { - &ast::PatIdent(_, ref path, _) => { + &ast::PatIdent(_, ref path1, _) => { match cx.tcx.def_map.borrow().find(&p.id) { Some(&def::DefLocal(_, _)) | Some(&def::DefBinding(_, _)) | Some(&def::DefArg(_, _)) => { - // last identifier alone is right choice for this lint. - let ident = path.segments.last().unwrap().identifier; - let s = token::get_ident(ident); + let s = token::get_ident(path1.node); if s.get().len() > 0 && s.get().char_at(0).is_uppercase() { - cx.span_lint(UPPERCASE_VARIABLES, path.span, + cx.span_lint(UPPERCASE_VARIABLES, path1.span, "variable names should start with \ a lowercase character"); } @@ -1113,15 +1109,10 @@ fn check_unused_mut_pat(&self, cx: &Context, pats: &[Gc]) { // avoid false warnings in match arms with multiple patterns let mut mutables = HashMap::new(); for &p in pats.iter() { - pat_util::pat_bindings(&cx.tcx.def_map, &*p, |mode, id, _, path| { + pat_util::pat_bindings(&cx.tcx.def_map, &*p, |mode, id, _, path1| { + let ident = path1.node; match mode { ast::BindByValue(ast::MutMutable) => { - if path.segments.len() != 1 { - cx.sess().span_bug(p.span, - "mutable binding that doesn't consist \ - of exactly one segment"); - } - let ident = path.segments.get(0).identifier; if !token::get_ident(ident).get().starts_with("_") { mutables.insert_or_update_with(ident.name as uint, vec!(id), |_, old| { old.push(id); }); diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index 96284f8de261a78254f0faa3ff837c660049cf2b..6eb7c5a4310e6f9cb61abc55001000ae275839cc 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -809,9 +809,8 @@ fn encode_method_argument_names(ebml_w: &mut Encoder, for arg in decl.inputs.iter() { ebml_w.start_tag(tag_method_argument_name); match arg.pat.node { - ast::PatIdent(_, ref name, _) => { - let name = name.segments.last().unwrap().identifier; - let name = token::get_ident(name); + ast::PatIdent(_, ref path1, _) => { + let name = token::get_ident(path1.node); ebml_w.writer.write(name.get().as_bytes()); } _ => {} @@ -1106,8 +1105,9 @@ fn add_to_index(item: &Item, ebml_w: &Encoder, match ty.node { ast::TyPath(ref path, ref bounds, _) if path.segments .len() == 1 => { + let ident = path.segments.last().unwrap().identifier; assert!(bounds.is_none()); - encode_impl_type_basename(ebml_w, ast_util::path_to_ident(path)); + encode_impl_type_basename(ebml_w, ident); } _ => {} } diff --git a/src/librustc/middle/borrowck/gather_loans/gather_moves.rs b/src/librustc/middle/borrowck/gather_loans/gather_moves.rs index 6df474809779ac37cd62eebe2b80a6c86f002b7b..de77fa602c9b406a0bf85a4e8c58b04bb72b7975 100644 --- a/src/librustc/middle/borrowck/gather_loans/gather_moves.rs +++ b/src/librustc/middle/borrowck/gather_loans/gather_moves.rs @@ -66,9 +66,9 @@ pub fn gather_move_from_pat(bccx: &BorrowckCtxt, move_pat: &ast::Pat, cmt: mc::cmt) { let pat_span_path_opt = match move_pat.node { - ast::PatIdent(_, ref path, _) => { - Some(MoveSpanAndPath::with_span_and_path(move_pat.span, - (*path).clone())) + ast::PatIdent(_, ref path1, _) => { + Some(MoveSpanAndPath{span: move_pat.span, + ident: path1.node}) }, _ => None, }; diff --git a/src/librustc/middle/borrowck/gather_loans/move_error.rs b/src/librustc/middle/borrowck/gather_loans/move_error.rs index 925244849bc8ab408f340242155d4c9f3812a742..f5c91f7b1b3bf4441e664ff0fd479486864b6d22 100644 --- a/src/librustc/middle/borrowck/gather_loans/move_error.rs +++ b/src/librustc/middle/borrowck/gather_loans/move_error.rs @@ -56,19 +56,8 @@ pub fn with_move_info(move_from: mc::cmt, #[deriving(Clone)] pub struct MoveSpanAndPath { - span: codemap::Span, - path: ast::Path -} - -impl MoveSpanAndPath { - pub fn with_span_and_path(span: codemap::Span, - path: ast::Path) - -> MoveSpanAndPath { - MoveSpanAndPath { - span: span, - path: path, - } - } + pub span: codemap::Span, + pub ident: ast::Ident } pub struct GroupedMoveErrors { @@ -83,7 +72,7 @@ fn report_move_errors(bccx: &BorrowckCtxt, errors: &Vec) { let mut is_first_note = true; for move_to in error.move_to_places.iter() { note_move_destination(bccx, move_to.span, - &move_to.path, is_first_note); + &move_to.ident, is_first_note); is_first_note = false; } } @@ -154,9 +143,9 @@ fn report_cannot_move_out_of(bccx: &BorrowckCtxt, move_from: mc::cmt) { fn note_move_destination(bccx: &BorrowckCtxt, move_to_span: codemap::Span, - pat_ident_path: &ast::Path, + pat_ident: &ast::Ident, is_first_note: bool) { - let pat_name = pprust::path_to_str(pat_ident_path); + let pat_name = pprust::ident_to_str(pat_ident); if is_first_note { bccx.span_note( move_to_span, diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index e7457f370d9adea16253276cb4fa5bc0b9224758..70db3e964abb3273cc2f4d078a3c809b1c7fdad0 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -247,6 +247,10 @@ fn visit_pat(&mut self, pat: &ast::Pat, ctxt: MarkSymbolVisitorContext) { ast::PatStruct(_, ref fields, _) => { self.handle_field_pattern_match(pat, fields.as_slice()); } + ast::PatIdent(_, _, _) => { + // it might be the only use of a static: + self.lookup_and_handle_definition(&pat.id) + } _ => () } diff --git a/src/librustc/middle/kind.rs b/src/librustc/middle/kind.rs index 34754f045ffce8b00ecc1d677d3c2df6b6d536b5..8163331667198a8b48035291d786c7c44a3cd93b 100644 --- a/src/librustc/middle/kind.rs +++ b/src/librustc/middle/kind.rs @@ -20,7 +20,7 @@ use syntax::ast::*; use syntax::attr; use syntax::codemap::Span; -use syntax::print::pprust::{expr_to_str,path_to_str}; +use syntax::print::pprust::{expr_to_str, ident_to_str}; use syntax::{visit}; use syntax::visit::Visitor; @@ -627,7 +627,7 @@ fn check_sized(tcx: &ty::ctxt, ty: ty::t, name: String, sp: Span) { fn check_pat(cx: &mut Context, pat: &Pat) { let var_name = match pat.node { PatWild => Some("_".to_string()), - PatIdent(_, ref path, _) => Some(path_to_str(path).to_string()), + PatIdent(_, ref path1, _) => Some(ident_to_str(&path1.node).to_string()), _ => None }; diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 5c09466cd96820bdfb686760caf70ba973302ba7..d48f7f541f0da016d1c85cfe980a529656c89031 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -367,9 +367,9 @@ fn visit_fn(ir: &mut IrMaps, for arg in decl.inputs.iter() { pat_util::pat_bindings(&ir.tcx.def_map, &*arg.pat, - |_bm, arg_id, _x, path| { + |_bm, arg_id, _x, path1| { debug!("adding argument {}", arg_id); - let ident = ast_util::path_to_ident(path); + let ident = path1.node; fn_maps.add_variable(Arg(arg_id, ident)); }) }; @@ -399,9 +399,9 @@ fn visit_fn(ir: &mut IrMaps, } fn visit_local(ir: &mut IrMaps, local: &Local) { - pat_util::pat_bindings(&ir.tcx.def_map, &*local.pat, |_, p_id, sp, path| { + pat_util::pat_bindings(&ir.tcx.def_map, &*local.pat, |_, p_id, sp, path1| { debug!("adding local variable {}", p_id); - let name = ast_util::path_to_ident(path); + let name = path1.node; ir.add_live_node_for_node(p_id, VarDefNode(sp)); ir.add_variable(Local(LocalInfo { id: p_id, @@ -413,10 +413,10 @@ fn visit_local(ir: &mut IrMaps, local: &Local) { fn visit_arm(ir: &mut IrMaps, arm: &Arm) { for pat in arm.pats.iter() { - pat_util::pat_bindings(&ir.tcx.def_map, &**pat, |bm, p_id, sp, path| { + pat_util::pat_bindings(&ir.tcx.def_map, &**pat, |bm, p_id, sp, path1| { debug!("adding local variable {} from match with bm {:?}", p_id, bm); - let name = ast_util::path_to_ident(path); + let name = path1.node; ir.add_live_node_for_node(p_id, VarDefNode(sp)); ir.add_variable(Local(LocalInfo { id: p_id, @@ -1522,10 +1522,10 @@ fn warn_about_unused_args(&self, decl: &FnDecl, entry_ln: LiveNode) { for arg in decl.inputs.iter() { pat_util::pat_bindings(&self.ir.tcx.def_map, &*arg.pat, - |_bm, p_id, sp, path| { + |_bm, p_id, sp, path1| { let var = self.variable(p_id, sp); // Ignore unused self. - let ident = ast_util::path_to_ident(path); + let ident = path1.node; if ident.name != special_idents::self_.name { self.warn_about_unused(sp, p_id, entry_ln, var); } diff --git a/src/librustc/middle/pat_util.rs b/src/librustc/middle/pat_util.rs index 24d97f5aac354212171f61b1110cae7506c0fb96..2d53d742ee44b15800ed580c6f375f65b1e87a24 100644 --- a/src/librustc/middle/pat_util.rs +++ b/src/librustc/middle/pat_util.rs @@ -14,7 +14,7 @@ use std::collections::HashMap; use std::gc::{Gc, GC}; use syntax::ast::*; -use syntax::ast_util::{path_to_ident, walk_pat}; +use syntax::ast_util::{walk_pat}; use syntax::codemap::{Span, DUMMY_SP}; pub type PatIdMap = HashMap; @@ -23,8 +23,8 @@ // use the NodeId of their namesake in the first pattern. pub fn pat_id_map(dm: &resolve::DefMap, pat: &Pat) -> PatIdMap { let mut map = HashMap::new(); - pat_bindings(dm, pat, |_bm, p_id, _s, n| { - map.insert(path_to_ident(n), p_id); + pat_bindings(dm, pat, |_bm, p_id, _s, path1| { + map.insert(path1.node, p_id); }); map } @@ -75,7 +75,7 @@ pub fn pat_is_binding_or_wild(dm: &resolve::DefMap, pat: &Pat) -> bool { /// `match foo() { Some(a) => (), None => () }` pub fn pat_bindings(dm: &resolve::DefMap, pat: &Pat, - it: |BindingMode, NodeId, Span, &Path|) { + it: |BindingMode, NodeId, Span, &SpannedIdent|) { walk_pat(pat, |p| { match p.node { PatIdent(binding_mode, ref pth, _) if pat_is_binding(dm, p) => { @@ -102,10 +102,10 @@ pub fn pat_contains_bindings(dm: &resolve::DefMap, pat: &Pat) -> bool { contains_bindings } -pub fn simple_identifier<'a>(pat: &'a Pat) -> Option<&'a Path> { +pub fn simple_identifier<'a>(pat: &'a Pat) -> Option<&'a Ident> { match pat.node { - PatIdent(BindByValue(_), ref path, None) => { - Some(path) + PatIdent(BindByValue(_), ref path1, None) => { + Some(&path1.node) } _ => { None diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index d42befc65421b36bb184bb7f1a3053b1f986eb86..b7b4618a7904619a97f34eacd6d26a0efe1a2b0f 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -23,11 +23,10 @@ use syntax::ast::*; use syntax::ast; use syntax::ast_util::{local_def}; -use syntax::ast_util::{path_to_ident, walk_pat, trait_method_to_ty_method}; +use syntax::ast_util::{walk_pat, trait_method_to_ty_method}; use syntax::ext::mtwt; use syntax::parse::token::special_idents; use syntax::parse::token; -use syntax::print::pprust::path_to_str; use syntax::codemap::{Span, DUMMY_SP, Pos}; use syntax::owned_slice::OwnedSlice; use syntax::visit; @@ -1247,7 +1246,7 @@ fn build_reduced_graph_for_item(&mut self, // Create the module and add all methods. match ty.node { TyPath(ref path, _, _) if path.segments.len() == 1 => { - let name = path_to_ident(path); + let name = path.segments.last().unwrap().identifier; let parent_opt = parent.module().children.borrow() .find_copy(&name.name); @@ -4104,8 +4103,8 @@ fn resolve_local(&mut self, local: &Local) { // user and one 'x' came from the macro. fn binding_mode_map(&mut self, pat: &Pat) -> BindingMap { let mut result = HashMap::new(); - pat_bindings(&self.def_map, pat, |binding_mode, _id, sp, path| { - let name = mtwt::resolve(path_to_ident(path)); + pat_bindings(&self.def_map, pat, |binding_mode, _id, sp, path1| { + let name = mtwt::resolve(path1.node); result.insert(name, binding_info {span: sp, binding_mode: binding_mode}); @@ -4314,8 +4313,7 @@ fn resolve_pattern(&mut self, let pat_id = pattern.id; walk_pat(pattern, |pattern| { match pattern.node { - PatIdent(binding_mode, ref path, _) - if !path.global && path.segments.len() == 1 => { + PatIdent(binding_mode, ref path1, _) => { // The meaning of pat_ident with no type parameters // depends on whether an enum variant or unit-like struct @@ -4326,7 +4324,7 @@ fn resolve_pattern(&mut self, // such a value is simply disallowed (since it's rarely // what you want). - let ident = path.segments.get(0).identifier; + let ident = path1.node; let renamed = mtwt::resolve(ident); match self.resolve_bare_identifier_pattern(ident) { @@ -4416,57 +4414,12 @@ struct or enum variant", format!("identifier `{}` is bound \ more than once in the same \ pattern", - path_to_str(path)).as_slice()); + token::get_ident(ident)).as_slice()); } // Else, not bound in the same pattern: do // nothing. } } - - // Check the types in the path pattern. - for ty in path.segments - .iter() - .flat_map(|seg| seg.types.iter()) { - self.resolve_type(&**ty); - } - } - - PatIdent(binding_mode, ref path, _) => { - // This must be an enum variant, struct, or constant. - match self.resolve_path(pat_id, path, ValueNS, false) { - Some(def @ (DefVariant(..), _)) | - Some(def @ (DefStruct(..), _)) => { - self.record_def(pattern.id, def); - } - Some(def @ (DefStatic(..), _)) => { - self.enforce_default_binding_mode( - pattern, - binding_mode, - "a constant"); - self.record_def(pattern.id, def); - } - Some(_) => { - self.resolve_error( - path.span, - format!("`{}` is not an enum variant or constant", - token::get_ident( - path.segments - .last() - .unwrap() - .identifier)).as_slice()) - } - None => { - self.resolve_error(path.span, - "unresolved enum variant"); - } - } - - // Check the types in the path pattern. - for ty in path.segments - .iter() - .flat_map(|s| s.types.iter()) { - self.resolve_type(&**ty); - } } PatEnum(ref path, _) => { @@ -5202,8 +5155,8 @@ fn resolve_expr(&mut self, expr: &Expr) { in a static method. Maybe a \ `self` argument is missing?"); } else { - let name = path_to_ident(path).name; - let mut msg = match self.find_fallback_in_self_type(name) { + let last_name = path.segments.last().unwrap().identifier.name; + let mut msg = match self.find_fallback_in_self_type(last_name) { NoSuggestion => { // limit search to 5 to reduce the number // of stupid suggestions diff --git a/src/librustc/middle/save/mod.rs b/src/librustc/middle/save/mod.rs index 2b2f3b8fb0b5fd085ba00cdc24736f1bde36644d..56894ad3e5c2b70c94bd720d291997226df8007b 100644 --- a/src/librustc/middle/save/mod.rs +++ b/src/librustc/middle/save/mod.rs @@ -926,7 +926,7 @@ fn process_pat(&mut self, p:&ast::Pat, e: DxrVisitorEnv) { self.collected_paths.push((p.id, path.clone(), false, recorder::VarRef)); visit::walk_pat(self, p, e); } - ast::PatIdent(bm, ref path, ref optional_subpattern) => { + ast::PatIdent(bm, ref path1, ref optional_subpattern) => { let immut = match bm { // Even if the ref is mut, you can't change the ref, only // the data pointed at, so showing the initialising expression @@ -940,7 +940,8 @@ fn process_pat(&mut self, p:&ast::Pat, e: DxrVisitorEnv) { } }; // collect path for either visit_local or visit_arm - self.collected_paths.push((p.id, path.clone(), immut, recorder::VarRef)); + let path = ast_util::ident_to_path(path1.span,path1.node); + self.collected_paths.push((p.id, path, immut, recorder::VarRef)); match *optional_subpattern { None => {} Some(subpattern) => self.visit_pat(&*subpattern, e), diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs index 595203fdefb2d26efe2e9b3358213d044ac98997..55939e6ea7a9fd56b7b03e5b28ed171df5efc022 100644 --- a/src/librustc/middle/trans/_match.rs +++ b/src/librustc/middle/trans/_match.rs @@ -231,8 +231,6 @@ use std::gc::{Gc}; use syntax::ast; use syntax::ast::Ident; -use syntax::ast_util::path_to_ident; -use syntax::ast_util; use syntax::codemap::Span; use syntax::parse::token::InternedString; @@ -435,13 +433,13 @@ fn expand_nested_bindings<'a, 'b>( m.iter().map(|br| { match br.pats.get(col).node { - ast::PatIdent(_, ref path, Some(inner)) => { + ast::PatIdent(_, ref path1, Some(inner)) => { let pats = Vec::from_slice(br.pats.slice(0u, col)) .append((vec!(inner)) .append(br.pats.slice(col + 1u, br.pats.len())).as_slice()); let mut bound_ptrs = br.bound_ptrs.clone(); - bound_ptrs.push((path_to_ident(path), val)); + bound_ptrs.push((path1.node, val)); Match { pats: pats, data: &*br.data, @@ -479,9 +477,9 @@ fn enter_match<'a, 'b>( let this = *br.pats.get(col); let mut bound_ptrs = br.bound_ptrs.clone(); match this.node { - ast::PatIdent(_, ref path, None) => { + ast::PatIdent(_, ref path1, None) => { if pat_is_binding(dm, &*this) { - bound_ptrs.push((path_to_ident(path), val)); + bound_ptrs.push((path1.node, val)); } } _ => {} @@ -1431,8 +1429,8 @@ fn create_bindings_map(bcx: &Block, pat: Gc) -> BindingsMap { let ccx = bcx.ccx(); let tcx = bcx.tcx(); let mut bindings_map = HashMap::new(); - pat_bindings(&tcx.def_map, &*pat, |bm, p_id, span, path| { - let ident = path_to_ident(path); + pat_bindings(&tcx.def_map, &*pat, |bm, p_id, span, path1| { + let ident = path1.node; let variable_ty = node_id_type(bcx, p_id); let llvariable_ty = type_of::type_of(ccx, variable_ty); @@ -1586,10 +1584,10 @@ pub fn store_local<'a>(bcx: &'a Block<'a>, // In such cases, the more general path is unsafe, because // it assumes it is matching against a valid value. match simple_identifier(&*pat) { - Some(path) => { + Some(ident) => { let var_scope = cleanup::var_scope(tcx, local.id); return mk_binding_alloca( - bcx, pat.id, path, BindLocal, var_scope, (), + bcx, pat.id, ident, BindLocal, var_scope, (), |(), bcx, v, _| expr::trans_into(bcx, &*init_expr, expr::SaveIn(v))); } @@ -1621,10 +1619,10 @@ fn create_dummy_locals<'a>(mut bcx: &'a Block<'a>, // create dummy memory for the variables if we have no // value to store into them immediately let tcx = bcx.tcx(); - pat_bindings(&tcx.def_map, &*pat, |_, p_id, _, path| { + pat_bindings(&tcx.def_map, &*pat, |_, p_id, _, path1| { let scope = cleanup::var_scope(tcx, p_id); bcx = mk_binding_alloca( - bcx, p_id, path, BindLocal, scope, (), + bcx, p_id, &path1.node, BindLocal, scope, (), |(), bcx, llval, ty| { zero_mem(bcx, llval, ty); bcx }); }); bcx @@ -1652,7 +1650,7 @@ pub fn store_arg<'a>(mut bcx: &'a Block<'a>, let _icx = push_ctxt("match::store_arg"); match simple_identifier(&*pat) { - Some(path) => { + Some(ident) => { // Generate nicer LLVM for the common case of fn a pattern // like `x: T` let arg_ty = node_id_type(bcx, pat.id); @@ -1667,7 +1665,7 @@ pub fn store_arg<'a>(mut bcx: &'a Block<'a>, bcx } else { mk_binding_alloca( - bcx, pat.id, path, BindArgument, arg_scope, arg, + bcx, pat.id, ident, BindArgument, arg_scope, arg, |arg, bcx, llval, _| arg.store_to(bcx, llval)) } } @@ -1685,17 +1683,16 @@ pub fn store_arg<'a>(mut bcx: &'a Block<'a>, fn mk_binding_alloca<'a,A>(bcx: &'a Block<'a>, p_id: ast::NodeId, - path: &ast::Path, + ident: &ast::Ident, binding_mode: IrrefutablePatternBindingMode, cleanup_scope: cleanup::ScopeId, arg: A, populate: |A, &'a Block<'a>, ValueRef, ty::t| -> &'a Block<'a>) -> &'a Block<'a> { let var_ty = node_id_type(bcx, p_id); - let ident = ast_util::path_to_ident(path); // Allocate memory on stack for the binding. - let llval = alloc_ty(bcx, var_ty, bcx.ident(ident).as_slice()); + let llval = alloc_ty(bcx, var_ty, bcx.ident(*ident).as_slice()); // Subtle: be sure that we *populate* the memory *before* // we schedule the cleanup. @@ -1753,13 +1750,13 @@ fn bind_irrefutable_pat<'a>( let tcx = bcx.tcx(); let ccx = bcx.ccx(); match pat.node { - ast::PatIdent(pat_binding_mode, ref path, inner) => { + ast::PatIdent(pat_binding_mode, ref path1, inner) => { if pat_is_binding(&tcx.def_map, &*pat) { // Allocate the stack slot where the value of this // binding will live and place it into the appropriate // map. bcx = mk_binding_alloca( - bcx, pat.id, path, binding_mode, cleanup_scope, (), + bcx, pat.id, &path1.node, binding_mode, cleanup_scope, (), |(), bcx, llval, ty| { match pat_binding_mode { ast::BindByValue(_) => { diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index f4019898003762f2f531259f605da2b4d0ffcadb..afa0b3041550e707eeffeb7e6f1407cfed9321ed 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -842,8 +842,8 @@ pub fn create_local_var_metadata(bcx: &Block, local: &ast::Local) { let cx = bcx.ccx(); let def_map = &cx.tcx.def_map; - pat_util::pat_bindings(def_map, &*local.pat, |_, node_id, span, path_ref| { - let var_ident = ast_util::path_to_ident(path_ref); + pat_util::pat_bindings(def_map, &*local.pat, |_, node_id, span, path1| { + let var_ident = path1.node; let datum = match bcx.fcx.lllocals.borrow().find_copy(&node_id) { Some(datum) => datum, @@ -890,8 +890,8 @@ pub fn create_captured_var_metadata(bcx: &Block, } Some(ast_map::NodeLocal(pat)) | Some(ast_map::NodeArg(pat)) => { match pat.node { - ast::PatIdent(_, ref path, _) => { - ast_util::path_to_ident(path) + ast::PatIdent(_, ref path1, _) => { + path1.node } _ => { cx.sess() @@ -990,7 +990,7 @@ pub fn create_argument_metadata(bcx: &Block, arg: &ast::Arg) { let def_map = &cx.tcx.def_map; let scope_metadata = bcx.fcx.debug_context.get_ref(cx, arg.pat.span).fn_metadata; - pat_util::pat_bindings(def_map, &*arg.pat, |_, node_id, span, path_ref| { + pat_util::pat_bindings(def_map, &*arg.pat, |_, node_id, span, path1| { let llarg = match bcx.fcx.llargs.borrow().find_copy(&node_id) { Some(v) => v, None => { @@ -1005,8 +1005,6 @@ pub fn create_argument_metadata(bcx: &Block, arg: &ast::Arg) { Referenced variable location is not an alloca!"); } - let argument_ident = ast_util::path_to_ident(path_ref); - let argument_index = { let counter = &fcx.debug_context.get_ref(cx, span).argument_counter; let argument_index = counter.get(); @@ -1015,7 +1013,7 @@ pub fn create_argument_metadata(bcx: &Block, arg: &ast::Arg) { }; declare_local(bcx, - argument_ident, + path1.node, llarg.ty, scope_metadata, DirectVariable { alloca: llarg.val }, @@ -3220,10 +3218,9 @@ struct ScopeStackEntry { // Push argument identifiers onto the stack so arguments integrate nicely // with variable shadowing. for &arg_pat in arg_pats.iter() { - pat_util::pat_bindings(def_map, &*arg_pat, |_, _, _, path_ref| { - let ident = ast_util::path_to_ident(path_ref); + pat_util::pat_bindings(def_map, &*arg_pat, |_, _, _, path1| { scope_stack.push(ScopeStackEntry { scope_metadata: fn_metadata, - ident: Some(ident) }); + ident: Some(path1.node) }); }) } @@ -3331,13 +3328,13 @@ fn walk_pattern(cx: &CrateContext, // ast_util::walk_pat() here because we have to visit *all* nodes in // order to put them into the scope map. The above functions don't do that. match pat.node { - ast::PatIdent(_, ref path_ref, ref sub_pat_opt) => { + ast::PatIdent(_, ref path1, ref sub_pat_opt) => { // Check if this is a binding. If so we need to put it on the // scope stack and maybe introduce an artificial scope if pat_util::pat_is_binding(def_map, &*pat) { - let ident = ast_util::path_to_ident(path_ref); + let ident = path1.node; // 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/middle/ty.rs b/src/librustc/middle/ty.rs index 79630be7c5e0840c21dfdf99228ed5bbede7f7ac..9629fb38af80fb62cf58726d520725b139aba143 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -2771,8 +2771,8 @@ pub fn local_var_name_str(cx: &ctxt, id: NodeId) -> InternedString { match cx.map.find(id) { Some(ast_map::NodeLocal(pat)) => { match pat.node { - ast::PatIdent(_, ref path, _) => { - token::get_ident(ast_util::path_to_ident(path)) + ast::PatIdent(_, ref path1, _) => { + token::get_ident(path1.node) } _ => { cx.sess.bug( diff --git a/src/librustc/middle/typeck/check/_match.rs b/src/librustc/middle/typeck/check/_match.rs index 60ce9508dc46b3422eb7dc34e4c5def15d0b4297..697c5d367ee5a51ab3a65cd2a6945de0d3ae5db6 100644 --- a/src/librustc/middle/typeck/check/_match.rs +++ b/src/librustc/middle/typeck/check/_match.rs @@ -485,7 +485,7 @@ pub fn check_pat(pcx: &pat_ctxt, pat: &ast::Pat, expected: ty::t) { demand::suptype(fcx, pat.span, expected, const_pty.ty); fcx.write_ty(pat.id, const_pty.ty); } - ast::PatIdent(bm, ref name, sub) if pat_is_binding(&tcx.def_map, pat) => { + ast::PatIdent(bm, ref path1, sub) if pat_is_binding(&tcx.def_map, pat) => { let typ = fcx.local_ty(pat.span, pat.id); match bm { @@ -507,7 +507,7 @@ pub fn check_pat(pcx: &pat_ctxt, pat: &ast::Pat, expected: ty::t) { } } - let canon_id = *pcx.map.get(&ast_util::path_to_ident(name)); + let canon_id = *pcx.map.get(&path1.node); if canon_id != pat.id { let ct = fcx.local_ty(pat.span, canon_id); demand::eqtype(fcx, pat.span, ct, typ); @@ -521,8 +521,10 @@ pub fn check_pat(pcx: &pat_ctxt, pat: &ast::Pat, expected: ty::t) { _ => () } } - ast::PatIdent(_, ref path, _) => { - check_pat_variant(pcx, pat, path, &Some(Vec::new()), expected); + // it's not a binding, it's an enum in disguise: + ast::PatIdent(_, ref path1, _) => { + let path = ast_util::ident_to_path(path1.span,path1.node); + check_pat_variant(pcx, pat, &path, &Some(Vec::new()), expected); } ast::PatEnum(ref path, ref subpats) => { check_pat_variant(pcx, pat, path, subpats, expected); diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index f5e34e9307764944b73ff9457acb678b2970fa36..b68991aed70963c53c341788689c4f11e1652a7a 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -406,11 +406,11 @@ fn visit_local(&mut self, local: &ast::Local, _: ()) { // Add pattern bindings. fn visit_pat(&mut self, p: &ast::Pat, _: ()) { match p.node { - ast::PatIdent(_, ref path, _) + ast::PatIdent(_, ref path1, _) if pat_util::pat_is_binding(&self.fcx.ccx.tcx.def_map, p) => { self.assign(p.id, None); debug!("Pattern binding {} is assigned to {}", - token::get_ident(path.segments.get(0).identifier), + token::get_ident(path1.node), self.fcx.infcx().ty_to_str( self.fcx.inh.locals.borrow().get_copy(&p.id))); } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 87151708812e54a5f106291d5a04fd851bf6a0dc..58985f832ce32091e01106dfe80e0c73aabcc22c 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1583,8 +1583,6 @@ fn clean(&self) -> PathSegment { } fn path_to_str(p: &ast::Path) -> String { - use syntax::parse::token; - let mut s = String::new(); let mut first = true; for i in p.segments.iter().map(|x| token::get_ident(x.identifier)) { @@ -1953,7 +1951,7 @@ fn name_from_pat(p: &ast::Pat) -> String { match p.node { PatWild => "_".to_string(), PatWildMulti => "..".to_string(), - PatIdent(_, ref p, _) => path_to_str(p), + PatIdent(_, ref p, _) => token::get_ident(p.node).get().to_string(), PatEnum(ref p, _) => path_to_str(p), PatStruct(..) => fail!("tried to get argument name from pat_struct, \ which is not allowed in function arguments"), diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 529b460adcd34d862bcb951e8ee00a8f27358d40..237d0660a41dcca5edb5f15875cd41bdc5fd2f5a 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -293,8 +293,8 @@ pub enum Pat_ { // In the nullary enum case, the parser can't determine // which it is. The resolver determines this, and // records this pattern's NodeId in an auxiliary - // set (of "pat_idents that refer to nullary enums") - PatIdent(BindingMode, Path, Option>), + // set (of "PatIdents that refer to nullary enums") + PatIdent(BindingMode, SpannedIdent, Option>), PatEnum(Path, Option>>), /* "none" means a * pattern where * we don't bind the fields to names */ PatStruct(Path, Vec, bool), @@ -818,7 +818,7 @@ pub struct Arg { impl Arg { pub fn new_self(span: Span, mutability: Mutability) -> Arg { - let path = ast_util::ident_to_path(span, special_idents::self_); + let path = Spanned{span:span,node:special_idents::self_}; Arg { // HACK(eddyb) fake type for the self argument. ty: P(Ty { diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 2a6f7bdb87e35eec4730e2d143a873b61a9fe539..036d6b4b43adc62d537c8c0f9dfc745964d6bca3 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -33,12 +33,6 @@ pub fn path_name_i(idents: &[Ident]) -> String { }).collect::>().connect("::") } -// totally scary function: ignores all but the last element, should have -// a different name -pub fn path_to_ident(path: &Path) -> Ident { - path.segments.last().unwrap().identifier -} - pub fn local_def(id: NodeId) -> DefId { ast::DefId { krate: LOCAL_CRATE, node: id } } @@ -186,6 +180,8 @@ pub fn block_from_expr(e: Gc) -> P { }) } +// convert a span and an identifier to the corresponding +// 1-segment path pub fn ident_to_path(s: Span, identifier: Ident) -> Path { ast::Path { span: s, @@ -202,7 +198,7 @@ pub fn ident_to_path(s: Span, identifier: Ident) -> Path { pub fn ident_to_pat(id: NodeId, s: Span, i: Ident) -> Gc { box(GC) ast::Pat { id: id, - node: PatIdent(BindByValue(MutImmutable), ident_to_path(s, i), None), + node: PatIdent(BindByValue(MutImmutable), codemap::Spanned{span:s, node:i}, None), span: s } } diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 8d48401f9c2a45ec077fcc2cdb8d43d86826fa09..46bc4ec11ce4f044ac14b35d1f603042558bf089 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -759,8 +759,7 @@ fn pat_ident_binding_mode(&self, span: Span, ident: ast::Ident, bm: ast::BindingMode) -> Gc { - let path = self.path_ident(span, ident); - let pat = ast::PatIdent(bm, path, None); + let pat = ast::PatIdent(bm, Spanned{span: span, node: ident}, None); self.pat(span, pat) } fn pat_enum(&self, span: Span, path: ast::Path, subpats: Vec> ) -> Gc { diff --git a/src/libsyntax/ext/deriving/generic/mod.rs b/src/libsyntax/ext/deriving/generic/mod.rs index 2b97687dbf8c99e5d19704f3c957758165d41ade..b9bc500933750d53a6a703448c3608c50d2ee70a 100644 --- a/src/libsyntax/ext/deriving/generic/mod.rs +++ b/src/libsyntax/ext/deriving/generic/mod.rs @@ -1049,7 +1049,7 @@ fn summarise_struct(&self, fn create_subpatterns(&self, cx: &mut ExtCtxt, - field_paths: Vec , + field_paths: Vec , mutbl: ast::Mutability) -> Vec> { field_paths.iter().map(|path| { @@ -1095,15 +1095,10 @@ fn create_struct_pattern(&self, cx.span_bug(sp, "a struct with named and unnamed fields in `deriving`"); } }; - let path = - cx.path_ident(sp, - cx.ident_of(format!("{}_{}", - prefix, - i).as_slice())); - paths.push(path.clone()); + let ident = cx.ident_of(format!("{}_{}", prefix, i).as_slice()); + paths.push(codemap::Spanned{span: sp, node: ident}); let val = cx.expr( - sp, ast::ExprParen( - cx.expr_deref(sp, cx.expr_path(path)))); + sp, ast::ExprParen(cx.expr_deref(sp, cx.expr_path(cx.path_ident(sp,ident))))); ident_expr.push((sp, opt_id, val)); } @@ -1145,15 +1140,11 @@ fn create_enum_variant_pattern(&self, let mut ident_expr = Vec::new(); for (i, va) in variant_args.iter().enumerate() { let sp = self.set_expn_info(cx, va.ty.span); - let path = - cx.path_ident(sp, - cx.ident_of(format!("{}_{}", - prefix, - i).as_slice())); - - paths.push(path.clone()); - let val = cx.expr( - sp, ast::ExprParen(cx.expr_deref(sp, cx.expr_path(path)))); + let ident = cx.ident_of(format!("{}_{}", prefix, i).as_slice()); + let path1 = codemap::Spanned{span: sp, node: ident}; + paths.push(path1); + let expr_path = cx.expr_path(cx.path_ident(sp, ident)); + let val = cx.expr(sp, ast::ExprParen(cx.expr_deref(sp, expr_path))); ident_expr.push((sp, None, val)); } diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index b9cedb7a7797a065a9b32a34e137ef12b1310972..d1eb0147b9cf454253dc9adc4b4b5dd5d2f87785 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -705,22 +705,10 @@ fn visit_pat(&mut self, pattern: &ast::Pat, _: ()) { // we found a pat_ident! ast::Pat { id: _, - node: ast::PatIdent(_, ref path, ref inner), + node: ast::PatIdent(_, ref path1, ref inner), span: _ } => { - match path { - // a path of length one: - &ast::Path { - global: false, - span: _, - segments: ref segments - } if segments.len() == 1 => { - self.ident_accumulator.push(segments.get(0) - .identifier) - } - // I believe these must be enums... - _ => () - } + self.ident_accumulator.push(path1.node); // visit optional subpattern of pat_ident: for subpat in inner.iter() { self.visit_pat(&**subpat, ()) diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index c6177ce31f5f874a8282020d717a6ca2f1c792bf..f9d7078da3dcbe4377132259c3c5699ae66fca36 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -791,9 +791,10 @@ pub fn noop_fold_pat(p: Gc, folder: &mut T) -> Gc { let node = match p.node { PatWild => PatWild, PatWildMulti => PatWildMulti, - PatIdent(binding_mode, ref pth, ref sub) => { + PatIdent(binding_mode, ref pth1, ref sub) => { PatIdent(binding_mode, - folder.fold_path(pth), + Spanned{span: folder.new_span(pth1.span), + node: folder.fold_ident(pth1.node)}, sub.map(|x| folder.fold_pat(x))) } PatLit(e) => PatLit(folder.fold_expr(e)), diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 331a49c83beacbeac006dc3a5666cc0e40c475de..4b5252bfba3118eb081d8a1783d18631a265b9bc 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -594,23 +594,15 @@ fn parser_done(p: Parser){ #[test] fn parse_ident_pat () { let sess = new_parse_sess(); let mut parser = string_to_parser(&sess, "b".to_string()); - assert!(parser.parse_pat() == - box(GC) ast::Pat{id: ast::DUMMY_NODE_ID, - node: ast::PatIdent( - ast::BindByValue(ast::MutImmutable), - ast::Path { - span:sp(0,1), - global:false, - segments: vec!( - ast::PathSegment { - identifier: str_to_ident("b"), - lifetimes: Vec::new(), - types: OwnedSlice::empty(), - } - ), - }, - None /* no idea */), - span: sp(0,1)}); + assert!(parser.parse_pat() + == box(GC) ast::Pat{ + id: ast::DUMMY_NODE_ID, + node: ast::PatIdent(ast::BindByValue(ast::MutImmutable), + Spanned{ span:sp(0, 1), + node: str_to_ident("b") + }, + None), + span: sp(0,1)}); parser_done(parser); } @@ -643,24 +635,15 @@ fn parser_done(p: Parser){ id: ast::DUMMY_NODE_ID, node: ast::PatIdent( ast::BindByValue(ast::MutImmutable), - ast::Path { - span:sp(6,7), - global:false, - segments: vec!( - ast::PathSegment { - identifier: - str_to_ident("b"), - lifetimes: Vec::new(), - types: OwnedSlice::empty(), - } - ), - }, - None // no idea - ), - span: sp(6,7) - }, - id: ast::DUMMY_NODE_ID - }), + Spanned{ + span: sp(6,7), + node: str_to_ident("b")}, + None + ), + span: sp(6,7) + }, + id: ast::DUMMY_NODE_ID + }), output: ast::P(ast::Ty{id: ast::DUMMY_NODE_ID, node: ast::TyNil, span:sp(15,15)}), // not sure diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 0fd5a7086b78c897507508137b3d7c410242a6a5..2aa2da3ba4b001b81c4bc3731f9e1b7429632a74 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -58,7 +58,7 @@ use ast::{ViewPath, ViewPathGlob, ViewPathList, ViewPathSimple}; use ast::Visibility; use ast; -use ast_util::{as_prec, lit_is_str, operator_prec}; +use ast_util::{as_prec, ident_to_path, lit_is_str, operator_prec}; use ast_util; use codemap::{Span, BytePos, Spanned, spanned, mk_sp}; use codemap; @@ -2854,8 +2854,7 @@ fn parse_pat_fields(&mut self) -> (Vec , bool) { self.bump(); self.parse_pat() } else { - let fieldpath = ast_util::ident_to_path(self.last_span, - fieldname); + let fieldpath = codemap::Spanned{span:self.last_span, node: fieldname}; box(GC) ast::Pat { id: ast::DUMMY_NODE_ID, node: PatIdent(bind_type, fieldpath, None), @@ -2961,6 +2960,7 @@ pub fn parse_pat(&mut self) -> Gc { } _ => {} } + // at this point, token != _, ~, &, &&, (, [ if (!is_ident_or_path(&self.token) && self.token != token::MOD_SEP) || self.is_keyword(keywords::True) @@ -3017,7 +3017,9 @@ pub fn parse_pat(&mut self) -> Gc { let end = self.parse_expr_res(RESTRICT_NO_BAR_OP); pat = PatRange(start, end); } else if is_plain_ident(&self.token) && !can_be_enum_or_struct { - let name = self.parse_path(NoTypesAllowed).path; + let id = self.parse_ident(); + let id_span = self.last_span; + let pth1 = codemap::Spanned{span:id_span, node: id}; if self.eat(&token::NOT) { // macro invocation let ket = token::close_delimiter_for(&self.token) @@ -3028,7 +3030,7 @@ pub fn parse_pat(&mut self) -> Gc { seq_sep_none(), |p| p.parse_token_tree()); - let mac = MacInvocTT(name, tts, EMPTY_CTXT); + let mac = MacInvocTT(ident_to_path(id_span,id), tts, EMPTY_CTXT); pat = ast::PatMac(codemap::Spanned {node: mac, span: self.span}); } else { let sub = if self.eat(&token::AT) { @@ -3038,7 +3040,7 @@ pub fn parse_pat(&mut self) -> Gc { // or just foo None }; - pat = PatIdent(BindByValue(MutImmutable), name, sub); + pat = PatIdent(BindByValue(MutImmutable), pth1, sub); } } else { // parse an enum pat @@ -3084,8 +3086,11 @@ pub fn parse_pat(&mut self) -> Gc { // or an identifier pattern, resolve // will sort it out: pat = PatIdent(BindByValue(MutImmutable), - enum_path, - None); + codemap::Spanned{ + span: enum_path.span, + node: enum_path.segments.get(0) + .identifier}, + None); } else { pat = PatEnum(enum_path, Some(args)); } @@ -3115,7 +3120,7 @@ fn parse_pat_ident(&mut self, "expected identifier, found path"); } // why a path here, and not just an identifier? - let name = self.parse_path(NoTypesAllowed).path; + let name = codemap::Spanned{span: self.last_span, node: self.parse_ident()}; let sub = if self.eat(&token::AT) { Some(self.parse_pat()) } else { diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index a9cf4fbd9f0f130855ce8c67d9bc5f0ab6f58a56..4660bb337ab23e1d46c4d8ad2fb608a214d5804c 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -196,6 +196,10 @@ pub fn path_to_str(p: &ast::Path) -> String { to_str(|s| s.print_path(p, false)) } +pub fn ident_to_str(id: &ast::Ident) -> String { + to_str(|s| s.print_ident(*id)) +} + pub fn fun_to_str(decl: &ast::FnDecl, fn_style: ast::FnStyle, name: ast::Ident, opt_explicit_self: Option, generics: &ast::Generics) -> String { @@ -1705,7 +1709,7 @@ pub fn print_pat(&mut self, pat: &ast::Pat) -> IoResult<()> { match pat.node { ast::PatWild => try!(word(&mut self.s, "_")), ast::PatWildMulti => try!(word(&mut self.s, "..")), - ast::PatIdent(binding_mode, ref path, sub) => { + ast::PatIdent(binding_mode, ref path1, sub) => { match binding_mode { ast::BindByRef(mutbl) => { try!(self.word_nbsp("ref")); @@ -1716,7 +1720,7 @@ pub fn print_pat(&mut self, pat: &ast::Pat) -> IoResult<()> { try!(self.word_nbsp("mut")); } } - try!(self.print_path(path, true)); + try!(self.print_ident(path1.node)); match sub { Some(ref p) => { try!(word(&mut self.s, "@")); @@ -2148,9 +2152,8 @@ pub fn print_arg(&mut self, input: &ast::Arg) -> IoResult<()> { ast::TyInfer => try!(self.print_pat(&*input.pat)), _ => { match input.pat.node { - ast::PatIdent(_, ref path, _) if - path.segments.len() == 1 && - path.segments.get(0).identifier.name == + ast::PatIdent(_, ref path1, _) if + path1.node.name == parse::token::special_idents::invalid.name => { // Do nothing. } diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 6f0fc217533fc5070b25007d2bad6cfaa9aa9175..4ab064a88b7950d3ede7d4ab57d8c05591666205 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -454,8 +454,8 @@ pub fn walk_pat>(visitor: &mut V, pattern: &Pat, env: E) PatRegion(ref subpattern) => { visitor.visit_pat(&**subpattern, env) } - PatIdent(_, ref path, ref optional_subpattern) => { - visitor.visit_path(path, pattern.id, env.clone()); + PatIdent(_, ref pth1, ref optional_subpattern) => { + visitor.visit_ident(pth1.span, pth1.node, env.clone()); match *optional_subpattern { None => {} Some(ref subpattern) => visitor.visit_pat(&**subpattern, env),