]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gccrs: Add minus sign compilation for LiteralPattern
authorYap Zhi Heng <yapzhhg@gmail.com>
Sun, 26 Oct 2025 02:49:28 +0000 (10:49 +0800)
committerArthur Cohen <arthur.cohen@embecosm.com>
Mon, 17 Nov 2025 14:58:17 +0000 (15:58 +0100)
GIMPLE output for literalpattern_neg.rs test case:

...
  x = -55;
  RUSTTMP.2 = x;
  if (RUSTTMP.2 == 55) goto <D.113>; else goto <D.114>;
  <D.113>:
  {
    RUSTTMP.1 = 1;
    goto <D.107>;
  }
  <D.114>:
  if (RUSTTMP.2 == -55) goto <D.115>; else goto <D.116>;
  <D.115>:
  {
    RUSTTMP.1 = 0;
    goto <D.107>;
  }
  <D.116>:
  if (1 != 0) goto <D.117>; else goto <D.118>;
  <D.117>:
  {
    RUSTTMP.1 = 1;
    goto <D.107>;
  }
...

gcc/rust/ChangeLog:

* parse/rust-parse-impl.h (parse_literal_or_range_pattern): Parse minus sign
properly for LiteralPattern.
* ast/rust-pattern.h (LiteralPattern): Add has_minus boolean for LiteralPattern.
* hir/tree/rust-hir-pattern.h (LiteralPattern): Ditto.
* ast/rust-pattern.cc (LiteralPattern::as_string): Update to include minus sign
if present.
* hir/tree/rust-hir.cc (LiteralPattern::as_string): Ditto.
* hir/rust-ast-lower-pattern.cc (visit(LiteralPattern)): Pass has_minus boolean
from AST to HIR.
* backend/rust-compile-pattern.cc (CompilePatternCheckExpr::visit(LiteralPattern)):
Compile litexpr as negative if minus sign is present.

Signed-off-by: Yap Zhi Heng <yapzhhg@gmail.com>
gcc/rust/ast/rust-pattern.cc
gcc/rust/ast/rust-pattern.h
gcc/rust/backend/rust-compile-pattern.cc
gcc/rust/hir/rust-ast-lower-pattern.cc
gcc/rust/hir/tree/rust-hir-pattern.h
gcc/rust/hir/tree/rust-hir.cc
gcc/rust/parse/rust-parse-impl.h
gcc/testsuite/rust/execute/torture/literalpattern_neg.rs [new file with mode: 0644]

index a2fe5d590813dd18e12f4be2d2bbc4af8d589475..80189d3746bfd15f77316d8832ae1942a29c20a1 100644 (file)
@@ -48,7 +48,7 @@ tokenid_to_rangekind (TokenId id)
 std::string
 LiteralPattern::as_string () const
 {
-  return lit.as_string ();
+  return (has_minus ? "-" : "") + lit.as_string ();
 }
 
 std::string
index 0da1981928f9c2982c8450cf27233f8ed69ccb5d..3b1bd1c29ecfca02b9a76f3ff011f8a41b248628 100644 (file)
@@ -30,6 +30,7 @@ class LiteralPattern : public Pattern
   Literal lit;
   location_t locus;
   NodeId node_id;
+  bool has_minus;
 
 public:
   std::string as_string () const override;
@@ -37,17 +38,34 @@ public:
   // Constructor for a literal pattern
   LiteralPattern (Literal lit, location_t locus)
     : lit (std::move (lit)), locus (locus),
-      node_id (Analysis::Mappings::get ().get_next_node_id ())
+      node_id (Analysis::Mappings::get ().get_next_node_id ()),
+      has_minus (false)
+  {}
+
+  LiteralPattern (Literal lit, location_t locus, bool has_minus)
+    : lit (std::move (lit)), locus (locus),
+      node_id (Analysis::Mappings::get ().get_next_node_id ()),
+      has_minus (has_minus)
   {}
 
   LiteralPattern (std::string val, Literal::LitType type, location_t locus,
                  PrimitiveCoreType type_hint)
     : lit (Literal (std::move (val), type, type_hint)), locus (locus),
-      node_id (Analysis::Mappings::get ().get_next_node_id ())
+      node_id (Analysis::Mappings::get ().get_next_node_id ()),
+      has_minus (false)
+  {}
+
+  LiteralPattern (std::string val, Literal::LitType type, location_t locus,
+                 PrimitiveCoreType type_hint, bool has_minus)
+    : lit (Literal (std::move (val), type, type_hint)), locus (locus),
+      node_id (Analysis::Mappings::get ().get_next_node_id ()),
+      has_minus (has_minus)
   {}
 
   location_t get_locus () const override final { return locus; }
 
