public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc/devel/rust/master] Add support for wildcard patterns within MatchExprs
@ 2022-06-08 11:58 Thomas Schwinge
0 siblings, 0 replies; only message in thread
From: Thomas Schwinge @ 2022-06-08 11:58 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:6d0892636e9642e75a858c40c45acd1df79c63e1
commit 6d0892636e9642e75a858c40c45acd1df79c63e1
Author: Philip Herron <philip.herron@embecosm.com>
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<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)
{
@@ -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<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 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
+}
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2022-06-08 11:58 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-08 11:58 [gcc/devel/rust/master] Add support for wildcard patterns within MatchExprs Thomas Schwinge
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).