diff options
| author | Eduard Burtescu <edy.burt@gmail.com> | 2015-01-13 06:02:56 +0200 |
|---|---|---|
| committer | Eduard Burtescu <edy.burt@gmail.com> | 2015-01-15 18:51:14 +0200 |
| commit | 2cdc86c180296ff2c929ec55fcf33a0f6b391b3a (patch) | |
| tree | 1d9e7cc7086adb4c17ba82171d3696ac633a8648 | |
| parent | 1c78ad937b4da9dd872b0a865025f3e2e885f90d (diff) | |
| download | rust-2cdc86c180296ff2c929ec55fcf33a0f6b391b3a.tar.gz rust-2cdc86c180296ff2c929ec55fcf33a0f6b391b3a.zip | |
syntax: add fully qualified UFCS expressions.
25 files changed, 89 insertions, 42 deletions
diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index d95000ece5a..59808b302f4 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -1731,7 +1731,7 @@ impl LintPass for Stability { let mut span = e.span; let id = match e.node { - ast::ExprPath(..) | ast::ExprStruct(..) => { + ast::ExprPath(..) | ast::ExprQPath(..) | ast::ExprStruct(..) => { match cx.tcx.def_map.borrow().get(&e.id) { Some(&def) => def.def_id(), None => return diff --git a/src/librustc/middle/cfg/construct.rs b/src/librustc/middle/cfg/construct.rs index b601ea59486..07b520e5865 100644 --- a/src/librustc/middle/cfg/construct.rs +++ b/src/librustc/middle/cfg/construct.rs @@ -495,7 +495,8 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> { ast::ExprMac(..) | ast::ExprClosure(..) | ast::ExprLit(..) | - ast::ExprPath(..) => { + ast::ExprPath(..) | + ast::ExprQPath(..) => { self.straightline(expr, pred, None::<ast::Expr>.iter()) } } diff --git a/src/librustc/middle/check_const.rs b/src/librustc/middle/check_const.rs index 621d7274b3f..202020a9033 100644 --- a/src/librustc/middle/check_const.rs +++ b/src/librustc/middle/check_const.rs @@ -111,7 +111,7 @@ fn check_expr(v: &mut CheckCrateVisitor, e: &ast::Expr) { expression"); } } - ast::ExprPath(_) => { + ast::ExprPath(_) | ast::ExprQPath(_) => { match v.tcx.def_map.borrow()[e.id] { DefStatic(..) | DefConst(..) | DefFn(..) | DefStaticMethod(..) | DefMethod(..) | diff --git a/src/librustc/middle/check_static.rs b/src/librustc/middle/check_static.rs index 154272d2deb..026aa3c5ccf 100644 --- a/src/librustc/middle/check_static.rs +++ b/src/librustc/middle/check_static.rs @@ -228,7 +228,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckStaticVisitor<'a, 'tcx> { "{} are not allowed to have custom pointers", self.msg()); } - ast::ExprPath(..) => { + ast::ExprPath(_) | ast::ExprQPath(_) => { match ty::resolve_expr(self.tcx, e) { def::DefStatic(..) if self.mode == InConstant => { let msg = "constants cannot refer to other statics, \ diff --git a/src/librustc/middle/check_static_recursion.rs b/src/librustc/middle/check_static_recursion.rs index e2a0738def1..86a58dae45a 100644 --- a/src/librustc/middle/check_static_recursion.rs +++ b/src/librustc/middle/check_static_recursion.rs @@ -93,7 +93,7 @@ impl<'a, 'ast, 'v> Visitor<'v> for CheckItemRecursionVisitor<'a, 'ast> { fn visit_expr(&mut self, e: &ast::Expr) { match e.node { - ast::ExprPath(..) => { + ast::ExprPath(_) | ast::ExprQPath(_) => { match self.def_map.borrow().get(&e.id) { Some(&DefStatic(def_id, _)) | Some(&DefConst(def_id)) if diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs index 52352e920ce..c998d178c22 100644 --- a/src/librustc/middle/const_eval.rs +++ b/src/librustc/middle/const_eval.rs @@ -244,7 +244,7 @@ impl<'a, 'tcx> ConstEvalVisitor<'a, 'tcx> { // FIXME: (#3728) we can probably do something CCI-ish // surrounding nonlocal constants. But we don't yet. - ast::ExprPath(_) => self.lookup_constness(e), + ast::ExprPath(_) | ast::ExprQPath(_) => self.lookup_constness(e), ast::ExprRepeat(..) => general_const, @@ -356,6 +356,13 @@ pub fn const_expr_to_pat(tcx: &ty::ctxt, expr: &Expr) -> P<ast::Pat> { } } + ast::ExprQPath(_) => { + match lookup_const(tcx, expr) { + Some(actual) => return const_expr_to_pat(tcx, actual), + _ => unreachable!() + } + } + _ => ast::PatLit(P(expr.clone())) }; P(ast::Pat { id: expr.id, node: pat, span: expr.span }) @@ -542,7 +549,7 @@ pub fn eval_const_expr_partial(tcx: &ty::ctxt, e: &Expr) -> Result<const_val, St ty::ty_float(ast::TyF64) => (f64, const_float, f64) })) } - ast::ExprPath(_) => { + ast::ExprPath(_) | ast::ExprQPath(_) => { match lookup_const(tcx, e) { Some(actual_e) => eval_const_expr_partial(tcx, &*actual_e), None => Err("non-constant path in constant expr".to_string()) diff --git a/src/librustc/middle/effect.rs b/src/librustc/middle/effect.rs index f7eea6e5cb7..abb8f35f662 100644 --- a/src/librustc/middle/effect.rs +++ b/src/librustc/middle/effect.rs @@ -175,7 +175,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> { ast::ExprInlineAsm(..) => { self.require_unsafe(expr.span, "use of inline assembly"); } - ast::ExprPath(..) => { + ast::ExprPath(_) | ast::ExprQPath(_) => { if let def::DefStatic(_, true) = ty::resolve_expr(self.tcx, expr) { self.require_unsafe(expr.span, "use of mutable static"); } diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index e5eb439d42c..a5f2dc398e9 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -424,7 +424,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> { self.walk_expr(&**subexpr) } - ast::ExprPath(..) => { } + ast::ExprPath(_) | ast::ExprQPath(_) => { } ast::ExprUnary(ast::UnDeref, ref base) => { // *base if !self.walk_overloaded_operator(expr, &**base, Vec::new(), PassArgs::ByRef) { diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 1b1dca00422..6b9e5b2ceea 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -447,7 +447,7 @@ fn visit_arm(ir: &mut IrMaps, arm: &ast::Arm) { fn visit_expr(ir: &mut IrMaps, expr: &Expr) { match expr.node { // live nodes required for uses or definitions of variables: - ast::ExprPath(_) => { + ast::ExprPath(_) | ast::ExprQPath(_) => { let def = ir.tcx.def_map.borrow()[expr.id].clone(); debug!("expr {}: path that leads to {:?}", expr.id, def); if let DefLocal(..) = def { @@ -960,7 +960,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { match expr.node { // Interesting cases with control flow or which gen/kill - ast::ExprPath(_) => { + ast::ExprPath(_) | ast::ExprQPath(_) => { self.access_path(expr, succ, ACC_READ | ACC_USE) } @@ -1289,7 +1289,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { // just ignore such cases and treat them as reads. match expr.node { - ast::ExprPath(_) => succ, + ast::ExprPath(_) | ast::ExprQPath(_) => succ, ast::ExprField(ref e, _) => self.propagate_through_expr(&**e, succ), ast::ExprTupField(ref e, _) => self.propagate_through_expr(&**e, succ), _ => self.propagate_through_expr(expr, succ) @@ -1300,7 +1300,9 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { fn write_lvalue(&mut self, expr: &Expr, succ: LiveNode, acc: uint) -> LiveNode { match expr.node { - ast::ExprPath(_) => self.access_path(expr, succ, acc), + ast::ExprPath(_) | ast::ExprQPath(_) => { + self.access_path(expr, succ, acc) + } // We do not track other lvalues, so just propagate through // to their subcomponents. Also, it may happen that @@ -1492,7 +1494,7 @@ fn check_expr(this: &mut Liveness, expr: &Expr) { ast::ExprBlock(..) | ast::ExprMac(..) | ast::ExprAddrOf(..) | ast::ExprStruct(..) | ast::ExprRepeat(..) | ast::ExprParen(..) | ast::ExprClosure(..) | ast::ExprPath(..) | ast::ExprBox(..) | - ast::ExprRange(..) => { + ast::ExprRange(..) | ast::ExprQPath(..) => { visit::walk_expr(this, expr); } ast::ExprIfLet(..) => { @@ -1583,7 +1585,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { fn check_lvalue(&mut self, expr: &Expr) { match expr.node { - ast::ExprPath(_) => { + ast::ExprPath(_) | ast::ExprQPath(_) => { if let DefLocal(nid) = self.ir.tcx.def_map.borrow()[expr.id].clone() { // Assignment to an immutable variable or argument: only legal // if there is no later assignment. If this local is actually diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 51ec7528432..90fe6b49911 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -520,7 +520,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> { } } - ast::ExprPath(_) => { + ast::ExprPath(_) | ast::ExprQPath(_) => { let def = (*self.tcx().def_map.borrow())[expr.id]; self.cat_def(expr.id, expr.span, expr_ty, def) } diff --git a/src/librustc/middle/privacy.rs b/src/librustc/middle/privacy.rs index aa37c2fe348..b92870cfa42 100644 --- a/src/librustc/middle/privacy.rs +++ b/src/librustc/middle/privacy.rs @@ -920,7 +920,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> { struct type?!"), } } - ast::ExprPath(..) => { + ast::ExprPath(_) | ast::ExprQPath(_) => { let guard = |&: did: ast::DefId| { let fields = ty::lookup_struct_fields(self.tcx, did); let any_priv = fields.iter().any(|f| { diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index 906607ddc5b..b7e6da8c5f6 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -104,7 +104,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ReachableContext<'a, 'tcx> { fn visit_expr(&mut self, expr: &ast::Expr) { match expr.node { - ast::ExprPath(_) => { + ast::ExprPath(_) | ast::ExprQPath(_) => { let def = match self.tcx.def_map.borrow().get(&expr.id) { Some(&def) => def, None => { diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 755983c71bb..525fe86cf24 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -4515,7 +4515,7 @@ pub fn expr_kind(tcx: &ctxt, expr: &ast::Expr) -> ExprKind { } match expr.node { - ast::ExprPath(..) => { + ast::ExprPath(_) | ast::ExprQPath(_) => { match resolve_expr(tcx, expr) { def::DefVariant(tid, vid, _) => { let variant_info = enum_variant_with_id(tcx, tid, vid); diff --git a/src/librustc_back/svh.rs b/src/librustc_back/svh.rs index 4e260da2e4d..789a87bbcda 100644 --- a/src/librustc_back/svh.rs +++ b/src/librustc_back/svh.rs @@ -252,6 +252,7 @@ mod svh_visitor { SawExprIndex, SawExprRange, SawExprPath, + SawExprQPath, SawExprAddrOf(ast::Mutability), SawExprRet, SawExprInlineAsm(&'a ast::InlineAsm), @@ -285,6 +286,7 @@ mod svh_visitor { ExprIndex(..) => SawExprIndex, ExprRange(..) => SawExprRange, ExprPath(..) => SawExprPath, + ExprQPath(..) => SawExprQPath, ExprAddrOf(m, _) => SawExprAddrOf(m), ExprBreak(id) => SawExprBreak(id.map(content)), ExprAgain(id) => SawExprAgain(id.map(content)), diff --git a/src/librustc_trans/trans/_match.rs b/src/librustc_trans/trans/_match.rs index f182045efd2..b01604bd397 100644 --- a/src/librustc_trans/trans/_match.rs +++ b/src/librustc_trans/trans/_match.rs @@ -1235,7 +1235,7 @@ pub fn trans_match<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, /// Checks whether the binding in `discr` is assigned to anywhere in the expression `body` fn is_discr_reassigned(bcx: Block, discr: &ast::Expr, body: &ast::Expr) -> bool { let (vid, field) = match discr.node { - ast::ExprPath(..) => match bcx.def(discr.id) { + ast::ExprPath(_) | ast::ExprQPath(_) => match bcx.def(discr.id) { def::DefLocal(vid) | def::DefUpvar(vid, _, _) => (vid, None), _ => return false }, diff --git a/src/librustc_trans/trans/callee.rs b/src/librustc_trans/trans/callee.rs index 6196f9e5eab..11006f37531 100644 --- a/src/librustc_trans/trans/callee.rs +++ b/src/librustc_trans/trans/callee.rs @@ -91,8 +91,11 @@ fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &ast::Expr) debug!("callee::trans(expr={})", expr.repr(bcx.tcx())); // pick out special kinds of expressions that can be called: - if let ast::ExprPath(_) = expr.node { - return trans_def(bcx, bcx.def(expr.id), expr); + match expr.node { + ast::ExprPath(_) | ast::ExprQPath(_) => { + return trans_def(bcx, bcx.def(expr.id), expr); + } + _ => {} } // any other expressions are closures: diff --git a/src/librustc_trans/trans/consts.rs b/src/librustc_trans/trans/consts.rs index 00b97286de3..29cf9f72ef8 100644 --- a/src/librustc_trans/trans/consts.rs +++ b/src/librustc_trans/trans/consts.rs @@ -600,7 +600,7 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr) -> ValueRef { C_array(llunitty, &vs[]) } } - ast::ExprPath(_) => { + ast::ExprPath(_) | ast::ExprQPath(_) => { let def = cx.tcx().def_map.borrow()[e.id]; match def { def::DefFn(..) | def::DefStaticMethod(..) | def::DefMethod(..) => { diff --git a/src/librustc_trans/trans/debuginfo.rs b/src/librustc_trans/trans/debuginfo.rs index 5bbd83344bf..d5416ae0631 100644 --- a/src/librustc_trans/trans/debuginfo.rs +++ b/src/librustc_trans/trans/debuginfo.rs @@ -3526,7 +3526,8 @@ fn create_scope_map(cx: &CrateContext, ast::ExprLit(_) | ast::ExprBreak(_) | ast::ExprAgain(_) | - ast::ExprPath(_) => {} + ast::ExprPath(_) | + ast::ExprQPath(_) => {} ast::ExprCast(ref sub_exp, _) | ast::ExprAddrOf(_, ref sub_exp) | diff --git a/src/librustc_trans/trans/expr.rs b/src/librustc_trans/trans/expr.rs index ac50445be2f..0e921d8e522 100644 --- a/src/librustc_trans/trans/expr.rs +++ b/src/librustc_trans/trans/expr.rs @@ -564,7 +564,7 @@ fn trans_datum_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ast::ExprParen(ref e) => { trans(bcx, &**e) } - ast::ExprPath(_) => { + ast::ExprPath(_) | ast::ExprQPath(_) => { trans_def(bcx, expr, bcx.def(expr.id)) } ast::ExprField(ref base, ident) => { @@ -997,7 +997,7 @@ fn trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ast::ExprParen(ref e) => { trans_into(bcx, &**e, dest) } - ast::ExprPath(_) => { + ast::ExprPath(_) | ast::ExprQPath(_) => { trans_def_dps_unadjusted(bcx, expr, bcx.def(expr.id), dest) } ast::ExprIf(ref cond, ref thn, ref els) => { diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 45e05c12713..27d31a3a2f7 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1001,9 +1001,12 @@ fn qpath_to_ty<'tcx>(this: &AstConv<'tcx>, debug!("qpath_to_ty: trait_ref={}", trait_ref.repr(this.tcx())); + // `<T as Trait>::U<V>` shouldn't parse right now. + assert!(qpath.item_path.parameters.is_empty()); + return this.projected_ty(ast_ty.span, trait_ref, - qpath.item_name.name); + qpath.item_path.identifier.name); } // Parses the programmer's textual representation of a type into our diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index b65e1d1d664..8dc3adad3b2 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1614,7 +1614,7 @@ impl<'tcx> Clean<Type> for ty::Ty<'tcx> { impl Clean<Type> for ast::QPath { fn clean(&self, cx: &DocContext) -> Type { Type::QPath { - name: self.item_name.clean(cx), + name: self.item_path.identifier.clean(cx), self_type: box self.self_type.clean(cx), trait_: box self.trait_ref.clean(cx) } diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index c2cfa484aff..61bc1865517 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -747,6 +747,8 @@ pub enum Expr_ { /// Variable reference, possibly containing `::` and/or /// type parameters, e.g. foo::bar::<baz> ExprPath(Path), + /// A "qualified path", e.g. `<Vec<T> as SomeTrait>::SomeType` + ExprQPath(P<QPath>), ExprAddrOf(Mutability, P<Expr>), ExprBreak(Option<Ident>), @@ -771,12 +773,12 @@ pub enum Expr_ { /// /// <Vec<T> as SomeTrait>::SomeAssociatedItem /// ^~~~~ ^~~~~~~~~ ^~~~~~~~~~~~~~~~~~ -/// self_type trait_name item_name +/// self_type trait_name item_path #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)] pub struct QPath { pub self_type: P<Ty>, pub trait_ref: P<TraitRef>, - pub item_name: Ident, // FIXME(#20301) -- should use Name + pub item_path: PathSegment, } #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show, Copy)] diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index c45a4005339..2a704349295 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -454,7 +454,10 @@ pub fn noop_fold_qpath<T: Folder>(qpath: P<QPath>, fld: &mut T) -> P<QPath> { QPath { self_type: fld.fold_ty(qpath.self_type), trait_ref: qpath.trait_ref.map(|tr| fld.fold_trait_ref(tr)), - item_name: fld.fold_ident(qpath.item_name), + item_path: PathSegment { + identifier: fld.fold_ident(qpath.item_path.identifier), + parameters: fld.fold_path_parameters(qpath.item_path.parameters), + } } }) } @@ -1381,6 +1384,7 @@ pub fn noop_fold_expr<T: Folder>(Expr {id, node, span}: Expr, folder: &mut T) -> e2.map(|x| folder.fold_expr(x))) } ExprPath(pth) => ExprPath(folder.fold_path(pth)), + ExprQPath(qpath) => ExprQPath(folder.fold_qpath(qpath)), ExprBreak(opt_ident) => ExprBreak(opt_ident.map(|x| folder.fold_ident(x))), ExprAgain(opt_ident) => ExprAgain(opt_ident.map(|x| folder.fold_ident(x))), ExprRet(e) => ExprRet(e.map(|x| folder.fold_expr(x))), diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 9b6f8e6002d..ec6672d22a9 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -727,14 +727,7 @@ impl<'a> State<'a> { try!(self.print_bounds("", &bounds[])); } ast::TyQPath(ref qpath) => { - try!(word(&mut self.s, "<")); - try!(self.print_type(&*qpath.self_type)); - try!(space(&mut self.s)); - try!(self.word_space("as")); - try!(self.print_trait_ref(&*qpath.trait_ref)); - try!(word(&mut self.s, ">")); - try!(word(&mut self.s, "::")); - try!(self.print_ident(qpath.item_name)); + try!(self.print_qpath(&**qpath, false)) } ast::TyFixedLengthVec(ref ty, ref v) => { try!(word(&mut self.s, "[")); @@ -1749,6 +1742,7 @@ impl<'a> State<'a> { } } ast::ExprPath(ref path) => try!(self.print_path(path, true)), + ast::ExprQPath(ref qpath) => try!(self.print_qpath(&**qpath, true)), ast::ExprBreak(opt_ident) => { try!(word(&mut self.s, "break")); try!(space(&mut self.s)); @@ -1933,6 +1927,22 @@ impl<'a> State<'a> { Ok(()) } + fn print_qpath(&mut self, + qpath: &ast::QPath, + colons_before_params: bool) + -> IoResult<()> + { + try!(word(&mut self.s, "<")); + try!(self.print_type(&*qpath.self_type)); + try!(space(&mut self.s)); + try!(self.word_space("as")); + try!(self.print_trait_ref(&*qpath.trait_ref)); + try!(word(&mut self.s, ">")); + try!(word(&mut self.s, "::")); + try!(self.print_ident(qpath.item_path.identifier)); + self.print_path_parameters(&qpath.item_path.parameters, colons_before_params) + } + fn print_path_parameters(&mut self, parameters: &ast::PathParameters, colons_before_params: bool) diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 3f91304dcc5..7778b4fa34a 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -126,6 +126,9 @@ pub trait Visitor<'v> : Sized { fn visit_path(&mut self, path: &'v Path, _id: ast::NodeId) { walk_path(self, path) } + fn visit_qpath(&mut self, qpath_span: Span, qpath: &'v QPath) { + walk_qpath(self, qpath_span, qpath) + } fn visit_path_segment(&mut self, path_span: Span, path_segment: &'v PathSegment) { walk_path_segment(self, path_span, path_segment) } @@ -419,9 +422,7 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) { walk_ty_param_bounds_helper(visitor, bounds); } TyQPath(ref qpath) => { - visitor.visit_ty(&*qpath.self_type); - visitor.visit_trait_ref(&*qpath.trait_ref); - visitor.visit_ident(typ.span, qpath.item_name); + visitor.visit_qpath(typ.span, &**qpath); } TyFixedLengthVec(ref ty, ref expression) => { visitor.visit_ty(&**ty); @@ -450,6 +451,14 @@ pub fn walk_path<'v, V: Visitor<'v>>(visitor: &mut V, path: &'v Path) { } } +pub fn walk_qpath<'v, V: Visitor<'v>>(visitor: &mut V, + qpath_span: Span, + qpath: &'v QPath) { + visitor.visit_ty(&*qpath.self_type); + visitor.visit_trait_ref(&*qpath.trait_ref); + visitor.visit_path_segment(qpath_span, &qpath.item_path); +} + pub fn walk_path_segment<'v, V: Visitor<'v>>(visitor: &mut V, path_span: Span, segment: &'v PathSegment) { @@ -881,6 +890,9 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) { ExprPath(ref path) => { visitor.visit_path(path, expression.id) } + ExprQPath(ref qpath) => { + visitor.visit_qpath(expression.span, &**qpath) + } ExprBreak(_) | ExprAgain(_) => {} ExprRet(ref optional_expression) => { walk_expr_opt(visitor, optional_expression) |
