From: Jakub Dupak <d...@jakubdupak.com>

gcc/rust/ChangeLog:

        * parse/rust-parse-impl.h (Parser::parse_where_clause): fix parsing
        (Parser::parse_where_clause_item): fix parsing
        (Parser::parse_type_bound_where_clause_item): fix parsing
        (Parser::parse_trait_bound): fix parsing
        * parse/rust-parse.h: fix parsing

Signed-off-by: Jakub Dupak <d...@jakubdupak.com>
---
 gcc/rust/parse/rust-parse-impl.h | 37 ++++++++++++++++++++------------
 gcc/rust/parse/rust-parse.h      |  6 ++++--
 2 files changed, 27 insertions(+), 16 deletions(-)

diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h
index c14c75ce70d..7ea7276dc94 100644
--- a/gcc/rust/parse/rust-parse-impl.h
+++ b/gcc/rust/parse/rust-parse-impl.h
@@ -3756,6 +3756,10 @@ Parser<ManagedTokenSource>::parse_where_clause ()
    * so won't be here */
   std::vector<std::unique_ptr<AST::WhereClauseItem>> where_clause_items;
 
+  std::vector<AST::LifetimeParam> for_lifetimes;
+  if (lexer.peek_token ()->get_id () == FOR)
+    for_lifetimes = parse_for_lifetimes ();
+
   /* HACK: where clauses end with a right curly or semicolon or equals in all
    * uses currently */
   const_TokenPtr t = lexer.peek_token ();
@@ -3763,7 +3767,7 @@ Parser<ManagedTokenSource>::parse_where_clause ()
         && t->get_id () != EQUAL)
     {
       std::unique_ptr<AST::WhereClauseItem> where_clause_item
-       = parse_where_clause_item ();
+       = parse_where_clause_item (for_lifetimes);
 
       if (where_clause_item == nullptr)
        {
@@ -3791,7 +3795,8 @@ Parser<ManagedTokenSource>::parse_where_clause ()
  * commas. */
 template <typename ManagedTokenSource>
 std::unique_ptr<AST::WhereClauseItem>
-Parser<ManagedTokenSource>::parse_where_clause_item ()
+Parser<ManagedTokenSource>::parse_where_clause_item (
+  const std::vector<AST::LifetimeParam> &outer_for_lifetimes)
 {
   // shitty cheat way of determining lifetime or type bound - test for
   // lifetime
@@ -3800,7 +3805,7 @@ Parser<ManagedTokenSource>::parse_where_clause_item ()
   if (t->get_id () == LIFETIME)
     return parse_lifetime_where_clause_item ();
   else
-    return parse_type_bound_where_clause_item ();
+    return parse_type_bound_where_clause_item (outer_for_lifetimes);
 }
 
 // Parses a lifetime where clause item.
@@ -3834,12 +3839,10 @@ 
Parser<ManagedTokenSource>::parse_lifetime_where_clause_item ()
 // Parses a type bound where clause item.
 template <typename ManagedTokenSource>
 std::unique_ptr<AST::TypeBoundWhereClauseItem>
-Parser<ManagedTokenSource>::parse_type_bound_where_clause_item ()
+Parser<ManagedTokenSource>::parse_type_bound_where_clause_item (
+  const std::vector<AST::LifetimeParam> &outer_for_lifetimes)
 {
-  // parse for lifetimes, if it exists
-  std::vector<AST::LifetimeParam> for_lifetimes;
-  if (lexer.peek_token ()->get_id () == FOR)
-    for_lifetimes = parse_for_lifetimes ();
+  std::vector<AST::LifetimeParam> for_lifetimes = outer_for_lifetimes;
 
   std::unique_ptr<AST::Type> type = parse_type ();
   if (type == nullptr)
@@ -3853,6 +3856,13 @@ 
Parser<ManagedTokenSource>::parse_type_bound_where_clause_item ()
       return nullptr;
     }
 
+  if (lexer.peek_token ()->get_id () == FOR)
+    {
+      auto for_lifetimes_inner = parse_for_lifetimes ();
+      for_lifetimes.insert (for_lifetimes.end (), for_lifetimes_inner.begin (),
+                           for_lifetimes_inner.end ());
+    }
+
   // parse type param bounds if they exist
   std::vector<std::unique_ptr<AST::TypeParamBound>> type_param_bounds
     = parse_type_param_bounds ();
@@ -4029,6 +4039,11 @@ Parser<ManagedTokenSource>::parse_trait_bound ()
 
   location_t locus = lexer.peek_token ()->get_locus ();
 
+  /* parse optional `for lifetimes`. */
+  std::vector<AST::LifetimeParam> for_lifetimes;
+  if (lexer.peek_token ()->get_id () == FOR)
+    for_lifetimes = parse_for_lifetimes ();
+
   // handle trait bound being in parentheses
   if (lexer.peek_token ()->get_id () == LEFT_PAREN)
     {
@@ -4043,12 +4058,6 @@ Parser<ManagedTokenSource>::parse_trait_bound ()
       lexer.skip_token ();
     }
 
-  /* parse for lifetimes, if it exists (although empty for lifetimes is ok to
-   * handle this) */
-  std::vector<AST::LifetimeParam> for_lifetimes;
-  if (lexer.peek_token ()->get_id () == FOR)
-    for_lifetimes = parse_for_lifetimes ();
-
   // handle TypePath
   AST::TypePath type_path = parse_type_path ();
 
diff --git a/gcc/rust/parse/rust-parse.h b/gcc/rust/parse/rust-parse.h
index 3fc86206de7..02f90217fc2 100644
--- a/gcc/rust/parse/rust-parse.h
+++ b/gcc/rust/parse/rust-parse.h
@@ -288,11 +288,13 @@ private:
   std::unique_ptr<AST::Param> parse_function_param ();
   std::unique_ptr<AST::Type> parse_function_return_type ();
   AST::WhereClause parse_where_clause ();
-  std::unique_ptr<AST::WhereClauseItem> parse_where_clause_item ();
+  std::unique_ptr<AST::WhereClauseItem> parse_where_clause_item (
+    const std::vector<AST::LifetimeParam> &global_for_lifetimes);
   std::unique_ptr<AST::LifetimeWhereClauseItem>
   parse_lifetime_where_clause_item ();
   std::unique_ptr<AST::TypeBoundWhereClauseItem>
-  parse_type_bound_where_clause_item ();
+  parse_type_bound_where_clause_item (
+    const std::vector<AST::LifetimeParam> &global_for_lifetimes);
   std::vector<AST::LifetimeParam> parse_for_lifetimes ();
   template <typename EndTokenPred>
   std::vector<std::unique_ptr<AST::TypeParamBound>>
-- 
2.42.1

Reply via email to