diff options
| author | Vadim Petrochenkov <vadim.petrochenkov@gmail.com> | 2017-07-07 02:39:55 +0300 |
|---|---|---|
| committer | Vadim Petrochenkov <vadim.petrochenkov@gmail.com> | 2017-07-10 00:20:25 +0300 |
| commit | 287de2595a40c03d9ffe81f55c13c731fd01583f (patch) | |
| tree | a905bf090561b54245a31fcc2580b1682c55e522 /src/libsyntax | |
| parent | 8b1271fcdd5b5958c76c43084e544d075d7d5dfd (diff) | |
| download | rust-287de2595a40c03d9ffe81f55c13c731fd01583f.tar.gz rust-287de2595a40c03d9ffe81f55c13c731fd01583f.zip | |
Store all generic arguments for method calls in AST
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ast.rs | 11 | ||||
| -rw-r--r-- | src/libsyntax/ext/build.rs | 3 | ||||
| -rw-r--r-- | src/libsyntax/fold.rs | 11 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 48 | ||||
| -rw-r--r-- | src/libsyntax/print/pprust.rs | 16 | ||||
| -rw-r--r-- | src/libsyntax/visit.rs | 5 |
6 files changed, 36 insertions, 58 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index d00e29d954f..f7d9d532062 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -848,19 +848,16 @@ pub enum ExprKind { /// The first field resolves to the function itself, /// and the second field is the list of arguments Call(P<Expr>, Vec<P<Expr>>), - /// A method call (`x.foo::<Bar, Baz>(a, b, c, d)`) + /// A method call (`x.foo::<'static, Bar, Baz>(a, b, c, d)`) /// - /// The `SpannedIdent` is the identifier for the method name. - /// The vector of `Ty`s are the ascripted type parameters for the method + /// The `PathSegment` represents the method name and its generic arguments /// (within the angle brackets). - /// /// The first element of the vector of `Expr`s is the expression that evaluates /// to the object on which the method is being called on (the receiver), /// and the remaining elements are the rest of the arguments. - /// /// Thus, `x.foo::<Bar, Baz>(a, b, c, d)` is represented as - /// `ExprKind::MethodCall(foo, [Bar, Baz], [x, a, b, c, d])`. - MethodCall(SpannedIdent, Vec<P<Ty>>, Vec<P<Expr>>), + /// `ExprKind::MethodCall(PathSegment { foo, [Bar, Baz] }, [x, a, b, c, d])`. + MethodCall(PathSegment, Vec<P<Expr>>), /// A tuple (`(a, b, c ,d)`) Tup(Vec<P<Expr>>), /// A binary operation (For example: `a + b`, `a * b`) diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 03e5ea529e2..2555bf6dea7 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -673,9 +673,8 @@ impl<'a> AstBuilder for ExtCtxt<'a> { expr: P<ast::Expr>, ident: ast::Ident, mut args: Vec<P<ast::Expr>> ) -> P<ast::Expr> { - let id = Spanned { node: ident, span: span }; args.insert(0, expr); - self.expr(span, ast::ExprKind::MethodCall(id, Vec::new(), args)) + self.expr(span, ast::ExprKind::MethodCall(ast::PathSegment::from_ident(ident, span), args)) } fn expr_block(&self, b: P<ast::Block>) -> P<ast::Expr> { self.expr(b.span, ast::ExprKind::Block(b)) diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 1fc670ec9f7..eaec1eef172 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -1151,10 +1151,15 @@ pub fn noop_fold_expr<T: Folder>(Expr {id, node, span, attrs}: Expr, folder: &mu ExprKind::Call(folder.fold_expr(f), folder.fold_exprs(args)) } - ExprKind::MethodCall(i, tps, args) => { + ExprKind::MethodCall(seg, args) => { ExprKind::MethodCall( - respan(folder.new_span(i.span), folder.fold_ident(i.node)), - tps.move_map(|x| folder.fold_ty(x)), + PathSegment { + identifier: folder.fold_ident(seg.identifier), + span: folder.new_span(seg.span), + parameters: seg.parameters.map(|ps| { + ps.map(|ps| folder.fold_path_parameters(ps)) + }), + }, folder.fold_exprs(args)) } ExprKind::Binary(binop, lhs, rhs) => { diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index f605c464310..093ab0073f0 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -9,7 +9,7 @@ // except according to those terms. use abi::{self, Abi}; -use ast::{AttrStyle, BareFnTy}; +use ast::{AngleBracketedParameterData, AttrStyle, BareFnTy}; use ast::{RegionTyParamBound, TraitTyParamBound, TraitBoundModifier}; use ast::Unsafety; use ast::{Mod, Arg, Arm, Attribute, BindingMode, TraitItemKind}; @@ -1831,11 +1831,7 @@ impl<'a> Parser<'a> { let parameters = if parse_generics && self.eat_lt() { let (lifetimes, types, bindings) = self.parse_generic_args()?; self.expect_gt()?; - ast::AngleBracketedParameterData { - lifetimes: lifetimes, - types: types, - bindings: bindings, - }.into() + AngleBracketedParameterData { lifetimes, types, bindings }.into() } else if self.eat(&token::OpenDelim(token::Paren)) { let lo = self.prev_span; @@ -1898,11 +1894,7 @@ impl<'a> Parser<'a> { segments.push(PathSegment { identifier: identifier, span: ident_span, - parameters: ast::AngleBracketedParameterData { - lifetimes: lifetimes, - types: types, - bindings: bindings, - }.into(), + parameters: AngleBracketedParameterData { lifetimes, types, bindings }.into(), }); // Consumed `a::b::<T,U>`, check for `::` before proceeding @@ -2023,14 +2015,6 @@ impl<'a> Parser<'a> { ExprKind::Call(f, args) } - fn mk_method_call(&mut self, - ident: ast::SpannedIdent, - tps: Vec<P<Ty>>, - args: Vec<P<Expr>>) - -> ast::ExprKind { - ExprKind::MethodCall(ident, tps, args) - } - pub fn mk_index(&mut self, expr: P<Expr>, idx: P<Expr>) -> ast::ExprKind { ExprKind::Index(expr, idx) } @@ -2460,7 +2444,7 @@ impl<'a> Parser<'a> { // parsing into an expression. fn parse_dot_suffix(&mut self, ident: Ident, ident_span: Span, self_value: P<Expr>, lo: Span) -> PResult<'a, P<Expr>> { - let (_, tys, bindings) = if self.eat(&token::ModSep) { + let (lifetimes, types, bindings) = if self.eat(&token::ModSep) { self.expect_lt()?; let args = self.parse_generic_args()?; self.expect_gt()?; @@ -2469,11 +2453,6 @@ impl<'a> Parser<'a> { (Vec::new(), Vec::new(), Vec::new()) }; - if !bindings.is_empty() { - let prev_span = self.prev_span; - self.span_err(prev_span, "type bindings are only permitted on trait paths"); - } - Ok(match self.token { // expr.f() method call. token::OpenDelim(token::Paren) => { @@ -2486,17 +2465,20 @@ impl<'a> Parser<'a> { let hi = self.prev_span; es.insert(0, self_value); - let id = respan(ident_span.to(ident_span), ident); - let nd = self.mk_method_call(id, tys, es); - self.mk_expr(lo.to(hi), nd, ThinVec::new()) + let seg = PathSegment { + identifier: ident, + span: ident_span.to(ident_span), + parameters: AngleBracketedParameterData { lifetimes, types, bindings }.into(), + }; + self.mk_expr(lo.to(hi), ExprKind::MethodCall(seg, es), ThinVec::new()) } // Field access. _ => { - if !tys.is_empty() { - let prev_span = self.prev_span; - self.span_err(prev_span, - "field expressions may not \ - have type parameters"); + if let Some(generic_arg_span) = lifetimes.get(0).map(|x| x.span).or_else(|| + types.get(0).map(|x| x.span)).or_else(|| + bindings.get(0).map(|x| x.span)) { + self.span_err(generic_arg_span, + "field expressions may not have generic arguments"); } let id = respan(ident_span.to(ident_span), ident); diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index d449e412d6c..51c48f15f29 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1951,18 +1951,14 @@ impl<'a> State<'a> { } fn print_expr_method_call(&mut self, - ident: ast::SpannedIdent, - tys: &[P<ast::Ty>], + segment: &ast::PathSegment, args: &[P<ast::Expr>]) -> io::Result<()> { let base_args = &args[1..]; self.print_expr(&args[0])?; word(&mut self.s, ".")?; - self.print_ident(ident.node)?; - if !tys.is_empty() { - word(&mut self.s, "::<")?; - self.commasep(Inconsistent, tys, - |s, ty| s.print_type(ty))?; - word(&mut self.s, ">")?; + self.print_ident(segment.identifier)?; + if let Some(ref parameters) = segment.parameters { + self.print_path_parameters(parameters, true)?; } self.print_call_post(base_args) } @@ -2041,8 +2037,8 @@ impl<'a> State<'a> { ast::ExprKind::Call(ref func, ref args) => { self.print_expr_call(func, &args[..])?; } - ast::ExprKind::MethodCall(ident, ref tys, ref args) => { - self.print_expr_method_call(ident, &tys[..], &args[..])?; + ast::ExprKind::MethodCall(ref segment, ref args) => { + self.print_expr_method_call(segment, &args[..])?; } ast::ExprKind::Binary(op, ref lhs, ref rhs) => { self.print_expr_binary(op, lhs, rhs)?; diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 18a0949af0e..f4ac7e341ce 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -674,9 +674,8 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) { visitor.visit_expr(callee_expression); walk_list!(visitor, visit_expr, arguments); } - ExprKind::MethodCall(ref ident, ref types, ref arguments) => { - visitor.visit_ident(ident.span, ident.node); - walk_list!(visitor, visit_ty, types); + ExprKind::MethodCall(ref segment, ref arguments) => { + visitor.visit_path_segment(expression.span, segment); walk_list!(visitor, visit_expr, arguments); } ExprKind::Binary(_, ref left_expression, ref right_expression) => { |
