about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorNick Cameron <ncameron@mozilla.com>2015-02-05 21:46:01 +1300
committerNick Cameron <ncameron@mozilla.com>2015-02-09 09:29:53 +1300
commit8122ce81d0909bed39c6df3e47bc751851bded84 (patch)
tree438c010af390cb3d7b67bbfe422e0772c80ca006 /src/libsyntax
parent012e9643e4d6f6fa449ca4f4e5e3fc9fb8e536db (diff)
downloadrust-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.rs3
-rw-r--r--src/libsyntax/ext/build.rs9
-rw-r--r--src/libsyntax/ext/deriving/generic/mod.rs1
-rw-r--r--src/libsyntax/fold.rs7
-rw-r--r--src/libsyntax/parse/parser.rs33
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),
         }
     }