diff options
| author | Manish Goregaokar <manishsmail@gmail.com> | 2015-02-25 10:27:03 +0530 |
|---|---|---|
| committer | Manish Goregaokar <manishsmail@gmail.com> | 2015-02-25 10:27:03 +0530 |
| commit | 9692f3bc941795dafac998294cc4e50e78efb4b5 (patch) | |
| tree | 1d5500407aadb3655b0820685e9ad6e947e373f2 /src/libsyntax | |
| parent | b711b6a5b2bc52ca27d75d5031239dbac92e42e2 (diff) | |
| parent | 848a7e692102643d99bb208b5a64199b6d6d87a1 (diff) | |
| download | rust-9692f3bc941795dafac998294cc4e50e78efb4b5.tar.gz rust-9692f3bc941795dafac998294cc4e50e78efb4b5.zip | |
Rollup merge of #22635 - kmcallister:macros-chapter, r=steveklabnik
r? @steveklabnik
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ast.rs | 38 | ||||
| -rw-r--r-- | src/libsyntax/ast_util.rs | 14 | ||||
| -rw-r--r-- | src/libsyntax/ext/build.rs | 52 | ||||
| -rw-r--r-- | src/libsyntax/ext/concat_idents.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/cmp/eq.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/cmp/ord.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/mod.rs | 6 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/primitive.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/ext/expand.rs | 11 | ||||
| -rw-r--r-- | src/libsyntax/feature_gate.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/fold.rs | 42 | ||||
| -rw-r--r-- | src/libsyntax/parse/mod.rs | 14 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 95 | ||||
| -rw-r--r-- | src/libsyntax/print/pprust.rs | 71 | ||||
| -rw-r--r-- | src/libsyntax/visit.rs | 29 |
15 files changed, 206 insertions, 178 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index effaac52716..6d6fdffa950 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -753,11 +753,10 @@ pub enum Expr_ { ExprIndex(P<Expr>, P<Expr>), ExprRange(Option<P<Expr>>, Option<P<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>), + /// Variable reference, possibly containing `::` and/or type + /// parameters, e.g. foo::bar::<baz>. Optionally "qualified", + /// e.g. `<Vec<T> as SomeTrait>::SomeType`. + ExprPath(Option<QSelf>, Path), ExprAddrOf(Mutability, P<Expr>), ExprBreak(Option<Ident>), @@ -778,16 +777,22 @@ pub enum Expr_ { ExprParen(P<Expr>) } -/// A "qualified path": +/// The explicit Self type in a "qualified path". The actual +/// path, including the trait and the associated item, is stored +/// sepparately. `position` represents the index of the associated +/// item qualified with this Self type. /// -/// <Vec<T> as SomeTrait>::SomeAssociatedItem -/// ^~~~~ ^~~~~~~~~ ^~~~~~~~~~~~~~~~~~ -/// self_type trait_name item_path +/// <Vec<T> as a::b::Trait>::AssociatedItem +/// ^~~~~ ~~~~~~~~~~~~~~^ +/// ty position = 3 +/// +/// <Vec<T>>::AssociatedItem +/// ^~~~~ ^ +/// ty position = 0 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub struct QPath { - pub self_type: P<Ty>, - pub trait_ref: P<TraitRef>, - pub item_path: PathSegment, +pub struct QSelf { + pub ty: P<Ty>, + pub position: usize } #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] @@ -1254,16 +1259,15 @@ pub enum Ty_ { TyBareFn(P<BareFnTy>), /// A tuple (`(A, B, C, D,...)`) TyTup(Vec<P<Ty>> ), - /// A path (`module::module::...::Type`) or primitive + /// A path (`module::module::...::Type`), optionally + /// "qualified", e.g. `<Vec<T> as SomeTrait>::SomeType`. /// /// Type parameters are stored in the Path itself - TyPath(Path, NodeId), + TyPath(Option<QSelf>, Path), /// Something like `A+B`. Note that `B` must always be a path. TyObjectSum(P<Ty>, TyParamBounds), /// A type like `for<'a> Foo<&'a Bar>` TyPolyTraitRef(TyParamBounds), - /// A "qualified path", e.g. `<Vec<T> as SomeTrait>::SomeType` - TyQPath(P<QPath>), /// No-op; kept solely so that we can pretty-print faithfully TyParen(P<Ty>), /// Unused for now diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index f1228c1d363..79f0433761d 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -134,7 +134,7 @@ pub fn unop_to_string(op: UnOp) -> &'static str { } pub fn is_path(e: P<Expr>) -> bool { - return match e.node { ExprPath(_) => true, _ => false }; + match e.node { ExprPath(..) => true, _ => false } } /// Get a string representation of a signed int type, with its value. @@ -488,9 +488,6 @@ impl<'a, 'v, O: IdVisitingOperation> Visitor<'v> for IdVisitor<'a, O> { fn visit_ty(&mut self, typ: &Ty) { self.operation.visit_id(typ.id); - if let TyPath(_, id) = typ.node { - self.operation.visit_id(id); - } visit::walk_ty(self, typ) } @@ -564,13 +561,18 @@ impl<'a, 'v, O: IdVisitingOperation> Visitor<'v> for IdVisitor<'a, O> { visit::walk_trait_item(self, tm); } - fn visit_lifetime_ref(&mut self, lifetime: &'v Lifetime) { + fn visit_lifetime_ref(&mut self, lifetime: &Lifetime) { self.operation.visit_id(lifetime.id); } - fn visit_lifetime_def(&mut self, def: &'v LifetimeDef) { + fn visit_lifetime_def(&mut self, def: &LifetimeDef) { self.visit_lifetime_ref(&def.lifetime); } + + fn visit_trait_ref(&mut self, trait_ref: &TraitRef) { + self.operation.visit_id(trait_ref.ref_id); + visit::walk_trait_ref(self, trait_ref); + } } pub fn visit_ids_for_inlined_item<O: IdVisitingOperation>(item: &InlinedItem, diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 656d507ed69..d916651b056 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -41,16 +41,16 @@ pub trait AstBuilder { -> ast::Path; fn qpath(&self, self_type: P<ast::Ty>, - trait_ref: P<ast::TraitRef>, - ident: ast::Ident ) - -> P<ast::QPath>; + trait_path: ast::Path, + ident: ast::Ident) + -> (ast::QSelf, ast::Path); fn qpath_all(&self, self_type: P<ast::Ty>, - trait_ref: P<ast::TraitRef>, + trait_path: ast::Path, ident: ast::Ident, lifetimes: Vec<ast::Lifetime>, types: Vec<P<ast::Ty>>, - bindings: Vec<P<ast::TypeBinding>> ) - -> P<ast::QPath>; + bindings: Vec<P<ast::TypeBinding>>) + -> (ast::QSelf, ast::Path); // types fn ty_mt(&self, ty: P<ast::Ty>, mutbl: ast::Mutability) -> ast::MutTy; @@ -114,7 +114,7 @@ pub trait AstBuilder { // expressions fn expr(&self, span: Span, node: ast::Expr_) -> P<ast::Expr>; fn expr_path(&self, path: ast::Path) -> P<ast::Expr>; - fn expr_qpath(&self, span: Span, qpath: P<ast::QPath>) -> P<ast::Expr>; + fn expr_qpath(&self, span: Span, qself: ast::QSelf, path: ast::Path) -> P<ast::Expr>; fn expr_ident(&self, span: Span, id: ast::Ident) -> P<ast::Expr>; fn expr_self(&self, span: Span) -> P<ast::Expr>; @@ -346,40 +346,40 @@ impl<'a> AstBuilder for ExtCtxt<'a> { /// Constructs a qualified path. /// - /// Constructs a path like `<self_type as trait_ref>::ident`. + /// Constructs a path like `<self_type as trait_path>::ident`. fn qpath(&self, self_type: P<ast::Ty>, - trait_ref: P<ast::TraitRef>, + trait_path: ast::Path, ident: ast::Ident) - -> P<ast::QPath> { - self.qpath_all(self_type, trait_ref, ident, Vec::new(), Vec::new(), Vec::new()) + -> (ast::QSelf, ast::Path) { + self.qpath_all(self_type, trait_path, ident, vec![], vec![], vec![]) } /// Constructs a qualified path. /// - /// Constructs a path like `<self_type as trait_ref>::ident<a, T, A=Bar>`. + /// Constructs a path like `<self_type as trait_path>::ident<'a, T, A=Bar>`. fn qpath_all(&self, self_type: P<ast::Ty>, - trait_ref: P<ast::TraitRef>, + trait_path: ast::Path, ident: ast::Ident, lifetimes: Vec<ast::Lifetime>, types: Vec<P<ast::Ty>>, - bindings: Vec<P<ast::TypeBinding>> ) - -> P<ast::QPath> { - let segment = ast::PathSegment { + bindings: Vec<P<ast::TypeBinding>>) + -> (ast::QSelf, ast::Path) { + let mut path = trait_path; + path.segments.push(ast::PathSegment { identifier: ident, parameters: ast::AngleBracketedParameters(ast::AngleBracketedParameterData { lifetimes: lifetimes, types: OwnedSlice::from_vec(types), bindings: OwnedSlice::from_vec(bindings), }) - }; + }); - P(ast::QPath { - self_type: self_type, - trait_ref: trait_ref, - item_path: segment, - }) + (ast::QSelf { + ty: self_type, + position: path.segments.len() - 1 + }, path) } fn ty_mt(&self, ty: P<ast::Ty>, mutbl: ast::Mutability) -> ast::MutTy { @@ -398,7 +398,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { } fn ty_path(&self, path: ast::Path) -> P<ast::Ty> { - self.ty(path.span, ast::TyPath(path, ast::DUMMY_NODE_ID)) + self.ty(path.span, ast::TyPath(None, path)) } fn ty_sum(&self, path: ast::Path, bounds: OwnedSlice<ast::TyParamBound>) -> P<ast::Ty> { @@ -603,12 +603,12 @@ impl<'a> AstBuilder for ExtCtxt<'a> { } fn expr_path(&self, path: ast::Path) -> P<ast::Expr> { - self.expr(path.span, ast::ExprPath(path)) + self.expr(path.span, ast::ExprPath(None, path)) } /// Constructs a QPath expression. - fn expr_qpath(&self, span: Span, qpath: P<ast::QPath>) -> P<ast::Expr> { - self.expr(span, ast::ExprQPath(qpath)) + fn expr_qpath(&self, span: Span, qself: ast::QSelf, path: ast::Path) -> P<ast::Expr> { + self.expr(span, ast::ExprPath(Some(qself), path)) } fn expr_ident(&self, span: Span, id: ast::Ident) -> P<ast::Expr> { diff --git a/src/libsyntax/ext/concat_idents.rs b/src/libsyntax/ext/concat_idents.rs index 9410a51e7a5..2303eb9645b 100644 --- a/src/libsyntax/ext/concat_idents.rs +++ b/src/libsyntax/ext/concat_idents.rs @@ -53,7 +53,7 @@ pub fn expand_syntax_ext<'cx>(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree] let e = P(ast::Expr { id: ast::DUMMY_NODE_ID, - node: ast::ExprPath( + node: ast::ExprPath(None, ast::Path { span: sp, global: false, diff --git a/src/libsyntax/ext/deriving/cmp/eq.rs b/src/libsyntax/ext/deriving/cmp/eq.rs index 91212a86958..80ef882745f 100644 --- a/src/libsyntax/ext/deriving/cmp/eq.rs +++ b/src/libsyntax/ext/deriving/cmp/eq.rs @@ -70,7 +70,7 @@ pub fn expand_deriving_eq<F>(cx: &mut ExtCtxt, generics: LifetimeBounds::empty(), explicit_self: borrowed_explicit_self(), args: vec!(borrowed_self()), - ret_ty: Literal(path!(bool)), + ret_ty: Literal(path_local!(bool)), attributes: attrs, combine_substructure: combine_substructure(box |a, b, c| { $f(a, b, c) diff --git a/src/libsyntax/ext/deriving/cmp/ord.rs b/src/libsyntax/ext/deriving/cmp/ord.rs index b109850a6bd..be4a33002aa 100644 --- a/src/libsyntax/ext/deriving/cmp/ord.rs +++ b/src/libsyntax/ext/deriving/cmp/ord.rs @@ -36,7 +36,7 @@ pub fn expand_deriving_ord<F>(cx: &mut ExtCtxt, generics: LifetimeBounds::empty(), explicit_self: borrowed_explicit_self(), args: vec!(borrowed_self()), - ret_ty: Literal(path!(bool)), + ret_ty: Literal(path_local!(bool)), attributes: attrs, combine_substructure: combine_substructure(box |cx, span, substr| { cs_op($op, $equal, cx, span, substr) diff --git a/src/libsyntax/ext/deriving/mod.rs b/src/libsyntax/ext/deriving/mod.rs index eee780f457c..973c8f5fa1e 100644 --- a/src/libsyntax/ext/deriving/mod.rs +++ b/src/libsyntax/ext/deriving/mod.rs @@ -30,6 +30,12 @@ macro_rules! path { ) } +macro_rules! path_local { + ($x:ident) => ( + ::ext::deriving::generic::ty::Path::new_local(stringify!($x)) + ) +} + macro_rules! pathvec_std { ($cx:expr, $first:ident :: $($rest:ident)::+) => ( if $cx.use_std { diff --git a/src/libsyntax/ext/deriving/primitive.rs b/src/libsyntax/ext/deriving/primitive.rs index 22c87d978c9..3b96292323a 100644 --- a/src/libsyntax/ext/deriving/primitive.rs +++ b/src/libsyntax/ext/deriving/primitive.rs @@ -38,7 +38,7 @@ pub fn expand_deriving_from_primitive<F>(cx: &mut ExtCtxt, name: "from_i64", generics: LifetimeBounds::empty(), explicit_self: None, - args: vec!(Literal(path!(i64))), + args: vec!(Literal(path_local!(i64))), ret_ty: Literal(Path::new_(pathvec_std!(cx, core::option::Option), None, vec!(box Self_), @@ -53,7 +53,7 @@ pub fn expand_deriving_from_primitive<F>(cx: &mut ExtCtxt, name: "from_u64", generics: LifetimeBounds::empty(), explicit_self: None, - args: vec!(Literal(path!(u64))), + args: vec!(Literal(path_local!(u64))), ret_ty: Literal(Path::new_(pathvec_std!(cx, core::option::Option), None, vec!(box Self_), diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 91bfe6f32dc..bea57ae14e4 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -41,7 +41,7 @@ pub fn expand_type(t: P<ast::Ty>, debug!("expanding type {:?} with impl_ty {:?}", t, impl_ty); let t = match (t.node.clone(), impl_ty) { // Expand uses of `Self` in impls to the concrete type. - (ast::Ty_::TyPath(ref path, _), Some(ref impl_ty)) => { + (ast::Ty_::TyPath(None, ref path), Some(ref impl_ty)) => { let path_as_ident = path_to_ident(path); // Note unhygenic comparison here. I think this is correct, since // even though `Self` is almost just a type parameter, the treatment @@ -1594,13 +1594,10 @@ mod test { impl<'v> Visitor<'v> for PathExprFinderContext { fn visit_expr(&mut self, expr: &ast::Expr) { - match expr.node { - ast::ExprPath(ref p) => { - self.path_accumulator.push(p.clone()); - // not calling visit_path, but it should be fine. - } - _ => visit::walk_expr(self, expr) + if let ast::ExprPath(None, ref p) = expr.node { + self.path_accumulator.push(p.clone()); } + visit::walk_expr(self, expr); } } diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 071158fcebb..32fd5b49f9a 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -549,7 +549,7 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> { fn visit_ty(&mut self, t: &ast::Ty) { match t.node { - ast::TyPath(ref p, _) => { + ast::TyPath(None, ref p) => { match &*p.segments { [ast::PathSegment { identifier, .. }] => { diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index dae830583c4..a556b2dfd2a 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -146,10 +146,6 @@ pub trait Folder : Sized { noop_fold_ty(t, self) } - fn fold_qpath(&mut self, t: P<QPath>) -> P<QPath> { - noop_fold_qpath(t, self) - } - fn fold_ty_binding(&mut self, t: P<TypeBinding>) -> P<TypeBinding> { noop_fold_ty_binding(t, self) } @@ -428,17 +424,19 @@ pub fn noop_fold_ty<T: Folder>(t: P<Ty>, fld: &mut T) -> P<Ty> { } TyTup(tys) => TyTup(tys.move_map(|ty| fld.fold_ty(ty))), TyParen(ty) => TyParen(fld.fold_ty(ty)), - TyPath(path, id) => { - let id = fld.new_id(id); - TyPath(fld.fold_path(path), id) + TyPath(qself, path) => { + let qself = qself.map(|QSelf { ty, position }| { + QSelf { + ty: fld.fold_ty(ty), + position: position + } + }); + TyPath(qself, fld.fold_path(path)) } TyObjectSum(ty, bounds) => { TyObjectSum(fld.fold_ty(ty), fld.fold_bounds(bounds)) } - TyQPath(qpath) => { - TyQPath(fld.fold_qpath(qpath)) - } TyFixedLengthVec(ty, e) => { TyFixedLengthVec(fld.fold_ty(ty), fld.fold_expr(e)) } @@ -453,19 +451,6 @@ pub fn noop_fold_ty<T: Folder>(t: P<Ty>, fld: &mut T) -> P<Ty> { }) } -pub fn noop_fold_qpath<T: Folder>(qpath: P<QPath>, fld: &mut T) -> P<QPath> { - qpath.map(|qpath| { - QPath { - self_type: fld.fold_ty(qpath.self_type), - trait_ref: qpath.trait_ref.map(|tr| fld.fold_trait_ref(tr)), - item_path: PathSegment { - identifier: fld.fold_ident(qpath.item_path.identifier), - parameters: fld.fold_path_parameters(qpath.item_path.parameters), - } - } - }) -} - pub fn noop_fold_foreign_mod<T: Folder>(ForeignMod {abi, items}: ForeignMod, fld: &mut T) -> ForeignMod { ForeignMod { @@ -1364,8 +1349,15 @@ pub fn noop_fold_expr<T: Folder>(Expr {id, node, span}: Expr, folder: &mut T) -> ExprRange(e1.map(|x| folder.fold_expr(x)), e2.map(|x| folder.fold_expr(x))) } - ExprPath(pth) => ExprPath(folder.fold_path(pth)), - ExprQPath(qpath) => ExprQPath(folder.fold_qpath(qpath)), + ExprPath(qself, path) => { + let qself = qself.map(|QSelf { ty, position }| { + QSelf { + ty: folder.fold_ty(ty), + position: position + } + }); + ExprPath(qself, folder.fold_path(path)) + } 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/parse/mod.rs b/src/libsyntax/parse/mod.rs index 43dfcbae57e..4d099529cb4 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -774,7 +774,7 @@ mod test { assert!(string_to_expr("a".to_string()) == P(ast::Expr{ id: ast::DUMMY_NODE_ID, - node: ast::ExprPath(ast::Path { + node: ast::ExprPath(None, ast::Path { span: sp(0, 1), global: false, segments: vec!( @@ -792,7 +792,7 @@ mod test { assert!(string_to_expr("::a::b".to_string()) == P(ast::Expr { id: ast::DUMMY_NODE_ID, - node: ast::ExprPath(ast::Path { + node: ast::ExprPath(None, ast::Path { span: sp(0, 6), global: true, segments: vec!( @@ -974,7 +974,7 @@ mod test { id: ast::DUMMY_NODE_ID, node:ast::ExprRet(Some(P(ast::Expr{ id: ast::DUMMY_NODE_ID, - node:ast::ExprPath(ast::Path{ + node:ast::ExprPath(None, ast::Path{ span: sp(7, 8), global: false, segments: vec!( @@ -995,7 +995,7 @@ mod test { P(Spanned{ node: ast::StmtExpr(P(ast::Expr { id: ast::DUMMY_NODE_ID, - node: ast::ExprPath(ast::Path { + node: ast::ExprPath(None, ast::Path { span:sp(0,1), global:false, segments: vec!( @@ -1041,7 +1041,7 @@ mod test { node: ast::ItemFn(P(ast::FnDecl { inputs: vec!(ast::Arg{ ty: P(ast::Ty{id: ast::DUMMY_NODE_ID, - node: ast::TyPath(ast::Path{ + node: ast::TyPath(None, ast::Path{ span:sp(10,13), global:false, segments: vec!( @@ -1051,7 +1051,7 @@ mod test { parameters: ast::PathParameters::none(), } ), - }, ast::DUMMY_NODE_ID), + }), span:sp(10,13) }), pat: P(ast::Pat { @@ -1084,7 +1084,7 @@ mod test { stmts: vec!(P(Spanned{ node: ast::StmtSemi(P(ast::Expr{ id: ast::DUMMY_NODE_ID, - node: ast::ExprPath( + node: ast::ExprPath(None, ast::Path{ span:sp(17,18), global:false, diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index fec33eddb91..f171e8279f4 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -25,7 +25,7 @@ use ast::{ExprAssign, ExprAssignOp, ExprBinary, ExprBlock, ExprBox}; use ast::{ExprBreak, ExprCall, ExprCast}; use ast::{ExprField, ExprTupField, ExprClosure, ExprIf, ExprIfLet, ExprIndex}; use ast::{ExprLit, ExprLoop, ExprMac, ExprRange}; -use ast::{ExprMethodCall, ExprParen, ExprPath, ExprQPath}; +use ast::{ExprMethodCall, ExprParen, ExprPath}; use ast::{ExprRepeat, ExprRet, ExprStruct, ExprTup, ExprUnary}; use ast::{ExprVec, ExprWhile, ExprWhileLet, ExprForLoop, Field, FnDecl}; use ast::{ForeignItem, ForeignItemStatic, ForeignItemFn, ForeignMod, FunctionRetTy}; @@ -43,7 +43,7 @@ use ast::{MethodImplItem, NamedField, UnNeg, NoReturn, NodeId, UnNot}; use ast::{Pat, PatEnum, PatIdent, PatLit, PatRange, PatRegion, PatStruct}; use ast::{PatTup, PatBox, PatWild, PatWildMulti, PatWildSingle}; use ast::{PolyTraitRef}; -use ast::{QPath, RequiredMethod}; +use ast::{QSelf, RequiredMethod}; use ast::{Return, BiShl, BiShr, Stmt, StmtDecl}; use ast::{StmtExpr, StmtSemi, StmtMac, StructDef, StructField}; use ast::{StructVariantKind, BiSub, StrStyle}; @@ -53,7 +53,7 @@ use ast::{TtDelimited, TtSequence, TtToken}; use ast::{TupleVariantKind, Ty, Ty_, TypeBinding}; use ast::{TyFixedLengthVec, TyBareFn}; use ast::{TyTypeof, TyInfer, TypeMethod}; -use ast::{TyParam, TyParamBound, TyParen, TyPath, TyPolyTraitRef, TyPtr, TyQPath}; +use ast::{TyParam, TyParamBound, TyParen, TyPath, TyPolyTraitRef, TyPtr}; use ast::{TyRptr, TyTup, TyU32, TyVec, UnUniq}; use ast::{TypeImplItem, TypeTraitItem, Typedef,}; use ast::{UnnamedField, UnsafeBlock}; @@ -143,7 +143,7 @@ macro_rules! maybe_whole_expr { _ => unreachable!() }; let span = $p.span; - Some($p.mk_expr(span.lo, span.hi, ExprPath(pt))) + Some($p.mk_expr(span.lo, span.hi, ExprPath(None, pt))) } token::Interpolated(token::NtBlock(_)) => { // FIXME: The following avoids an issue with lexical borrowck scopes, @@ -1076,8 +1076,7 @@ impl<'a> Parser<'a> { } pub fn parse_ty_path(&mut self) -> Ty_ { - let path = self.parse_path(LifetimeAndTypesWithoutColons); - TyPath(path, ast::DUMMY_NODE_ID) + TyPath(None, self.parse_path(LifetimeAndTypesWithoutColons)) } /// parse a TyBareFn type: @@ -1525,19 +1524,36 @@ impl<'a> Parser<'a> { } else if self.eat_lt() { // QUALIFIED PATH `<TYPE as TRAIT_REF>::item` let self_type = self.parse_ty_sum(); - self.expect_keyword(keywords::As); - let trait_ref = self.parse_trait_ref(); + + let mut path = if self.eat_keyword(keywords::As) { + self.parse_path(LifetimeAndTypesWithoutColons) + } else { + ast::Path { + span: self.span, + global: false, + segments: vec![] + } + }; + + let qself = QSelf { + ty: self_type, + position: path.segments.len() + }; + self.expect(&token::Gt); self.expect(&token::ModSep); - let item_name = self.parse_ident(); - TyQPath(P(QPath { - self_type: self_type, - trait_ref: P(trait_ref), - item_path: ast::PathSegment { - identifier: item_name, - parameters: ast::PathParameters::none() - } - })) + + path.segments.push(ast::PathSegment { + identifier: self.parse_ident(), + parameters: ast::PathParameters::none() + }); + + if path.segments.len() == 1 { + path.span.lo = self.last_span.lo; + } + path.span.hi = self.last_span.hi; + + TyPath(Some(qself), path) } else if self.check(&token::ModSep) || self.token.is_ident() || self.token.is_path() { @@ -2178,7 +2194,7 @@ impl<'a> Parser<'a> { }, token::Plain) => { self.bump(); let path = ast_util::ident_to_path(mk_sp(lo, hi), id); - ex = ExprPath(path); + ex = ExprPath(None, path); hi = self.last_span.hi; } token::OpenDelim(token::Bracket) => { @@ -2220,10 +2236,22 @@ impl<'a> Parser<'a> { if self.eat_lt() { // QUALIFIED PATH `<TYPE as TRAIT_REF>::item::<'a, T>` let self_type = self.parse_ty_sum(); - self.expect_keyword(keywords::As); - let trait_ref = self.parse_trait_ref(); + let mut path = if self.eat_keyword(keywords::As) { + self.parse_path(LifetimeAndTypesWithoutColons) + } else { + ast::Path { + span: self.span, + global: false, + segments: vec![] + } + }; + let qself = QSelf { + ty: self_type, + position: path.segments.len() + }; self.expect(&token::Gt); self.expect(&token::ModSep); + let item_name = self.parse_ident(); let parameters = if self.eat(&token::ModSep) { self.expect_lt(); @@ -2238,15 +2266,18 @@ impl<'a> Parser<'a> { } else { ast::PathParameters::none() }; + path.segments.push(ast::PathSegment { + identifier: item_name, + parameters: parameters + }); + + if path.segments.len() == 1 { + path.span.lo = self.last_span.lo; + } + path.span.hi = self.last_span.hi; + let hi = self.span.hi; - return self.mk_expr(lo, hi, ExprQPath(P(QPath { - self_type: self_type, - trait_ref: P(trait_ref), - item_path: ast::PathSegment { - identifier: item_name, - parameters: parameters - } - }))); + return self.mk_expr(lo, hi, ExprPath(Some(qself), path)); } if self.eat_keyword(keywords::Move) { return self.parse_lambda_expr(CaptureByValue); @@ -2386,7 +2417,7 @@ impl<'a> Parser<'a> { } hi = pth.span.hi; - ex = ExprPath(pth); + ex = ExprPath(None, pth); } else { // other literal expression let lit = self.parse_lit(); @@ -3428,7 +3459,7 @@ impl<'a> Parser<'a> { let end = if self.token.is_ident() || self.token.is_path() { let path = self.parse_path(LifetimeAndTypesWithColons); let hi = self.span.hi; - self.mk_expr(lo, hi, ExprPath(path)) + self.mk_expr(lo, hi, ExprPath(None, path)) } else { self.parse_literal_maybe_minus() }; @@ -4815,10 +4846,10 @@ impl<'a> Parser<'a> { let opt_trait = if could_be_trait && self.eat_keyword(keywords::For) { // New-style trait. Reinterpret the type as a trait. match ty.node { - TyPath(ref path, node_id) => { + TyPath(None, ref path) => { Some(TraitRef { path: (*path).clone(), - ref_id: node_id, + ref_id: ty.id, }) } _ => { diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 869dad867eb..af16e19c9f0 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -373,7 +373,7 @@ pub fn fn_block_to_string(p: &ast::FnDecl) -> String { } pub fn path_to_string(p: &ast::Path) -> String { - $to_string(|s| s.print_path(p, false)) + $to_string(|s| s.print_path(p, false, 0)) } pub fn ident_to_string(id: &ast::Ident) -> String { @@ -729,8 +729,11 @@ impl<'a> State<'a> { &generics, None)); } - ast::TyPath(ref path, _) => { - try!(self.print_path(path, false)); + ast::TyPath(None, ref path) => { + try!(self.print_path(path, false, 0)); + } + ast::TyPath(Some(ref qself), ref path) => { + try!(self.print_qpath(path, qself, false)) } ast::TyObjectSum(ref ty, ref bounds) => { try!(self.print_type(&**ty)); @@ -739,9 +742,6 @@ impl<'a> State<'a> { ast::TyPolyTraitRef(ref bounds) => { try!(self.print_bounds("", &bounds[..])); } - ast::TyQPath(ref qpath) => { - try!(self.print_qpath(&**qpath, false)) - } ast::TyFixedLengthVec(ref ty, ref v) => { try!(word(&mut self.s, "[")); try!(self.print_type(&**ty)); @@ -1018,7 +1018,7 @@ impl<'a> State<'a> { ast::ItemMac(codemap::Spanned { node: ast::MacInvocTT(ref pth, ref tts, _), ..}) => { try!(self.print_visibility(item.vis)); - try!(self.print_path(pth, false)); + try!(self.print_path(pth, false, 0)); try!(word(&mut self.s, "! ")); try!(self.print_ident(item.ident)); try!(self.cbox(indent_unit)); @@ -1033,7 +1033,7 @@ impl<'a> State<'a> { } fn print_trait_ref(&mut self, t: &ast::TraitRef) -> IoResult<()> { - self.print_path(&t.path, false) + self.print_path(&t.path, false, 0) } fn print_formal_lifetime_list(&mut self, lifetimes: &[ast::LifetimeDef]) -> IoResult<()> { @@ -1297,7 +1297,7 @@ impl<'a> State<'a> { ast::MethMac(codemap::Spanned { node: ast::MacInvocTT(ref pth, ref tts, _), ..}) => { // code copied from ItemMac: - try!(self.print_path(pth, false)); + try!(self.print_path(pth, false, 0)); try!(word(&mut self.s, "! ")); try!(self.cbox(indent_unit)); try!(self.popen()); @@ -1514,7 +1514,7 @@ impl<'a> State<'a> { match m.node { // I think it's reasonable to hide the ctxt here: ast::MacInvocTT(ref pth, ref tts, _) => { - try!(self.print_path(pth, false)); + try!(self.print_path(pth, false, 0)); try!(word(&mut self.s, "!")); match delim { token::Paren => try!(self.popen()), @@ -1584,7 +1584,7 @@ impl<'a> State<'a> { path: &ast::Path, fields: &[ast::Field], wth: &Option<P<ast::Expr>>) -> IoResult<()> { - try!(self.print_path(path, true)); + try!(self.print_path(path, true, 0)); if !(fields.is_empty() && wth.is_none()) { try!(word(&mut self.s, "{")); try!(self.commasep_cmnt( @@ -1852,8 +1852,12 @@ impl<'a> State<'a> { try!(self.print_expr(&**e)); } } - ast::ExprPath(ref path) => try!(self.print_path(path, true)), - ast::ExprQPath(ref qpath) => try!(self.print_qpath(&**qpath, true)), + ast::ExprPath(None, ref path) => { + try!(self.print_path(path, true, 0)) + } + ast::ExprPath(Some(ref qself), ref path) => { + try!(self.print_qpath(path, qself, true)) + } ast::ExprBreak(opt_ident) => { try!(word(&mut self.s, "break")); try!(space(&mut self.s)); @@ -2014,16 +2018,14 @@ impl<'a> State<'a> { fn print_path(&mut self, path: &ast::Path, - colons_before_params: bool) + colons_before_params: bool, + depth: usize) -> IoResult<()> { try!(self.maybe_print_comment(path.span.lo)); - if path.global { - try!(word(&mut self.s, "::")); - } - let mut first = true; - for segment in &path.segments { + let mut first = !path.global; + for segment in &path.segments[..path.segments.len()-depth] { if first { first = false } else { @@ -2039,19 +2041,24 @@ impl<'a> State<'a> { } fn print_qpath(&mut self, - qpath: &ast::QPath, + path: &ast::Path, + qself: &ast::QSelf, 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!(self.print_type(&qself.ty)); + if qself.position > 0 { + try!(space(&mut self.s)); + try!(self.word_space("as")); + let depth = path.segments.len() - qself.position; + try!(self.print_path(&path, false, depth)); + } 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) + let item_segment = path.segments.last().unwrap(); + try!(self.print_ident(item_segment.identifier)); + self.print_path_parameters(&item_segment.parameters, colons_before_params) } fn print_path_parameters(&mut self, @@ -2156,7 +2163,7 @@ impl<'a> State<'a> { } } ast::PatEnum(ref path, ref args_) => { - try!(self.print_path(path, true)); + try!(self.print_path(path, true, 0)); match *args_ { None => try!(word(&mut self.s, "(..)")), Some(ref args) => { @@ -2170,7 +2177,7 @@ impl<'a> State<'a> { } } ast::PatStruct(ref path, ref fields, etc) => { - try!(self.print_path(path, true)); + try!(self.print_path(path, true, 0)); try!(self.nbsp()); try!(self.word_space("{")); try!(self.commasep_cmnt( @@ -2555,7 +2562,7 @@ impl<'a> State<'a> { } } &ast::WherePredicate::EqPredicate(ast::WhereEqPredicate{ref path, ref ty, ..}) => { - try!(self.print_path(path, false)); + try!(self.print_path(path, false, 0)); try!(space(&mut self.s)); try!(self.word_space("=")); try!(self.print_type(&**ty)); @@ -2592,7 +2599,7 @@ impl<'a> State<'a> { pub fn print_view_path(&mut self, vp: &ast::ViewPath) -> IoResult<()> { match vp.node { ast::ViewPathSimple(ident, ref path) => { - try!(self.print_path(path, false)); + try!(self.print_path(path, false, 0)); // FIXME(#6993) can't compare identifiers directly here if path.segments.last().unwrap().identifier.name != @@ -2606,7 +2613,7 @@ impl<'a> State<'a> { } ast::ViewPathGlob(ref path) => { - try!(self.print_path(path, false)); + try!(self.print_path(path, false, 0)); word(&mut self.s, "::*") } @@ -2614,7 +2621,7 @@ impl<'a> State<'a> { if path.segments.is_empty() { try!(word(&mut self.s, "{")); } else { - try!(self.print_path(path, false)); + try!(self.print_path(path, false, 0)); try!(word(&mut self.s, "::{")); } try!(self.commasep(Inconsistent, &idents[..], |s, w| { diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 412bf0fa22a..33d8d56b4b1 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -125,9 +125,6 @@ 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) } @@ -399,16 +396,16 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) { walk_fn_ret_ty(visitor, &function_declaration.decl.output); walk_lifetime_decls_helper(visitor, &function_declaration.lifetimes); } - TyPath(ref path, id) => { - visitor.visit_path(path, id); + TyPath(ref maybe_qself, ref path) => { + if let Some(ref qself) = *maybe_qself { + visitor.visit_ty(&qself.ty); + } + visitor.visit_path(path, typ.id); } TyObjectSum(ref ty, ref bounds) => { visitor.visit_ty(&**ty); walk_ty_param_bounds_helper(visitor, bounds); } - TyQPath(ref qpath) => { - visitor.visit_qpath(typ.span, &**qpath); - } TyFixedLengthVec(ref ty, ref expression) => { visitor.visit_ty(&**ty); visitor.visit_expr(&**expression) @@ -436,14 +433,6 @@ 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) { @@ -869,12 +858,12 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) { walk_expr_opt(visitor, start); walk_expr_opt(visitor, end) } - ExprPath(ref path) => { + ExprPath(ref maybe_qself, ref path) => { + if let Some(ref qself) = *maybe_qself { + visitor.visit_ty(&qself.ty); + } 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) |
