https://gcc.gnu.org/g:62da3d9c3c8d4d64207996115fba2acb55f9eca7

commit r16-5341-g62da3d9c3c8d4d64207996115fba2acb55f9eca7
Author: Yap Zhi Heng <[email protected]>
Date:   Sun Oct 26 10:49:28 2025 +0800

    gccrs: Add minus sign compilation for LiteralPattern
    
    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 <[email protected]>

Diff:
---
 gcc/rust/ast/rust-pattern.cc                       |  2 +-
 gcc/rust/ast/rust-pattern.h                        | 22 ++++++++++++++++++++--
 gcc/rust/backend/rust-compile-pattern.cc           |  2 ++
 gcc/rust/hir/rust-ast-lower-pattern.cc             |  3 ++-
 gcc/rust/hir/tree/rust-hir-pattern.h               | 14 ++++++++++++--
 gcc/rust/hir/tree/rust-hir.cc                      |  2 +-
 gcc/rust/parse/rust-parse-impl.h                   |  2 +-
 .../rust/execute/torture/literalpattern_neg.rs     |  9 +++++++++
 8 files changed, 48 insertions(+), 8 deletions(-)

diff --git a/gcc/rust/ast/rust-pattern.cc b/gcc/rust/ast/rust-pattern.cc
index a2fe5d590813..80189d3746bf 100644
--- a/gcc/rust/ast/rust-pattern.cc
+++ b/gcc/rust/ast/rust-pattern.cc
@@ -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
diff --git a/gcc/rust/ast/rust-pattern.h b/gcc/rust/ast/rust-pattern.h
index 0da1981928f9..3b1bd1c29ecf 100644
--- a/gcc/rust/ast/rust-pattern.h
+++ b/gcc/rust/ast/rust-pattern.h
@@ -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; }
diff --git a/gcc/rust/backend/rust-compile-pattern.cc 
b/gcc/rust/backend/rust-compile-pattern.cc
index 82333dc39c04..3a983e9bc887 100644
--- a/gcc/rust/backend/rust-compile-pattern.cc
+++ b/gcc/rust/backend/rust-compile-pattern.cc
@@ -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.
diff --git a/gcc/rust/hir/rust-ast-lower-pattern.cc 
b/gcc/rust/hir/rust-ast-lower-pattern.cc
index 4250adbfbab6..c941a5c9af94 100644
--- a/gcc/rust/hir/rust-ast-lower-pattern.cc
+++ b/gcc/rust/hir/rust-ast-lower-pattern.cc
@@ -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
diff --git a/gcc/rust/hir/tree/rust-hir-pattern.h 
b/gcc/rust/hir/tree/rust-hir-pattern.h
index 89b9cc6a06ce..a2c408fdc772 100644
--- a/gcc/rust/hir/tree/rust-hir-pattern.h
+++ b/gcc/rust/hir/tree/rust-hir-pattern.h
@@ -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 */
diff --git a/gcc/rust/hir/tree/rust-hir.cc b/gcc/rust/hir/tree/rust-hir.cc
index ce10b02303c3..57f560b06d3e 100644
--- a/gcc/rust/hir/tree/rust-hir.cc
+++ b/gcc/rust/hir/tree/rust-hir.cc
@@ -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
diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h
index ec4c1c1d6c7c..e79727704553 100644
--- a/gcc/rust/parse/rust-parse-impl.h
+++ b/gcc/rust/parse/rust-parse-impl.h
@@ -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
index 000000000000..3553c4a3462a
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/literalpattern_neg.rs
@@ -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

Reply via email to