diff --git a/gcc/rust/ast/rust-pattern.cc b/gcc/rust/ast/rust-pattern.cc index a2fe5d59081..80189d3746b 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 0da1981928f..3b1bd1c29ec 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 @@ class LiteralPattern : public Pattern // 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 82333dc39c0..3a983e9bc88 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 (pattern.get_mappings (), pattern.get_literal (), pattern.get_locus (), std::vector ())); + 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 4250adbfbab..c941a5c9af9 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 89b9cc6a06c..a2c408fdc77 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 @@ class LiteralPattern : public Pattern 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 ce10b02303c..57f560b06d3 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 ec4c1c1d6c7..e7972770455 100644 --- a/gcc/rust/parse/rust-parse-impl.h +++ b/gcc/rust/parse/rust-parse-impl.h @@ -10345,7 +10345,7 @@ Parser::parse_literal_or_range_pattern () return std::unique_ptr ( 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 00000000000..3553c4a3462 --- /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