about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2014-11-15 16:55:27 -0500
committerNiko Matsakis <niko@alum.mit.edu>2014-11-18 12:32:37 -0500
commitc8a94c5dfaaf5f1dacc110bb81d292c4382554d9 (patch)
tree82e6306f91f24f06e8be597672f9a3c82a206300 /src/libsyntax
parent9c808ffee44afad69aeeeec835601d44bf0e9147 (diff)
downloadrust-c8a94c5dfaaf5f1dacc110bb81d292c4382554d9.tar.gz
rust-c8a94c5dfaaf5f1dacc110bb81d292c4382554d9.zip
Convert TyPolyTraitRef to accept arbitary bounds, so that things like
`Box<for<'a> Foo<&'a T> + 'a>` can be accepted. Also cleanup the visitor/fold
in general, exposing more callbacks.
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/ast.rs2
-rw-r--r--src/libsyntax/ast_util.rs8
-rw-r--r--src/libsyntax/fold.rs10
-rw-r--r--src/libsyntax/parse/parser.rs17
-rw-r--r--src/libsyntax/print/pprust.rs4
-rw-r--r--src/libsyntax/visit.rs112
6 files changed, 97 insertions, 56 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 0cb80d4c153..15e14902727 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -1154,7 +1154,7 @@ pub enum Ty_ {
     /// Type parameters are stored in the Path itself
     TyPath(Path, Option<TyParamBounds>, NodeId), // for #7264; see above
     /// A type like `for<'a> Foo<&'a Bar>`
-    TyPolyTraitRef(P<PolyTraitRef>),
+    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
diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs
index 2e3a15bfd4b..30cdecbc851 100644
--- a/src/libsyntax/ast_util.rs
+++ b/src/libsyntax/ast_util.rs
@@ -494,10 +494,10 @@ impl<'a, 'v, O: IdVisitingOperation> Visitor<'v> for IdVisitor<'a, O> {
         }
 
         visit::walk_fn(self,
-                        function_kind,
-                        function_declaration,
-                        block,
-                        span);
+                       function_kind,
+                       function_declaration,
+                       block,
+                       span);
 
         if !self.pass_through_items {
             match function_kind {
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index 56d91282437..b3137ff5f7e 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -445,10 +445,12 @@ pub fn noop_fold_ty<T: Folder>(t: P<Ty>, fld: &mut T) -> P<Ty> {
             TyFixedLengthVec(ty, e) => {
                 TyFixedLengthVec(fld.fold_ty(ty), fld.fold_expr(e))
             }
-            TyTypeof(expr) => TyTypeof(fld.fold_expr(expr)),
-            TyPolyTraitRef(poly_trait_ref) => {
-                TyPolyTraitRef(poly_trait_ref.map(|p| fld.fold_poly_trait_ref(p)))
-            },
+            TyTypeof(expr) => {
+                TyTypeof(fld.fold_expr(expr))
+            }
+            TyPolyTraitRef(bounds) => {
+                TyPolyTraitRef(bounds.move_map(|b| fld.fold_ty_param_bound(b)))
+            }
         },
         span: fld.new_span(span)
     })
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 98479d65cbb..40c4ac9f8c0 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -1023,10 +1023,21 @@ impl<'a> Parser<'a> {
             self.parse_ty_bare_fn_or_ty_closure(lifetime_defs)
         } else if self.token == token::ModSep ||
                   self.token.is_ident() ||
