aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/rust/backend/rust-compile-expr.cc7
-rw-r--r--gcc/rust/backend/rust-compile-pattern.cc9
-rw-r--r--gcc/rust/backend/rust-compile-pattern.h2
-rw-r--r--gcc/rust/hir/rust-ast-lower-pattern.cc28
-rw-r--r--gcc/rust/hir/rust-ast-lower-pattern.h18
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-expr.h2
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-pattern.cc9
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-pattern.h15
-rw-r--r--gcc/testsuite/rust/execute/torture/match3.rs51
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
+}