Implement <T>::method UFCS expression syntax.

This commit is contained in:
Eduard Burtescu
2015-02-17 19:29:13 +02:00
parent fdfb532d78
commit d31b9ebef5
40 changed files with 286 additions and 200 deletions

View File

@@ -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,7 +1076,7 @@ impl<'a> Parser<'a> {
}
pub fn parse_ty_path(&mut self) -> Ty_ {
TyPath(self.parse_path(LifetimeAndTypesWithoutColons))
TyPath(None, self.parse_path(LifetimeAndTypesWithoutColons))
}
/// parse a TyBareFn type:
@@ -1524,15 +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 mut path = self.parse_path(LifetimeAndTypesWithoutColons);
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);
path.segments.push(ast::PathSegment {
identifier: self.parse_ident(),
parameters: ast::PathParameters::none()
});
TyQPath(QPath { self_type: self_type, path: path })
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() {
@@ -2173,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) => {
@@ -2215,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 mut path = self.parse_path(LifetimeAndTypesWithoutColons);
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();
@@ -2237,9 +2270,14 @@ impl<'a> Parser<'a> {
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(QPath { self_type: self_type, path: path }));
return self.mk_expr(lo, hi, ExprPath(Some(qself), path));
}
if self.eat_keyword(keywords::Move) {
return self.parse_lambda_expr(CaptureByValue);
@@ -2379,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();
@@ -3421,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()
};
@@ -4808,7 +4846,7 @@ 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) => {
TyPath(None, ref path) => {
Some(TraitRef {
path: (*path).clone(),
ref_id: ty.id,