-                  self.token.is_path() {
+                  self.token.is_path()
+        {
             let trait_ref = self.parse_trait_ref();
-            TyPolyTraitRef(P(PolyTraitRef { bound_lifetimes: lifetime_defs,
-                                            trait_ref: trait_ref }))
+            let poly_trait_ref = ast::PolyTraitRef { bound_lifetimes: lifetime_defs,
+                                                     trait_ref: trait_ref };
+            let other_bounds = if self.eat(&token::BinOp(token::Plus)) {
+                self.parse_ty_param_bounds()
+            } else {
+                OwnedSlice::empty()
+            };
+            let all_bounds =
+                Some(TraitTyParamBound(poly_trait_ref)).into_iter()
+                .chain(other_bounds.into_vec().into_iter())
+                .collect();
+            ast::TyPolyTraitRef(all_bounds)
         } else {
             self.parse_ty_closure(lifetime_defs)
         }
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 0543b80f208..e6e0c33a42d 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -739,8 +739,8 @@ impl<'a> State<'a> {
             ast::TyPath(ref path, ref bounds, _) => {
                 try!(self.print_bounded_path(path, bounds));
             }
-            ast::TyPolyTraitRef(ref poly_trait_ref) => {
-                try!(self.print_poly_trait_ref(&**poly_trait_ref));
+            ast::TyPolyTraitRef(ref bounds) => {
+                try!(self.print_bounds("", bounds));
             }
             ast::TyQPath(ref qpath) => {
                 try!(word(&mut self.s, "<"));
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index 2960c28a8b7..efe1e18eda9 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -78,6 +78,9 @@ pub trait Visitor<'v> {
     fn visit_ty_method(&mut self, t: &'v TypeMethod) { walk_ty_method(self, t) }
     fn visit_trait_item(&mut self, t: &'v TraitItem) { walk_trait_item(self, t) }
     fn visit_trait_ref(&mut self, t: &'v TraitRef) { walk_trait_ref(self, t) }
+    fn visit_ty_param_bound(&mut self, bounds: &'v TyParamBound) {
+        walk_ty_param_bound(self, bounds)
+    }
     fn visit_poly_trait_ref(&mut self, t: &'v PolyTraitRef) {
         walk_poly_trait_ref(self, t)
     }
@@ -119,6 +122,12 @@ pub trait Visitor<'v> {
     fn visit_path(&mut self, path: &'v Path, _id: ast::NodeId) {
         walk_path(self, path)
     }
+    fn visit_path_segment(&mut self, path_span: Span, path_segment: &'v PathSegment) {
+        walk_path_segment(self, path_span, path_segment)
+    }
+    fn visit_path_parameters(&mut self, path_span: Span, path_parameters: &'v PathParameters) {
+        walk_path_parameters(self, path_span, path_parameters)
+    }
     fn visit_attribute(&mut self, _attr: &'v Attribute) {}
 }
 
@@ -170,7 +179,7 @@ pub fn walk_view_item<'v, V: Visitor<'v>>(visitor: &mut V, vi: &'v ViewItem) {
                 ViewPathGlob(ref path, id) => {
                     visitor.visit_path(path, id);
                 }
-                ViewPathList(ref path, ref list, _) => {
+                ViewPathList(ref prefix, ref list, _) => {
                     for id in list.iter() {
                         match id.node {
                             PathListIdent { name, .. } => {
@@ -179,7 +188,10 @@ pub fn walk_view_item<'v, V: Visitor<'v>>(visitor: &mut V, vi: &'v ViewItem) {
                             PathListMod { .. } => ()
                         }
                     }
-                    walk_path(visitor, path);
+
+                    // Note that the `prefix` here is not a complete
+                    // path, so we don't use `visit_path`.
+                    walk_path(visitor, prefix);
                 }
             }
         }
@@ -212,7 +224,7 @@ pub fn walk_poly_trait_ref<'v, V>(visitor: &mut V,
                                          trait_ref: &'v PolyTraitRef)
     where V: Visitor<'v>
 {
-    walk_lifetime_decls(visitor, &trait_ref.bound_lifetimes);
+    walk_lifetime_decls_helper(visitor, &trait_ref.bound_lifetimes);
     visitor.visit_trait_ref(&trait_ref.trait_ref);
 }
 
@@ -290,7 +302,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
         }
         ItemTrait(ref generics, _, ref bounds, ref methods) => {
             visitor.visit_generics(generics);
-            walk_ty_param_bounds(visitor, bounds);
+            walk_ty_param_bounds_helper(visitor, bounds);
             for method in methods.iter() {
                 visitor.visit_trait_item(method)
             }
@@ -363,29 +375,29 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) {
                 visitor.visit_ty(&*argument.ty)
             }
             walk_fn_ret_ty(visitor, &function_declaration.decl.output);
-            walk_ty_param_bounds(visitor, &function_declaration.bounds);
-            walk_lifetime_decls(visitor, &function_declaration.lifetimes);
+            walk_ty_param_bounds_helper(visitor, &function_declaration.bounds);
+            walk_lifetime_decls_helper(visitor, &function_declaration.lifetimes);
         }
         TyProc(ref function_declaration) => {
             for argument in function_declaration.decl.inputs.iter() {
                 visitor.visit_ty(&*argument.ty)
             }
             walk_fn_ret_ty(visitor, &function_declaration.decl.output);
-            walk_ty_param_bounds(visitor, &function_declaration.bounds);
-            walk_lifetime_decls(visitor, &function_declaration.lifetimes);
+            walk_ty_param_bounds_helper(visitor, &function_declaration.bounds);
+            walk_lifetime_decls_helper(visitor, &function_declaration.lifetimes);
         }
         TyBareFn(ref function_declaration) => {
             for argument in function_declaration.decl.inputs.iter() {
                 visitor.visit_ty(&*argument.ty)
             }
             walk_fn_ret_ty(visitor, &function_declaration.decl.output);
-            walk_lifetime_decls(visitor, &function_declaration.lifetimes);
+            walk_lifetime_decls_helper(visitor, &function_declaration.lifetimes);
         }
         TyPath(ref path, ref opt_bounds, id) => {
             visitor.visit_path(path, id);
             match *opt_bounds {
                 Some(ref bounds) => {
-                    walk_ty_param_bounds(visitor, bounds);
+                    walk_ty_param_bounds_helper(visitor, bounds);
                 }
                 None => { }
             }
@@ -399,8 +411,8 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) {
             visitor.visit_ty(&**ty);
             visitor.visit_expr(&**expression)
         }
-        TyPolyTraitRef(ref poly_trait_ref) => {
-            visitor.visit_poly_trait_ref(&**poly_trait_ref)
+        TyPolyTraitRef(ref bounds) => {
+            walk_ty_param_bounds_helper(visitor, bounds)
         }
         TyTypeof(ref expression) => {
             visitor.visit_expr(&**expression)
@@ -409,8 +421,8 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) {
     }
 }
 
-fn walk_lifetime_decls<'v, V: Visitor<'v>>(visitor: &mut V,
-                                           lifetimes: &'v Vec<LifetimeDef>) {
+pub fn walk_lifetime_decls_helper<'v, V: Visitor<'v>>(visitor: &mut V,
+                                                      lifetimes: &'v Vec<LifetimeDef>) {
     for l in lifetimes.iter() {
         visitor.visit_lifetime_decl(l);
     }
@@ -418,24 +430,35 @@ fn walk_lifetime_decls<'v, V: Visitor<'v>>(visitor: &mut V,
 
 pub fn walk_path<'v, V: Visitor<'v>>(visitor: &mut V, path: &'v Path) {
     for segment in path.segments.iter() {
-        visitor.visit_ident(path.span, segment.identifier);
+        visitor.visit_path_segment(path.span, segment);
+    }
+}
 
-        match segment.parameters {
-            ast::AngleBracketedParameters(ref data) => {
-                for typ in data.types.iter() {
-                    visitor.visit_ty(&**typ);
-                }
-                for lifetime in data.lifetimes.iter() {
-                    visitor.visit_lifetime_ref(lifetime);
-                }
+pub fn walk_path_segment<'v, V: Visitor<'v>>(visitor: &mut V,
+                                             path_span: Span,
+                                             segment: &'v PathSegment) {
+    visitor.visit_ident(path_span, segment.identifier);
+    visitor.visit_path_parameters(path_span, &segment.parameters);
+}
+
+pub fn walk_path_parameters<'v, V: Visitor<'v>>(visitor: &mut V,
+                                                _path_span: Span,
+                                                path_parameters: &'v PathParameters) {
+    match *path_parameters {
+        ast::AngleBracketedParameters(ref data) => {
+            for typ in data.types.iter() {
+                visitor.visit_ty(&**typ);
             }
-            ast::ParenthesizedParameters(ref data) => {
-                for typ in data.inputs.iter() {
-                    visitor.visit_ty(&**typ);
-                }
-                for typ in data.output.iter() {
-                    visitor.visit_ty(&**typ);
-                }
+            for lifetime in data.lifetimes.iter() {
+                visitor.visit_lifetime_ref(lifetime);
+            }
+        }
+        ast::ParenthesizedParameters(ref data) => {
+            for typ in data.inputs.iter() {
+                visitor.visit_ty(&**typ);
+            }
+            for typ in data.output.iter() {
+                visitor.visit_ty(&**typ);
             }
         }
     }
@@ -511,32 +534,37 @@ pub fn walk_foreign_item<'v, V: Visitor<'v>>(visitor: &mut V,
     }
 }
 
-pub fn walk_ty_param_bounds<'v, V: Visitor<'v>>(visitor: &mut V,
-                                                bounds: &'v OwnedSlice<TyParamBound>) {
+pub fn walk_ty_param_bounds_helper<'v, V: Visitor<'v>>(visitor: &mut V,
+                                                       bounds: &'v OwnedSlice<TyParamBound>) {
     for bound in bounds.iter() {
-        match *bound {
-            TraitTyParamBound(ref typ) => {
-                visitor.visit_poly_trait_ref(typ)
-            }
-            RegionTyParamBound(ref lifetime) => {
-                visitor.visit_lifetime_ref(lifetime);
-            }
+        visitor.visit_ty_param_bound(bound)
+    }
+}
+
+pub fn walk_ty_param_bound<'v, V: Visitor<'v>>(visitor: &mut V,
+                                               bound: &'v TyParamBound) {
+    match *bound {
+        TraitTyParamBound(ref typ) => {
+            visitor.visit_poly_trait_ref(typ);
+        }
+        RegionTyParamBound(ref lifetime) => {
+            visitor.visit_lifetime_ref(lifetime);
         }
     }
 }
 
 pub fn walk_generics<'v, V: Visitor<'v>>(visitor: &mut V, generics: &'v Generics) {
     for type_parameter in generics.ty_params.iter() {
-        walk_ty_param_bounds(visitor, &type_parameter.bounds);
+        walk_ty_param_bounds_helper(visitor, &type_parameter.bounds);
         match type_parameter.default {
             Some(ref ty) => visitor.visit_ty(&**ty),
             None => {}
         }
     }
-    walk_lifetime_decls(visitor, &generics.lifetimes);
+    walk_lifetime_decls_helper(visitor, &generics.lifetimes);
     for predicate in generics.where_clause.predicates.iter() {
         visitor.visit_ident(predicate.span, predicate.ident);
-        walk_ty_param_bounds(visitor, &predicate.bounds);
+        walk_ty_param_bounds_helper(visitor, &predicate.bounds);
     }
 }