]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gccrs: Resolve labels within break or continue expressions
authorPierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
Wed, 2 Apr 2025 15:41:54 +0000 (17:41 +0200)
committerArthur Cohen <arthur.cohen@embecosm.com>
Tue, 8 Apr 2025 08:17:19 +0000 (10:17 +0200)
gcc/rust/ChangeLog:

* resolve/rust-late-name-resolver-2.0.cc (Late::visit): Add call
to label resolution if there is one label.
(Late::resolve_label): Look for labels and emit an error message on
failure.
* resolve/rust-late-name-resolver-2.0.h: Add function prototypes.

gcc/testsuite/ChangeLog:

* rust/compile/nr2/exclude: Remove test.

Signed-off-by: Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
gcc/rust/resolve/rust-late-name-resolver-2.0.cc
gcc/rust/resolve/rust-late-name-resolver-2.0.h
gcc/testsuite/rust/compile/nr2/exclude

index e0006fdea27935301471a78323409aea63d3249a..3e69d34367330b42ad96e15af57af2b43590fcd5 100644 (file)
@@ -187,6 +187,9 @@ Late::visit (AST::SelfParam &param)
 void
 Late::visit (AST::BreakExpr &expr)
 {
+  if (expr.has_label ())
+    resolve_label (expr.get_label ().get_lifetime ());
+
   if (expr.has_break_expr ())
     {
       auto &break_expr = expr.get_break_expr ();
@@ -215,20 +218,33 @@ Late::visit (AST::BreakExpr &expr)
 void
 Late::visit (AST::LoopLabel &label)
 {
-  // Shall we move this to visit(AST::Lifetime) or do we need to
-  // keep the context ?
-  auto lifetime = label.get_lifetime ();
+  auto &lifetime = label.get_lifetime ();
+  ctx.labels.insert (Identifier (lifetime.as_string (), lifetime.get_locus ()),
+                    lifetime.get_node_id ());
+}
+
+void
+Late::resolve_label (AST::Lifetime &lifetime)
+{
   if (auto resolved = ctx.labels.get (lifetime.as_string ()))
     {
-      ctx.map_usage (Usage (lifetime.get_node_id ()),
-                    Definition (resolved->get_node_id ()));
+      if (resolved->get_node_id () != lifetime.get_node_id ())
+       ctx.map_usage (Usage (lifetime.get_node_id ()),
+                      Definition (resolved->get_node_id ()));
     }
   else
-    {
-      ctx.labels.insert (Identifier (lifetime.as_string (),
-                                    lifetime.get_locus ()),
-                        lifetime.get_node_id ());
-    }
+    rust_error_at (lifetime.get_locus (), ErrorCode::E0426,
+                  "use of undeclared label %qs",
+                  lifetime.as_string ().c_str ());
+}
+
+void
+Late::visit (AST::ContinueExpr &expr)
+{
+  if (expr.has_label ())
+    resolve_label (expr.get_label ());
+
+  DefaultResolver::visit (expr);
 }
 
 void
index e40141c9238ce69acfc535a274ffca69a2e99824..5703b152f7e7ee1b05e2d19e714d71881062b31f 100644 (file)
@@ -48,6 +48,7 @@ public:
   void visit (AST::IdentifierExpr &) override;
   void visit (AST::StructExprFieldIdentifier &) override;
   void visit (AST::BreakExpr &) override;
+  void visit (AST::ContinueExpr &) override;
   void visit (AST::LoopLabel &) override;
   void visit (AST::PathInExpression &) override;
   void visit (AST::TypePath &) override;
@@ -62,6 +63,8 @@ public:
   void visit (AST::ClosureExprInnerTyped &) override;
 
 private:
+  void resolve_label (AST::Lifetime &lifetime);
+
   /* Setup Rust's builtin types (u8, i32, !...) in the resolver */
   void setup_builtin_types ();
 
index c688026a7b8f61b915a2087b343549752594145e..665e0cf4d99b686c97d353a595f5083ecdf4bb20 100644 (file)
@@ -12,7 +12,6 @@ privacy8.rs
 pub_restricted_1.rs
 pub_restricted_2.rs
 pub_restricted_3.rs
-undeclared_label.rs
 use_1.rs
 issue-2905-2.rs
 derive_clone_enum3.rs