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
