public inbox for gcc-cvs@sourceware.org help / color / mirror / Atom feed
From: Thomas Schwinge <tschwinge@gcc.gnu.org> To: gcc-cvs@gcc.gnu.org Subject: [gcc/devel/rust/master] Allow match on primitive types Date: Wed, 8 Jun 2022 12:46:20 +0000 (GMT) [thread overview] Message-ID: <20220608124620.F3E96381D4B8@sourceware.org> (raw) https://gcc.gnu.org/g:5aa411c537289f5695b63de12b973415b2d830d6 commit 5aa411c537289f5695b63de12b973415b2d830d6 Author: David Faust <david.faust@oracle.com> Date: Tue May 10 11:52:44 2022 -0700 Allow match on primitive types This patch enables compiling match expressions for other primitive types, like int and char. However, we cannot currently compile matches on floats; CASE_LABEL_EXPR doesn't support floating-point types. Diff: --- gcc/rust/backend/rust-compile-expr.cc | 14 +++- gcc/rust/backend/rust-compile-pattern.cc | 11 +++ gcc/testsuite/rust/execute/torture/match_byte1.rs | 49 ++++++++++++ gcc/testsuite/rust/execute/torture/match_char1.rs | 49 ++++++++++++ gcc/testsuite/rust/execute/torture/match_int1.rs | 94 +++++++++++++++++++++++ 5 files changed, 214 insertions(+), 3 deletions(-) diff --git a/gcc/rust/backend/rust-compile-expr.cc b/gcc/rust/backend/rust-compile-expr.cc index 1cf4e3d5499..0fd1e3a1341 100644 --- a/gcc/rust/backend/rust-compile-expr.cc +++ b/gcc/rust/backend/rust-compile-expr.cc @@ -212,7 +212,8 @@ CompileExpr::visit (HIR::MatchExpr &expr) } TyTy::TypeKind scrutinee_kind = scrutinee_expr_tyty->get_kind (); - rust_assert (scrutinee_kind == TyTy::TypeKind::BOOL + rust_assert ((TyTy::is_primitive_type_kind (scrutinee_kind) + && scrutinee_kind != TyTy::TypeKind::NEVER) || scrutinee_kind == TyTy::TypeKind::ADT); if (scrutinee_kind == TyTy::TypeKind::ADT) @@ -223,6 +224,13 @@ CompileExpr::visit (HIR::MatchExpr &expr) rust_assert (adt->is_enum ()); rust_assert (adt->number_of_variants () > 0); } + else if (scrutinee_kind == TyTy::TypeKind::FLOAT) + { + // FIXME: CASE_LABEL_EXPR does not support floating point types. + // Find another way to compile these. + sorry_at (expr.get_locus ().gcc_location (), + "match on floating-point types is not yet supported"); + } TyTy::BaseType *expr_tyty = nullptr; if (!ctx->get_tyctx ()->lookup_type (expr.get_mappings ().get_hirid (), @@ -253,7 +261,7 @@ CompileExpr::visit (HIR::MatchExpr &expr) = CompileExpr::Compile (expr.get_scrutinee_expr ().get (), ctx); tree match_scrutinee_expr_qualifier_expr; - if (scrutinee_kind == TyTy::TypeKind::BOOL) + if (TyTy::is_primitive_type_kind (scrutinee_kind)) { match_scrutinee_expr_qualifier_expr = match_scrutinee_expr; } @@ -274,7 +282,7 @@ CompileExpr::visit (HIR::MatchExpr &expr) else { // FIXME: match on other types of expressions not yet implemented. - gcc_assert (0); + gcc_unreachable (); } // setup the end label so the cases can exit properly diff --git a/gcc/rust/backend/rust-compile-pattern.cc b/gcc/rust/backend/rust-compile-pattern.cc index e8f1c51a1d4..9c1a35a5b91 100644 --- a/gcc/rust/backend/rust-compile-pattern.cc +++ b/gcc/rust/backend/rust-compile-pattern.cc @@ -89,6 +89,17 @@ CompilePatternCaseLabelExpr::visit (HIR::LiteralPattern &pattern) pattern.get_literal (), pattern.get_locus (), std::vector<AST::Attribute> ()); + // Note: Floating point literals are currently accepted but will likely be + // forbidden in LiteralPatterns in a future version of Rust. + // See: https://github.com/rust-lang/rust/issues/41620 + // For now, we cannot compile them anyway as CASE_LABEL_EXPR does not support + // floating point types. + if (pattern.get_literal ().get_lit_type () == HIR::Literal::LitType::FLOAT) + { + sorry_at (pattern.get_locus ().gcc_location (), + "floating-point literal in pattern"); + } + tree lit = CompileExpr::Compile (litexpr, ctx); case_label_expr = build_case_label (lit, NULL_TREE, associated_case_label); diff --git a/gcc/testsuite/rust/execute/torture/match_byte1.rs b/gcc/testsuite/rust/execute/torture/match_byte1.rs new file mode 100644 index 00000000000..3d09a33a77e --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/match_byte1.rs @@ -0,0 +1,49 @@ +// { dg-output "a\nseven\nquote\nelse" } + +extern "C" { + fn printf(s: *const i8, ...); +} + +fn foo (x: u8) { + match x { + b'a' => { + let a = "a\n\0"; + let b = a as *const str; + let c = b as *const i8; + printf (c); + } + + b'\x07' => { + let a = "seven\n\0"; + let b = a as *const str; + let c = b as *const i8; + printf (c); + } + + b'\'' => { + let a = "quote\n\0"; + let b = a as *const str; + let c = b as *const i8; + printf (c); + } + + _ => { + let a = "else\n\0"; + let b = a as *const str; + let c = b as *const i8; + printf (c); + } + } +} + +fn main () -> i32 { + + let x: u8 = 7; + + foo (b'a'); + foo (x); + foo (b'\''); + foo (b'\\'); + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/match_char1.rs b/gcc/testsuite/rust/execute/torture/match_char1.rs new file mode 100644 index 00000000000..e9da8ffbddc --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/match_char1.rs @@ -0,0 +1,49 @@ +// { dg-output "amazing\nwildcard\ncompiler\nproductivity\n" } + +extern "C" { + fn printf(s: *const i8, ...); +} + +fn foo (x: char) { + match x { + 'a' => { + let a = "amazing\n\0"; + let b = a as *const str; + let c = b as *const i8; + printf (c); + } + + 'c' => { + let a = "compiler\n\0"; + let b = a as *const str; + let c = b as *const i8; + printf (c); + } + + 'p' => { + let a = "productivity\n\0"; + let b = a as *const str; + let c = b as *const i8; + printf (c); + } + + _ => { + let a = "wildcard\n\0"; + let b = a as *const str; + let c = b as *const i8; + printf (c); + } + } +} + +fn main () -> i32 { + + let p = 'p'; + + foo ('a'); + foo ('b'); + foo ('c'); + foo (p); + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/match_int1.rs b/gcc/testsuite/rust/execute/torture/match_int1.rs new file mode 100644 index 00000000000..b1373bf8498 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/match_int1.rs @@ -0,0 +1,94 @@ +// { dg-output "other!\nother!\nother!\nfifteen!\nfifteen!\nother!\nother!\nfifteen!\n" } + +extern "C" { + fn printf(s: *const i8, ...); +} + +fn foo_i32 (x: i32) { + match x { + 15 => { + let a = "fifteen!\n\0"; + let b = a as *const str; + let c = b as *const i8; + printf (c); + } + + _ => { + let a = "other!\n\0"; + let b = a as *const str; + let c = b as *const i8; + printf (c); + } + } +} + +fn foo_isize (x: isize) { + match x { + 15 => { + let a = "fifteen!\n\0"; + let b = a as *const str; + let c = b as *const i8; + printf (c); + } + + _ => { + let a = "other!\n\0"; + let b = a as *const str; + let c = b as *const i8; + printf (c); + } + } +} + +fn foo_u32 (x: u32) { + match x { + 15 => { + let a = "fifteen!\n\0"; + let b = a as *const str; + let c = b as *const i8; + printf (c); + } + + _ => { + let a = "other!\n\0"; + let b = a as *const str; + let c = b as *const i8; + printf (c); + } + } +} + +fn foo_usize (x: usize) { + match x { + 15 => { + let a = "fifteen!\n\0"; + let b = a as *const str; + let c = b as *const i8; + printf (c); + } + + _ => { + let a = "other!\n\0"; + let b = a as *const str; + let c = b as *const i8; + printf (c); + } + } +} + + +fn main () -> i32 { + let x = -2; + foo_i32 (x); + foo_i32 (334); + foo_isize (-4768); + foo_isize (15); + + let y = 127; + foo_u32 (15); + foo_u32 (y); + foo_usize (2394); + foo_usize (15); + + 0 +}
reply other threads:[~2022-06-08 12:46 UTC|newest] Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20220608124620.F3E96381D4B8@sourceware.org \ --to=tschwinge@gcc.gnu.org \ --cc=gcc-cvs@gcc.gnu.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
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).