https://gcc.gnu.org/g:587c3b2b91db8034a6fc7f6c7ef6ba672147ecea

commit 587c3b2b91db8034a6fc7f6c7ef6ba672147ecea
Author: Jakub Dupak <d...@jakubdupak.com>
Date:   Wed Oct 18 23:01:06 2023 +0200

    borrowck: BIR continue
    
    gcc/rust/ChangeLog:
    
            * checks/errors/borrowck/rust-bir-builder-expr-stmt.cc 
(ExprStmtBuilder::visit): Continue.
            (ExprStmtBuilder::setup_loop): Continue.
    
    Signed-off-by: Jakub Dupak <d...@jakubdupak.com>

Diff:
---
 .../errors/borrowck/rust-bir-builder-expr-stmt.cc  | 50 ++++++++++++++--------
 1 file changed, 32 insertions(+), 18 deletions(-)

diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.cc 
b/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.cc
index 67b98e2254f9..9a850facff96 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.cc
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.cc
@@ -305,20 +305,32 @@ ExprStmtBuilder::visit (HIR::BlockExpr &block)
 void
 ExprStmtBuilder::visit (HIR::ContinueExpr &cont)
 {
-  //  BuilderContext::LabelledBlockCtx loop_ctx;
-  //  NodeId label = UNKNOWN_NODEID;
-  //  if (cont.has_label ())
-  //    {
-  //      if (!resolve_label (cont.get_label (), label))
-  //   return;
-  //    }
-  //
-  //  if (!find_block_ctx (label, loop_ctx))
-  //    {
-  //      rust_error_at (cont.get_locus (), "unresolved loop label");
-  //    }
-  //
-  //  add_jump_to (loop_ctx.continue_bb);
+  BuilderContext::LoopAndLabelInfo info;
+  if (cont.has_label ())
+    {
+      NodeId label = resolve_label (cont.get_label ());
+      auto lookup
+       = std::find_if (ctx.loop_and_label_stack.rbegin (),
+                       ctx.loop_and_label_stack.rend (),
+                       [label] (const BuilderContext::LoopAndLabelInfo &info) {
+                         return info.label == label;
+                       });
+      rust_assert (lookup != ctx.loop_and_label_stack.rend ());
+      info = *lookup;
+    }
+  else
+    {
+      auto lookup
+       = std::find_if (ctx.loop_and_label_stack.rbegin (),
+                       ctx.loop_and_label_stack.rend (),
+                       [] (const BuilderContext::LoopAndLabelInfo &info) {
+                         return info.is_loop;
+                       });
+      rust_assert (lookup != ctx.loop_and_label_stack.rend ());
+      info = *lookup;
+    }
+  add_jump_to (info.continue_bb);
+  // No code allowed after continue. No BB starts - would be empty.
 }
 
 void
@@ -418,9 +430,10 @@ ExprStmtBuilder::visit (HIR::UnsafeBlockExpr &expr)
 BuilderContext::LoopAndLabelInfo &
 ExprStmtBuilder::setup_loop (HIR::BaseLoopExpr &expr)
 {
-  NodeId label = (expr.has_loop_label ())
-                  ? resolve_label (expr.get_loop_label ())
-                  : UNKNOWN_NODEID;
+  NodeId label
+    = (expr.has_loop_label ())
+       ? expr.get_loop_label ().get_lifetime ().get_mappings ().get_nodeid ()
+       : UNKNOWN_NODEID;
   PlaceId label_var = ctx.place_db.add_temporary (lookup_type (expr));
 
   BasicBlockId continue_bb = new_bb ();
@@ -439,7 +452,8 @@ ExprStmtBuilder::visit (HIR::LoopExpr &expr)
 
   ctx.current_bb = loop.continue_bb;
   (void) visit_expr (*expr.get_loop_block ());
-  add_jump_to (loop.continue_bb);
+  if (!ctx.get_current_bb ().is_terminated ())
+    add_jump_to (loop.continue_bb);
 
   ctx.current_bb = loop.break_bb;
 }

Reply via email to