diff options
| author | bors <bors@rust-lang.org> | 2015-01-15 17:12:55 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2015-01-15 17:12:55 +0000 |
| commit | 9ade482b3bdc7a967ca98f1f1138b596ef45191e (patch) | |
| tree | 84335c40ee3bd03d89f14d22a8d60c479a0d2c51 /src/libsyntax | |
| parent | 1c78ad937b4da9dd872b0a865025f3e2e885f90d (diff) | |
| parent | 85ba8178e2e995c0da6eb9268612baca8a6ba2e3 (diff) | |
| download | rust-9ade482b3bdc7a967ca98f1f1138b596ef45191e.tar.gz rust-9ade482b3bdc7a967ca98f1f1138b596ef45191e.zip | |
auto merge of #21077 : eddyb/rust/expr-qpath, r=nikomatsakis
Working towards #16293, this adds support for `<T as Trait>::method` in expressions.
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ast.rs | 6 | ||||
| -rw-r--r-- | src/libsyntax/fold.rs | 6 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 44 | ||||
| -rw-r--r-- | src/libsyntax/print/pprust.rs | 26 | ||||
| -rw-r--r-- | src/libsyntax/visit.rs | 18 |
5 files changed, 79 insertions, 21 deletions
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/parse/parser.rs b/src/libsyntax/parse/parser.rs index 33f9e35d8b7..543b7468499 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}; +use ast::{ExprMethodCall, ExprParen, ExprPath, ExprQPath}; use ast::{ExprRepeat, ExprRet, ExprStruct, ExprTup, ExprUnary}; use ast::{ExprVec, ExprWhile, ExprWhileLet, ExprForLoop, Field, FnDecl}; use ast::{FnUnboxedClosureKind, FnMutUnboxedClosureKind}; @@ -1573,7 +1573,10 @@ impl<'a> Parser<'a> { TyQPath(P(QPath { self_type: self_type, trait_ref: P(trait_ref), - item_name: item_name, + item_path: ast::PathSegment { + identifier: item_name, + parameters: ast::PathParameters::none() + } })) } else if self.check(&token::ModSep) || self.token.is_ident() || @@ -1894,11 +1897,7 @@ impl<'a> Parser<'a> { if !self.eat(&token::ModSep) { segments.push(ast::PathSegment { identifier: identifier, - parameters: ast::AngleBracketedParameters(ast::AngleBracketedParameterData { - lifetimes: Vec::new(), - types: OwnedSlice::empty(), - bindings: OwnedSlice::empty(), - }) + parameters: ast::PathParameters::none() }); return segments; } @@ -2253,6 +2252,37 @@ impl<'a> Parser<'a> { hi = self.last_span.hi; } _ => { + 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(); + self.expect(&token::Gt); + self.expect(&token::ModSep); + let item_name = self.parse_ident(); + let parameters = if self.eat(&token::ModSep) { + self.expect_lt(); + // Consumed `item::<`, go look for types + let (lifetimes, types, bindings) = + self.parse_generic_values_after_lt(); + ast::AngleBracketedParameters(ast::AngleBracketedParameterData { + lifetimes: lifetimes, + types: OwnedSlice::from_vec(types), + bindings: OwnedSlice::from_vec(bindings), + }) + } else { + ast::PathParameters::none() + }; + 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 + } + }))); + } if self.eat_keyword(keywords::Move) { return self.parse_lambda_expr(CaptureByValue); } 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) |
