diff options
| author | Nick Cameron <ncameron@mozilla.com> | 2015-02-05 21:46:01 +1300 |
|---|---|---|
| committer | Nick Cameron <ncameron@mozilla.com> | 2015-02-09 09:29:53 +1300 |
| commit | 8122ce81d0909bed39c6df3e47bc751851bded84 (patch) | |
| tree | 438c010af390cb3d7b67bbfe422e0772c80ca006 /src/libsyntax | |
| parent | 012e9643e4d6f6fa449ca4f4e5e3fc9fb8e536db (diff) | |
| download | rust-8122ce81d0909bed39c6df3e47bc751851bded84.tar.gz rust-8122ce81d0909bed39c6df3e47bc751851bded84.zip | |
Accept quantification of lifetimes outside the self type in where clauses.
Closes #20022
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ast.rs | 3 | ||||
| -rw-r--r-- | src/libsyntax/ext/build.rs | 9 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/generic/mod.rs | 1 | ||||
| -rw-r--r-- | src/libsyntax/fold.rs | 7 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 33 |
5 files changed, 42 insertions, 11 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 71259ff5d9a..f8793f81b19 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -443,6 +443,7 @@ pub enum WherePredicate { #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub struct WhereBoundPredicate { pub span: Span, + pub bound_lifetimes: Vec<LifetimeDef>, pub bounded_ty: P<Ty>, pub bounds: OwnedSlice<TyParamBound>, } @@ -1535,6 +1536,8 @@ pub struct PolyTraitRef { /// The `Foo<&'a T>` in `<'a> Foo<&'a T>` pub trait_ref: TraitRef, + + pub span: Span, } #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index a7d1baf08be..6d9a2fdb9f1 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -70,7 +70,7 @@ pub trait AstBuilder { default: Option<P<ast::Ty>>) -> ast::TyParam; fn trait_ref(&self, path: ast::Path) -> ast::TraitRef; - fn poly_trait_ref(&self, path: ast::Path) -> ast::PolyTraitRef; + fn poly_trait_ref(&self, span: Span, path: ast::Path) -> ast::PolyTraitRef; fn typarambound(&self, path: ast::Path) -> ast::TyParamBound; fn lifetime(&self, span: Span, ident: ast::Name) -> ast::Lifetime; fn lifetime_def(&self, @@ -442,15 +442,16 @@ impl<'a> AstBuilder for ExtCtxt<'a> { } } - fn poly_trait_ref(&self, path: ast::Path) -> ast::PolyTraitRef { + fn poly_trait_ref(&self, span: Span, path: ast::Path) -> ast::PolyTraitRef { ast::PolyTraitRef { bound_lifetimes: Vec::new(), - trait_ref: self.trait_ref(path) + trait_ref: self.trait_ref(path), + span: span, } } fn typarambound(&self, path: ast::Path) -> ast::TyParamBound { - ast::TraitTyParamBound(self.poly_trait_ref(path), ast::TraitBoundModifier::None) + ast::TraitTyParamBound(self.poly_trait_ref(path.span, path), ast::TraitBoundModifier::None) } fn lifetime(&self, span: Span, name: ast::Name) -> ast::Lifetime { diff --git a/src/libsyntax/ext/deriving/generic/mod.rs b/src/libsyntax/ext/deriving/generic/mod.rs index 28573ef757b..d9242417e04 100644 --- a/src/libsyntax/ext/deriving/generic/mod.rs +++ b/src/libsyntax/ext/deriving/generic/mod.rs @@ -443,6 +443,7 @@ impl<'a> TraitDef<'a> { ast::WherePredicate::BoundPredicate(ref wb) => { ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate { span: self.span, + bound_lifetimes: wb.bound_lifetimes.clone(), bounded_ty: wb.bounded_ty.clone(), bounds: OwnedSlice::from_vec(wb.bounds.iter().map(|b| b.clone()).collect()) }) diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index b0ddb655882..8f1d15f6da8 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -806,10 +806,12 @@ pub fn noop_fold_where_predicate<T: Folder>( fld: &mut T) -> WherePredicate { match pred { - ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate{bounded_ty, + ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate{bound_lifetimes, + bounded_ty, bounds, span}) => { ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate { + bound_lifetimes: fld.fold_lifetime_defs(bound_lifetimes), bounded_ty: fld.fold_ty(bounded_ty), bounds: bounds.move_map(|x| fld.fold_ty_param_bound(x)), span: fld.new_span(span) @@ -895,7 +897,8 @@ pub fn noop_fold_trait_ref<T: Folder>(p: TraitRef, fld: &mut T) -> TraitRef { pub fn noop_fold_poly_trait_ref<T: Folder>(p: PolyTraitRef, fld: &mut T) -> PolyTraitRef { ast::PolyTraitRef { bound_lifetimes: fld.fold_lifetime_defs(p.bound_lifetimes), - trait_ref: fld.fold_trait_ref(p.trait_ref) + trait_ref: fld.fold_trait_ref(p.trait_ref), + span: fld.new_span(p.span), } } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 3107f47de78..fd2f0685cab 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1036,6 +1036,8 @@ impl<'a> Parser<'a> { */ // parse <'lt> + let lo = self.span.lo; + let lifetime_defs = self.parse_late_bound_lifetime_defs(); // examine next token to decide to do @@ -1047,9 +1049,11 @@ impl<'a> Parser<'a> { self.token.is_ident() || self.token.is_path() { + let hi = self.span.hi; let trait_ref = self.parse_trait_ref(); let poly_trait_ref = ast::PolyTraitRef { bound_lifetimes: lifetime_defs, - trait_ref: trait_ref }; + trait_ref: trait_ref, + span: mk_sp(lo, hi)}; let other_bounds = if self.eat(&token::BinOp(token::Plus)) { self.parse_ty_param_bounds(BoundParsingMode::Bare) } else { @@ -4070,7 +4074,8 @@ impl<'a> Parser<'a> { if let Some(unbound) = unbound { let mut bounds_as_vec = bounds.into_vec(); bounds_as_vec.push(TraitTyParamBound(PolyTraitRef { bound_lifetimes: vec![], - trait_ref: unbound }, + trait_ref: unbound, + span: span }, TraitBoundModifier::Maybe)); bounds = OwnedSlice::from_vec(bounds_as_vec); }; @@ -4223,6 +4228,16 @@ impl<'a> Parser<'a> { } _ => { + let bound_lifetimes = if self.eat_keyword(keywords::For) { + // Higher ranked constraint. + self.expect(&token::Lt); + let lifetime_defs = self.parse_lifetime_defs(); + self.expect_gt(); + lifetime_defs + } else { + vec![] + }; + let bounded_ty = self.parse_ty(); if self.eat(&token::Colon) { @@ -4233,12 +4248,13 @@ impl<'a> Parser<'a> { if bounds.len() == 0 { self.span_err(span, "each predicate in a `where` clause must have \ - at least one bound in it"); + at least one bound in it"); } generics.where_clause.predicates.push(ast::WherePredicate::BoundPredicate( ast::WhereBoundPredicate { span: span, + bound_lifetimes: bound_lifetimes, bounded_ty: bounded_ty, bounds: bounds, })); @@ -4674,8 +4690,12 @@ impl<'a> Parser<'a> { /// Parse trait Foo { ... } fn parse_item_trait(&mut self, unsafety: Unsafety) -> ItemInfo { + let ident = self.parse_ident(); let mut tps = self.parse_generics(); + // This is not very accurate, but since unbound only exists to catch + // obsolete syntax, the span is unlikely to ever be used. + let unbound_span = self.span; let unbound = self.parse_for_sized(); // Parse supertrait bounds. @@ -4684,7 +4704,8 @@ impl<'a> Parser<'a> { if let Some(unbound) = unbound { let mut bounds_as_vec = bounds.into_vec(); bounds_as_vec.push(TraitTyParamBound(PolyTraitRef { bound_lifetimes: vec![], - trait_ref: unbound }, + trait_ref: unbound, + span: unbound_span }, TraitBoundModifier::Maybe)); bounds = OwnedSlice::from_vec(bounds_as_vec); }; @@ -4803,11 +4824,13 @@ impl<'a> Parser<'a> { /// Parse for<'l> a::B<String,i32> fn parse_poly_trait_ref(&mut self) -> PolyTraitRef { + let lo = self.span.lo; let lifetime_defs = self.parse_late_bound_lifetime_defs(); ast::PolyTraitRef { bound_lifetimes: lifetime_defs, - trait_ref: self.parse_trait_ref() + trait_ref: self.parse_trait_ref(), + span: mk_sp(lo, self.last_span.hi), } } |
