From: Yap Zhi Heng <[email protected]>

006t.original dump of rust/compile/match-structpattern-tuplefield.rs:

...
  const struct match_structpattern_tuplefield::TupStruct t = {.0=1, .1=2};
    struct () RUSTTMP.1;
    const struct match_structpattern_tuplefield::TupStruct RUSTTMP.2;
  RUSTTMP.2 = t;
  if (RUSTTMP.2.0 == 1 && RUSTTMP.2.1 == 2)
    {
      {
                struct () RUSTTMP.3;
        {}
        goto <D.100>;
      }
    }
  if (1)
    {
      {
                struct () RUSTTMP.4;
        {}
        goto <D.100>;
      }
    }
  if (RUSTTMP.2.0 == 1)
    {
      {
                struct () RUSTTMP.5;
        {}
        goto <D.100>;
      }
    }
  if (1)
    {
      {
                struct () RUSTTMP.6;
        {}
        goto <D.100>;
      }
    }
  <D.100>:;
...

gcc/rust/ChangeLog:

        * typecheck/rust-hir-type-check-pattern.cc (visit(StructPattern)): 
Implement
        type check case for HIR::StructPatternFieldTuplePat.
        * checks/errors/rust-hir-pattern-analysis.cc (lower_struct_pattern): 
Implement
        case for HIR::StructPatternField::ItemType::TUPLE_PAT.
        * backend/rust-compile-pattern.cc:
                * CompilePatternCheckExpr::visit (HIR::StructPattern): 
Implement code
                gen for HIR::StructPatternField::ItemType::TUPLE_PAT case.
                * CompilePatternBindings::handle_struct_pattern_tuple_pat: 
Implement
                bindings for HIR::StructPatternFieldTuplePat.
        * backend/rust-compile-pattern.h: Update function definition for
        handle_struct_pattern_tuple_pat.

Signed-off-by: Yap Zhi Heng <[email protected]>
---
This change was merged into the gccrs repository and is posted here for
upstream visibility and potential drive-by review, as requested by GCC
release managers.
Each commit email contains a link to its details on github from where you can
find the Pull-Request and associated discussions.


Commit on github: 
https://github.com/Rust-GCC/gccrs/commit/b940d2c51ba04f6c224642e777aacf4b2931be6b

The commit has been mentioned in the following pull-request(s):
 - https://github.com/Rust-GCC/gccrs/pull/4400

 gcc/rust/backend/rust-compile-pattern.cc      | 51 +++++++++++++++++--
 gcc/rust/backend/rust-compile-pattern.h       |  5 +-
 .../errors/rust-hir-pattern-analysis.cc       |  8 ++-
 .../typecheck/rust-hir-type-check-pattern.cc  | 17 ++++++-
 .../match-structpattern-tuplefield-err.rs     | 17 +++++++
 .../compile/match-structpattern-tuplefield.rs | 11 ++++
 .../torture/match-structpattern-tuplefield.rs | 10 ++++
 7 files changed, 109 insertions(+), 10 deletions(-)
 create mode 100644 
gcc/testsuite/rust/compile/match-structpattern-tuplefield-err.rs
 create mode 100644 gcc/testsuite/rust/compile/match-structpattern-tuplefield.rs
 create mode 100644 
gcc/testsuite/rust/execute/torture/match-structpattern-tuplefield.rs

