diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/backend/rust-compile-expr.cc | 7 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-pattern.cc | 9 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-pattern.h | 2 | ||||
-rw-r--r-- | gcc/rust/hir/rust-ast-lower-pattern.cc | 28 | ||||
-rw-r--r-- | gcc/rust/hir/rust-ast-lower-pattern.h | 18 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-expr.h | 2 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-pattern.cc | 9 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-pattern.h | 15 | ||||
-rw-r--r-- | 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 b77a4d5..5e43f5a 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 e634dbd..27ee487 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 e49f75c..b12ea93 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 156f023..4bf3c51 100644 --- a/gcc/rust/hir/rust-ast-lower-pattern.cc +++ b/gcc/rust/hir/rust-ast-lower-pattern.cc @@ -23,6 +23,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<Pattern> 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) { translated = ASTLowerPathInExpression::translate (&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 bd25b83..60a3ad1 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<Pattern> 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 8de736d..631bc86 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 2b93958..bc66312 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 ac348fb..a5e542d 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 0000000..3d1fa0c --- /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 +} |