diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2014-11-15 16:55:27 -0500 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2014-11-18 12:32:37 -0500 |
| commit | c8a94c5dfaaf5f1dacc110bb81d292c4382554d9 (patch) | |
| tree | 82e6306f91f24f06e8be597672f9a3c82a206300 /src/libsyntax | |
| parent | 9c808ffee44afad69aeeeec835601d44bf0e9147 (diff) | |
| download | rust-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.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/ast_util.rs | 8 | ||||
| -rw-r--r-- | src/libsyntax/fold.rs | 10 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 17 | ||||
| -rw-r--r-- | src/libsyntax/print/pprust.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/visit.rs | 112 |
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); } } |