+  bool get_has_minus () const { return has_minus; }
+
   void accept_vis (ASTVisitor &vis) override;
 
   NodeId get_node_id () const override { return node_id; }
index 82333dc39c046706d5d169899c87508331cfe1d3..3a983e9bc887f16772b741986bbcbb0ca2fc8871 100644 (file)
@@ -87,6 +87,8 @@ CompilePatternCheckExpr::visit (HIR::LiteralPattern &pattern)
   auto litexpr = std::make_unique<HIR::LiteralExpr> (
     HIR::LiteralExpr (pattern.get_mappings (), pattern.get_literal (),
                      pattern.get_locus (), std::vector<AST::Attribute> ()));
+  if (pattern.get_has_minus ())
+    litexpr->set_negative ();
 
   // Note: Floating point literals are currently accepted but will likely be
   // forbidden in LiteralPatterns in a future version of Rust.
index 4250adbfbab68f6ac2af94230e876778b26c6a4c..c941a5c9af943f6554167a6caf642f249635f90c 100644 (file)
@@ -280,7 +280,8 @@ ASTLoweringPattern::visit (AST::LiteralPattern &pattern)
 
   HIR::Literal l = lower_literal (pattern.get_literal ());
   translated
-    = new HIR::LiteralPattern (mapping, std::move (l), pattern.get_locus ());
+    = new HIR::LiteralPattern (mapping, std::move (l), pattern.get_locus (),
+                              pattern.get_has_minus ());
 }
 
 void
index 89b9cc6a06cefee4884e25d30b12782931a7f499..a2c408fdc7721bc0851fd7bfe2ab370f4c6a101b 100644 (file)
@@ -32,19 +32,27 @@ class LiteralPattern : public Pattern
   Literal lit;
   location_t locus;
   Analysis::NodeMapping mappings;
+  bool has_minus;
 
 public:
   std::string as_string () const override;
 
   // Constructor for a literal pattern
   LiteralPattern (Analysis::NodeMapping mappings, Literal lit, location_t locus)
-    : lit (std::move (lit)), locus (locus), mappings (mappings)
+    : lit (std::move (lit)), locus (locus), mappings (mappings),
+      has_minus (false)
+  {}
+
+  LiteralPattern (Analysis::NodeMapping mappings, Literal lit, location_t locus,
+                 bool has_minus)
+    : lit (std::move (lit)), locus (locus), mappings (mappings),
+      has_minus (has_minus)
   {}
 
   LiteralPattern (Analysis::NodeMapping mappings, std::string val,
                  Literal::LitType type, location_t locus)
     : lit (Literal (std::move (val), type, PrimitiveCoreType::CORETYPE_STR)),
-      locus (locus), mappings (mappings)
+      locus (locus), mappings (mappings), has_minus (false)
   {}
 
   location_t get_locus () const override { return locus; }
@@ -65,6 +73,8 @@ public:
   Literal &get_literal () { return lit; }
   const Literal &get_literal () const { return lit; }
 
+  bool get_has_minus () const { return has_minus; }
+
 protected:
   /* Use covariance to implement clone function as returning this object rather
    * than base */
index ce10b02303c314b29bd74f6ed600ff1cce004440..57f560b06d3eb96187b43026654f73bc6b970fd8 100644 (file)
@@ -2634,7 +2634,7 @@ StructPattern::as_string () const
 std::string
 LiteralPattern::as_string () const
 {
-  return lit.as_string ();
+  return (has_minus ? "-" : "") + lit.as_string ();
 }
 
 std::string
index ec4c1c1d6c7c25ce862abc846a99015f6bc7bede..e79727704553d35feb5b64372a1b781c43140c4f 100644 (file)
@@ -10345,7 +10345,7 @@ Parser<ManagedTokenSource>::parse_literal_or_range_pattern ()
       return std::unique_ptr<AST::LiteralPattern> (
        new AST::LiteralPattern (range_lower->get_str (), type,
                                 range_lower->get_locus (),
-                                range_lower->get_type_hint ()));
+                                range_lower->get_type_hint (), has_minus));
     }
 }
 
diff --git a/gcc/testsuite/rust/execute/torture/literalpattern_neg.rs b/gcc/testsuite/rust/execute/torture/literalpattern_neg.rs
new file mode 100644 (file)
index 0000000..3553c4a
--- /dev/null
@@ -0,0 +1,9 @@
+fn main() -> i32 {
+    let x = -55;
+
+    match x {
+        55 => 1,
+        -55 => 0, // correct case
+        _ => 1
+    }
+}
\ No newline at end of file