about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>2017-07-07 02:39:55 +0300
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>2017-07-10 00:20:25 +0300
commit287de2595a40c03d9ffe81f55c13c731fd01583f (patch)
treea905bf090561b54245a31fcc2580b1682c55e522 /src/libsyntax
parent8b1271fcdd5b5958c76c43084e544d075d7d5dfd (diff)
downloadrust-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.rs11
-rw-r--r--src/libsyntax/ext/build.rs3
-rw-r--r--src/libsyntax/fold.rs11
-rw-r--r--src/libsyntax/parse/parser.rs48
-rw-r--r--src/libsyntax/print/pprust.rs16
-rw-r--r--src/libsyntax/visit.rs5
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) => {