]> git.lizzy.rs Git - rust.git/commitdiff
syntax: Allow where strings to be parsed independent from generics
authorErick Tryzelaar <erick.tryzelaar@gmail.com>
Sat, 14 Mar 2015 05:22:04 +0000 (22:22 -0700)
committerErick Tryzelaar <erick.tryzelaar@gmail.com>
Tue, 24 Mar 2015 21:18:39 +0000 (14:18 -0700)
This allows quasiquoting to insert where clauses.

src/libsyntax/ext/quote.rs
src/libsyntax/parse/parser.rs

index c11ffe66e6c392305450dd13706994e6ba3ed812..7dac40c87d189a8fe9146b60dd94c2d645f9f1ec 100644 (file)
@@ -175,6 +175,7 @@ fn to_source_with_hygiene(&self) -> String {
     impl_to_source! { ast::Block, block_to_string }
     impl_to_source! { ast::Arg, arg_to_string }
     impl_to_source! { Generics, generics_to_string }
+    impl_to_source! { ast::WhereClause, where_clause_to_string }
     impl_to_source! { P<ast::Item>, item_to_string }
     impl_to_source! { P<ast::ImplItem>, impl_item_to_string }
     impl_to_source! { P<ast::TraitItem>, trait_item_to_string }
@@ -318,6 +319,7 @@ fn to_tokens(&self, cx: &ExtCtxt) -> Vec<TokenTree> {
     impl_to_tokens! { ast::Ty }
     impl_to_tokens_lifetime! { &'a [ast::Ty] }
     impl_to_tokens! { Generics }
+    impl_to_tokens! { ast::WhereClause }
     impl_to_tokens! { P<ast::Stmt> }
     impl_to_tokens! { P<ast::Expr> }
     impl_to_tokens! { ast::Block }
index 4ae5e0faa310552144a04720e950c6c5d88d8dcd..023f6e69945aba4fe028b4c8b168414f05985673 100644 (file)
@@ -1126,7 +1126,7 @@ pub fn parse_trait_items(&mut self) -> Vec<P<TraitItem>> {
                     p.parse_arg_general(false)
                 });
 
-                p.parse_where_clause(&mut generics);
+                generics.where_clause = p.parse_where_clause();
                 let sig = ast::MethodSig {
                     unsafety: style,
                     decl: d,
@@ -3932,9 +3932,14 @@ fn forbid_lifetime(&mut self) {
     /// ```
     /// where T : Trait<U, V> + 'b, 'a : 'b
     /// ```
-    fn parse_where_clause(&mut self, generics: &mut ast::Generics) {
+    fn parse_where_clause(&mut self) -> ast::WhereClause {
+        let mut where_clause = WhereClause {
+            id: ast::DUMMY_NODE_ID,
+            predicates: Vec::new(),
+        };
+
         if !self.eat_keyword(keywords::Where) {
-            return
+            return where_clause;
         }
 
         let mut parsed_something = false;
@@ -3957,7 +3962,7 @@ fn parse_where_clause(&mut self, generics: &mut ast::Generics) {
                     let hi = self.span.hi;
                     let span = mk_sp(lo, hi);
 
-                    generics.where_clause.predicates.push(ast::WherePredicate::RegionPredicate(
+                    where_clause.predicates.push(ast::WherePredicate::RegionPredicate(
                         ast::WhereRegionPredicate {
                             span: span,
                             lifetime: bounded_lifetime,
@@ -3992,7 +3997,7 @@ fn parse_where_clause(&mut self, generics: &mut ast::Generics) {
                                            at least one bound in it");
                         }
 
-                        generics.where_clause.predicates.push(ast::WherePredicate::BoundPredicate(
+                        where_clause.predicates.push(ast::WherePredicate::BoundPredicate(
                                 ast::WhereBoundPredicate {
                                     span: span,
                                     bound_lifetimes: bound_lifetimes,
@@ -4005,7 +4010,7 @@ fn parse_where_clause(&mut self, generics: &mut ast::Generics) {
                         // let ty = self.parse_ty();
                         let hi = self.span.hi;
                         let span = mk_sp(lo, hi);
-                        // generics.where_clause.predicates.push(
+                        // where_clause.predicates.push(
                         //     ast::WherePredicate::EqPredicate(ast::WhereEqPredicate {
                         //         id: ast::DUMMY_NODE_ID,
                         //         span: span,
@@ -4036,6 +4041,8 @@ fn parse_where_clause(&mut self, generics: &mut ast::Generics) {
                           "a `where` clause must have at least one predicate \
                            in it");
         }
+
+        where_clause
     }
 
     fn parse_fn_args(&mut self, named_args: bool, allow_variadic: bool)
@@ -4354,7 +4361,7 @@ fn mk_item(&mut self, lo: BytePos, hi: BytePos, ident: Ident,
     fn parse_item_fn(&mut self, unsafety: Unsafety, abi: abi::Abi) -> ItemInfo {
         let (ident, mut generics) = self.parse_fn_header();
         let decl = self.parse_fn_decl(false);
-        self.parse_where_clause(&mut generics);
+        generics.where_clause = self.parse_where_clause();
         let (inner_attrs, body) = self.parse_inner_attrs_and_block();
         (ident, ItemFn(decl, unsafety, abi, generics, body), Some(inner_attrs))
     }
@@ -4439,7 +4446,7 @@ fn parse_impl_method(&mut self, vis: Visibility)
             let (explicit_self, decl) = self.parse_fn_decl_with_self(|p| {
                     p.parse_arg()
                 });
-            self.parse_where_clause(&mut generics);
+            generics.where_clause = self.parse_where_clause();
             let (inner_attrs, body) = self.parse_inner_attrs_and_block();
             (ident, inner_attrs, MethodImplItem(ast::MethodSig {
                 generics: generics,
@@ -4460,7 +4467,7 @@ fn parse_item_trait(&mut self, unsafety: Unsafety) -> ItemInfo {
         // Parse supertrait bounds.
         let bounds = self.parse_colon_then_ty_param_bounds(BoundParsingMode::Bare);
 
-        self.parse_where_clause(&mut tps);
+        tps.where_clause = self.parse_where_clause();
 
         let meths = self.parse_trait_items();
         (ident, ItemTrait(unsafety, tps, bounds, meths), None)
@@ -4531,7 +4538,7 @@ fn parse_item_impl(&mut self, unsafety: ast::Unsafety) -> ItemInfo {
             if opt_trait.is_some() {
                 ty = self.parse_ty_sum();
             }
-            self.parse_where_clause(&mut generics);
+            generics.where_clause = self.parse_where_clause();
 
             self.expect(&token::OpenDelim(token::Brace));
             let attrs = self.parse_inner_attributes();
@@ -4603,7 +4610,7 @@ fn parse_item_struct(&mut self) -> ItemInfo {
         // struct.
 
         let (fields, ctor_id) = if self.token.is_keyword(keywords::Where) {
-            self.parse_where_clause(&mut generics);
+            generics.where_clause = self.parse_where_clause();
             if self.eat(&token::Semi) {
                 // If we see a: `struct Foo<T> where T: Copy;` style decl.
                 (Vec::new(), Some(ast::DUMMY_NODE_ID))
@@ -4684,12 +4691,12 @@ pub fn parse_tuple_struct_body(&mut self,
                     token::get_ident(class_name.clone())));
             }
 
-            self.parse_where_clause(generics);
+            generics.where_clause = self.parse_where_clause();
             self.expect(&token::Semi);
             fields
         // This is the case where we just see struct Foo<T> where T: Copy;
         } else if self.token.is_keyword(keywords::Where) {
-            self.parse_where_clause(generics);
+            generics.where_clause = self.parse_where_clause();
             self.expect(&token::Semi);
             Vec::new()
         // This case is where we see: `struct Foo<T>;`
@@ -4937,7 +4944,7 @@ fn parse_item_foreign_fn(&mut self, vis: ast::Visibility,
 
         let (ident, mut generics) = self.parse_fn_header();
         let decl = self.parse_fn_decl(true);
-        self.parse_where_clause(&mut generics);
+        generics.where_clause = self.parse_where_clause();
         let hi = self.span.hi;
         self.expect(&token::Semi);
         P(ast::ForeignItem {
@@ -5082,7 +5089,7 @@ fn parse_item_foreign_mod(&mut self,
     fn parse_item_type(&mut self) -> ItemInfo {
         let ident = self.parse_ident();
         let mut tps = self.parse_generics();
-        self.parse_where_clause(&mut tps);
+        tps.where_clause = self.parse_where_clause();
         self.expect(&token::Eq);
         let ty = self.parse_ty_sum();
         self.expect(&token::Semi);
@@ -5182,7 +5189,7 @@ fn parse_enum_def(&mut self, _generics: &ast::Generics) -> EnumDef {
     fn parse_item_enum(&mut self) -> ItemInfo {
         let id = self.parse_ident();
         let mut generics = self.parse_generics();
-        self.parse_where_clause(&mut generics);
+        generics.where_clause = self.parse_where_clause();
         self.expect(&token::OpenDelim(token::Brace));
 
         let enum_definition = self.parse_enum_def(&generics);