From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1643) id 3C41F3AA9002; Wed, 8 Jun 2022 11:58:41 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 3C41F3AA9002 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Thomas Schwinge To: gcc-cvs@gcc.gnu.org Subject: [gcc/devel/rust/master] Add support for wildcard patterns within MatchExprs X-Act-Checkin: gcc X-Git-Author: Philip Herron X-Git-Refname: refs/heads/devel/rust/master X-Git-Oldrev: 69f6be3ee483c9895b4b5187a44b3e1c8be2ba63 X-Git-Newrev: 6d0892636e9642e75a858c40c45acd1df79c63e1 Message-Id: <20220608115841.3C41F3AA9002@sourceware.org> Date: Wed, 8 Jun 2022 11:58:41 +0000 (GMT) X-BeenThere: gcc-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 08 Jun 2022 11:58:41 -0000 https://gcc.gnu.org/g:6d0892636e9642e75a858c40c45acd1df79c63e1 commit 6d0892636e9642e75a858c40c45acd1df79c63e1 Author: Philip Herron Date: Thu Jan 6 14:45:15 2022 +0000 Add support for wildcard patterns within MatchExprs GCC CASE_LABEL_EXPR's contain operand 0 and 1, operand 0 is used for the low value of a case label and operand 1 for a high value. So with this CASE_LABEL_EXPR is is possible to support a range of values from low->high if set apropriately, but for the wildcard case this is effectively a default case which means we set both operand 0 and 1 to NULL_TREE. Fixes #853 Diff: --- gcc/rust/backend/rust-compile-expr.cc | 7 ---- gcc/rust/backend/rust-compile-pattern.cc | 9 ++++ gcc/rust/backend/rust-compile-pattern.h | 2 + gcc/rust/hir/rust-ast-lower-pattern.cc | 28 +++++++++++++ gcc/rust/hir/rust-ast-lower-pattern.h | 18 ++------ gcc/rust/typecheck/rust-hir-type-check-expr.h | 2 +- gcc/rust/typecheck/rust-hir-type-check-pattern.cc | 9 ++++ gcc/rust/typecheck/rust-hir-type-check-pattern.h | 15 ++++--- gcc/testsuite/rust/execute/torture/match3.rs | 51 +++++++++++++++++++++++ 9 files changed, 113 insertions(+), 28 deletions(-) diff --git a/gcc/rust/backend/rust-compile-expr.cc b/gcc/rust/backend/rust-compile-expr.cc index b77a4d5d57c..5e43f5a197d 100644 --- a/gcc/rust/backend/rust-compile-expr.cc +++ b/gcc/rust/backend/rust-compile-expr.cc @@ -275,19 +275,12 @@ CompileExpr::visit (HIR::MatchExpr &expr) tree case_label = ctx->get_backend ()->label ( fndecl, "" /* empty creates an artificial label */, arm_locus); - // not sure if we need to add this to the block or if the CASE_LABEL_EXPR - // does this implicitly - // - // tree case_label_decl_statement - // = ctx->get_backend ()->label_definition_statement (case_label); - // setup the bindings for the block for (auto &kase_pattern : kase_arm.get_patterns ()) { tree switch_kase_expr = CompilePatternCaseLabelExpr::Compile (kase_pattern.get (), case_label, ctx); - // ctx->add_statement (case_label_decl_statement); ctx->add_statement (switch_kase_expr); CompilePatternBindings::Compile (kase_pattern.get (), diff --git a/gcc/rust/backend/rust-compile-pattern.cc b/gcc/rust/backend/rust-compile-pattern.cc index e634dbd03c3..27ee48723a5 100644 --- a/gcc/rust/backend/rust-compile-pattern.cc +++ b/gcc/rust/backend/rust-compile-pattern.cc @@ -77,6 +77,15 @@ CompilePatternCaseLabelExpr::visit (HIR::TupleStructPattern &pattern) CompilePatternCaseLabelExpr::visit (pattern.get_path ()); } +void +CompilePatternCaseLabelExpr::visit (HIR::WildcardPattern &pattern) +{ + // operand 0 being NULL_TREE signifies this is the default case label see: + // tree.def for documentation for CASE_LABEL_EXPR + case_label_expr + = build_case_label (NULL_TREE, NULL_TREE, associated_case_label); +} + // setup the bindings void diff --git a/gcc/rust/backend/rust-compile-pattern.h b/gcc/rust/backend/rust-compile-pattern.h index e49f75c70c7..b12ea93007e 100644 --- a/gcc/rust/backend/rust-compile-pattern.h +++ b/gcc/rust/backend/rust-compile-pattern.h @@ -40,6 +40,8 @@ public: void visit (HIR::TupleStructPattern &pattern) override; + void visit (HIR::WildcardPattern &pattern) override; + private: CompilePatternCaseLabelExpr (Context *ctx, tree associated_case_label) : HIRCompileBase (ctx), case_label_expr (error_mark_node), diff --git a/gcc/rust/hir/rust-ast-lower-pattern.cc b/gcc/rust/hir/rust-ast-lower-pattern.cc index 156f023281b..4bf3c51caef 100644 --- a/gcc/rust/hir/rust-ast-lower-pattern.cc +++ b/gcc/rust/hir/rust-ast-lower-pattern.cc @@ -22,6 +22,23 @@ namespace Rust { namespace HIR { +void +ASTLoweringPattern::visit (AST::IdentifierPattern &pattern) +{ + auto crate_num = mappings->get_current_crate (); + Analysis::NodeMapping mapping (crate_num, pattern.get_node_id (), + mappings->get_next_hir_id (crate_num), + UNKNOWN_LOCAL_DEFID); + + std::unique_ptr to_bind; + translated + = new HIR::IdentifierPattern (mapping, pattern.get_ident (), + pattern.get_locus (), pattern.get_is_ref (), + pattern.get_is_mut () ? Mutability::Mut + : Mutability::Imm, + std::move (to_bind)); +} + void ASTLoweringPattern::visit (AST::PathInExpression &pattern) { @@ -135,5 +152,16 @@ ASTLoweringPattern::visit (AST::StructPattern &pattern) translated = new HIR::StructPattern (mapping, *path, std::move (elems)); } +void +ASTLoweringPattern::visit (AST::WildcardPattern &pattern) +{ + auto crate_num = mappings->get_current_crate (); + Analysis::NodeMapping mapping (crate_num, pattern.get_node_id (), + mappings->get_next_hir_id (crate_num), + UNKNOWN_LOCAL_DEFID); + + translated = new HIR::WildcardPattern (mapping, pattern.get_locus ()); +} + } // namespace HIR } // namespace Rust diff --git a/gcc/rust/hir/rust-ast-lower-pattern.h b/gcc/rust/hir/rust-ast-lower-pattern.h index bd25b83741e..60a3ad10bd0 100644 --- a/gcc/rust/hir/rust-ast-lower-pattern.h +++ b/gcc/rust/hir/rust-ast-lower-pattern.h @@ -48,21 +48,7 @@ public: return resolver.translated; } - void visit (AST::IdentifierPattern &pattern) override - { - auto crate_num = mappings->get_current_crate (); - Analysis::NodeMapping mapping (crate_num, pattern.get_node_id (), - mappings->get_next_hir_id (crate_num), - UNKNOWN_LOCAL_DEFID); - - std::unique_ptr to_bind; - translated - = new HIR::IdentifierPattern (mapping, pattern.get_ident (), - pattern.get_locus (), pattern.get_is_ref (), - pattern.get_is_mut () ? Mutability::Mut - : Mutability::Imm, - std::move (to_bind)); - } + void visit (AST::IdentifierPattern &pattern) override; void visit (AST::PathInExpression &pattern) override; @@ -70,6 +56,8 @@ public: void visit (AST::TupleStructPattern &pattern) override; + void visit (AST::WildcardPattern &pattern) override; + private: ASTLoweringPattern () : translated (nullptr) {} diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h index 8de736db542..631bc86840a 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-expr.h +++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h @@ -1294,7 +1294,7 @@ public: for (auto &pattern : kase_arm.get_patterns ()) { TyTy::BaseType *kase_arm_ty - = TypeCheckPattern::Resolve (pattern.get ()); + = TypeCheckPattern::Resolve (pattern.get (), scrutinee_tyty); TyTy::BaseType *checked_kase = scrutinee_tyty->unify (kase_arm_ty); if (checked_kase->get_kind () == TyTy::TypeKind::ERROR) diff --git a/gcc/rust/typecheck/rust-hir-type-check-pattern.cc b/gcc/rust/typecheck/rust-hir-type-check-pattern.cc index 2b939585b82..bc6631201a5 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-pattern.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-pattern.cc @@ -219,5 +219,14 @@ TypeCheckPattern::visit (HIR::StructPattern &pattern) } } +void +TypeCheckPattern::visit (HIR::WildcardPattern &pattern) +{ + // wildcard patterns within the MatchArm's are simply just the same type as + // the parent + infered = parent->clone (); + infered->set_ref (pattern.get_pattern_mappings ().get_hirid ()); +} + } // namespace Resolver } // namespace Rust diff --git a/gcc/rust/typecheck/rust-hir-type-check-pattern.h b/gcc/rust/typecheck/rust-hir-type-check-pattern.h index ac348fb1297..a5e542dcd72 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-pattern.h +++ b/gcc/rust/typecheck/rust-hir-type-check-pattern.h @@ -30,14 +30,14 @@ class TypeCheckPattern : public TypeCheckBase using Rust::Resolver::TypeCheckBase::visit; public: - static TyTy::BaseType *Resolve (HIR::Pattern *pattern) + static TyTy::BaseType *Resolve (HIR::Pattern *pattern, TyTy::BaseType *parent) { - TypeCheckPattern resolver; + TypeCheckPattern resolver (parent); pattern->accept_vis (resolver); - // FIXME need to check how we do mappings here if (resolver.infered == nullptr) - return new TyTy::ErrorType (1); + return new TyTy::ErrorType ( + pattern->get_pattern_mappings ().get_hirid ()); return resolver.infered; } @@ -48,10 +48,15 @@ public: void visit (HIR::TupleStructPattern &pattern) override; + void visit (HIR::WildcardPattern &pattern) override; + private: - TypeCheckPattern () : TypeCheckBase (), infered (nullptr) {} + TypeCheckPattern (TyTy::BaseType *parent) + : TypeCheckBase (), infered (nullptr), parent (parent) + {} TyTy::BaseType *infered; + TyTy::BaseType *parent; }; } // namespace Resolver diff --git a/gcc/testsuite/rust/execute/torture/match3.rs b/gcc/testsuite/rust/execute/torture/match3.rs new file mode 100644 index 00000000000..3d1fa0cc5e8 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/match3.rs @@ -0,0 +1,51 @@ +// { dg-output "Foo::A\nwildcard\nwildcard\nFoo::D 20 80\n" } +extern "C" { + fn printf(s: *const i8, ...); +} + +enum Foo { + A, + B, + C(char), + D { x: i64, y: i64 }, +} + +fn inspect(f: Foo) { + match f { + Foo::A => unsafe { + let a = "Foo::A\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c); + }, + Foo::D { x, y } => unsafe { + let a = "Foo::D %i %i\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c, x, y); + }, + _ => unsafe { + let a = "wildcard\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c); + }, + } +} + +fn main() -> i32 { + let a = Foo::A; + let b = Foo::B; + let c = Foo::C('x'); + let d = Foo::D { x: 20, y: 80 }; + + inspect(a); + inspect(b); + inspect(c); + inspect(d); + + 0 +}