diff --git a/gcc/rust/backend/rust-compile-pattern.cc 
b/gcc/rust/backend/rust-compile-pattern.cc
index 3836aa2af..d57616e6d 100644
--- a/gcc/rust/backend/rust-compile-pattern.cc
+++ b/gcc/rust/backend/rust-compile-pattern.cc
@@ -297,8 +297,18 @@ CompilePatternCheckExpr::visit (HIR::StructPattern 
&pattern)
        {
        case HIR::StructPatternField::ItemType::TUPLE_PAT:
          {
-           // TODO
-           rust_unreachable ();
+           HIR::StructPatternFieldTuplePat &tuple_pat
+             = static_cast<HIR::StructPatternFieldTuplePat &> (*field.get ());
+           size_t tuple_pat_index = tuple_pat.get_index ();
+           tree field_expr
+             = Backend::struct_field_expression (variant_accesser_expr,
+                                                 tuple_pat_index,
+                                                 tuple_pat.get_locus ());
+           tree check_expr_sub = CompilePatternCheckExpr::Compile (
+             tuple_pat.get_tuple_pattern (), field_expr, ctx);
+           check_expr = Backend::arithmetic_or_logical_expression (
+             ArithmeticOrLogicalOperator::BITWISE_AND, check_expr,
+             check_expr_sub, tuple_pat.get_locus ());
          }
          break;
 
@@ -954,9 +964,40 @@ CompilePatternBindings::handle_struct_pattern_ident_pat (
 
 void
 CompilePatternBindings::handle_struct_pattern_tuple_pat (
-  HIR::StructPatternField &pat)
+  HIR::StructPatternField &pat, TyTy::ADTType *adt, TyTy::VariantDef *variant,
+  int variant_index)
 {
-  rust_unreachable ();
+  HIR::StructPatternFieldTuplePat &tuple_pat
+    = static_cast<HIR::StructPatternFieldTuplePat &> (pat);
+
+  size_t tuple_pat_index = tuple_pat.get_index ();
+  tree binding;
+
+  if (adt->is_enum ())
+    {
+      tree payload_accessor_union
+       = Backend::struct_field_expression (match_scrutinee_expr, 1,
+                                           pat.get_locus ());
+
+      tree variant_accessor
+       = Backend::struct_field_expression (payload_accessor_union,
+                                           variant_index, pat.get_locus ());
+
+      binding
+       = Backend::struct_field_expression (variant_accessor, tuple_pat_index,
+                                           pat.get_locus ());
+    }
+  else
+    {
+      tree variant_accessor = match_scrutinee_expr;
+
+      binding
+       = Backend::struct_field_expression (variant_accessor, tuple_pat_index,
+                                           pat.get_locus ());
+    }
+
+  CompilePatternBindings::Compile (tuple_pat.get_tuple_pattern (), binding,
+                                  ctx);
 }
 
 void
@@ -996,7 +1037,7 @@ CompilePatternBindings::visit (HIR::StructPattern &pattern)
       switch (field->get_item_type ())
        {
        case HIR::StructPatternField::ItemType::TUPLE_PAT:
-         handle_struct_pattern_tuple_pat (*field);
+         handle_struct_pattern_tuple_pat (*field, adt, variant, variant_index);
          break;
        case HIR::StructPatternField::ItemType::IDENT_PAT:
          handle_struct_pattern_ident_pat (*field, adt, variant, variant_index);
diff --git a/gcc/rust/backend/rust-compile-pattern.h 
b/gcc/rust/backend/rust-compile-pattern.h
index 7c38eb571..35e152fe3 100644
--- a/gcc/rust/backend/rust-compile-pattern.h
+++ b/gcc/rust/backend/rust-compile-pattern.h
@@ -88,7 +88,10 @@ public:
                                        TyTy::ADTType *adt,
                                        TyTy::VariantDef *variant,
                                        int variant_index);
-  void handle_struct_pattern_tuple_pat (HIR::StructPatternField &pat);
+  void handle_struct_pattern_tuple_pat (HIR::StructPatternField &pat,
+                                       TyTy::ADTType *adt,
+                                       TyTy::VariantDef *variant,
+                                       int variant_index);
 
   void visit (HIR::StructPattern &pattern) override;
   void visit (HIR::TupleStructPattern &pattern) override;
diff --git a/gcc/rust/checks/errors/rust-hir-pattern-analysis.cc 
b/gcc/rust/checks/errors/rust-hir-pattern-analysis.cc
index 8c972a596..431cd9bb8 100644
--- a/gcc/rust/checks/errors/rust-hir-pattern-analysis.cc
+++ b/gcc/rust/checks/errors/rust-hir-pattern-analysis.cc
@@ -1315,8 +1315,12 @@ lower_struct_pattern (Resolver::TypeCheckContext *ctx,
          break;
        case HIR::StructPatternField::ItemType::TUPLE_PAT:
          {
-           // TODO: tuple: pat
-           rust_unreachable ();
+           HIR::StructPatternFieldTuplePat *tuple_pat
+             = static_cast<HIR::StructPatternFieldTuplePat *> (elem.get ());
+           int field_idx = tuple_pat->get_index ();
+           fields.at (field_idx) = lower_pattern (
+             ctx, tuple_pat->get_tuple_pattern (),
+             variant->get_fields ().at (field_idx)->get_field_type ());
          }
          break;
        default:
diff --git a/gcc/rust/typecheck/rust-hir-type-check-pattern.cc 
b/gcc/rust/typecheck/rust-hir-type-check-pattern.cc
index 1e043d737..4f484ca0d 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-pattern.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-pattern.cc
@@ -474,8 +474,21 @@ TypeCheckPattern::visit (HIR::StructPattern &pattern)
        {
        case HIR::StructPatternField::ItemType::TUPLE_PAT:
          {
-           // TODO
-           rust_unreachable ();
+           HIR::StructPatternFieldTuplePat &tuple_pat
+             = static_cast<HIR::StructPatternFieldTuplePat &> (*field.get ());
+
+           if ((size_t) tuple_pat.get_index () >= variant->num_fields ())
+             {
+               emit_invalid_field_error (tuple_pat.get_locus (), variant,
+                                         std::to_string (
+                                           tuple_pat.get_index ()));
+               break;
+             }
+           named_fields.push_back (std::to_string (tuple_pat.get_index ()));
+           TyTy::StructFieldType *field
+             = variant->get_field_at_index (tuple_pat.get_index ());
+           TyTy::BaseType *fty = field->get_field_type ();
+           TypeCheckPattern::Resolve (tuple_pat.get_tuple_pattern (), fty);
          }
          break;
 
diff --git a/gcc/testsuite/rust/compile/match-structpattern-tuplefield-err.rs 
b/gcc/testsuite/rust/compile/match-structpattern-tuplefield-err.rs
new file mode 100644
index 000000000..ca4fb1ab1
--- /dev/null
+++ b/gcc/testsuite/rust/compile/match-structpattern-tuplefield-err.rs
@@ -0,0 +1,17 @@
+pub struct TupStruct (i32, i32);
+
+pub fn main() {
+    let t = TupStruct (1, 2);
+    match t {
+        TupStruct { 0: 1, 1: 2, 2: 3 } => {}
+        // { dg-error "variant TupStruct does not have a field named 2 
.E0026." "" { target *-*-* } .-1 }
+        TupStruct { 3: 3 } => {}
+        // { dg-error "pattern does not mention fields 0, 1 .E0027." "" { 
target *-*-* } .-1 }
+        // { dg-error "variant TupStruct does not have a field named 3 
.E0026." "" { target *-*-* } .-2 }
+        TupStruct { a: 3 } => {}
+        // { dg-error "tuple variant .TupStruct. written as struct variant 
.E0769." "" { target *-*-* } .-1 }
+        TupStruct { 0: 0.1f32, .. } => {}
+        // { dg-error "mismatched types, expected .i32. but got .f32. .E0308." 
"" { target *-*-* } .-1 }
+        _ => {}
+    }
+}
diff --git a/gcc/testsuite/rust/compile/match-structpattern-tuplefield.rs 
b/gcc/testsuite/rust/compile/match-structpattern-tuplefield.rs
new file mode 100644
index 000000000..8807e98ac
--- /dev/null
+++ b/gcc/testsuite/rust/compile/match-structpattern-tuplefield.rs
@@ -0,0 +1,11 @@
+pub struct TupStruct (i32, i32);
+
+pub fn main() {
+    let t = TupStruct (1, 2);
+    match t {
+        TupStruct { 0: 1, 1: 2 } => {}
+        TupStruct { 1: b, .. } => {}
+        TupStruct { 0: 1, .. } => {}
+        _ => {}
+    }
+}
diff --git 
a/gcc/testsuite/rust/execute/torture/match-structpattern-tuplefield.rs 
b/gcc/testsuite/rust/execute/torture/match-structpattern-tuplefield.rs
new file mode 100644
index 000000000..3c6657547
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/match-structpattern-tuplefield.rs
@@ -0,0 +1,10 @@
+pub struct TupStruct (i32, i32);
+
+pub fn main() -> i32 {
+    let mut t = TupStruct (1, 1);
+    match t {
+        TupStruct { 0: 1, 1: b } => { b -= 1 }
+        _ => {}
+    }
+    b
+}

base-commit: d2f8f6493738e752660b3deeb34529613f4adf1b
-- 
2.52.0

Reply via email to