https://gcc.gnu.org/g:ad46f0871d80966a1dd1adf7bf444c99f094d42a

commit ad46f0871d80966a1dd1adf7bf444c99f094d42a
Author: Philip Herron <herron.phi...@googlemail.com>
Date:   Tue Jan 21 17:20:06 2025 +0000

    gccrs: add support for ref literal patterns
    
    Fixes Rust-GCC#3174
    
    gcc/rust/ChangeLog:
    
            * backend/rust-compile-pattern.cc (CompilePatternBindings::visit): 
make recursive
            * typecheck/rust-hir-type-check-pattern.cc 
(TypeCheckPattern::visit): handle ref flag
    
    gcc/testsuite/ChangeLog:
    
            * rust/compile/nr2/exclude: nr2 cant handle this
            * rust/compile/issue-3174.rs: New test.
    
    Signed-off-by: Philip Herron <herron.phi...@googlemail.com>

Diff:
---
 gcc/rust/backend/rust-compile-pattern.cc          | 18 ++++++++++-----
 gcc/rust/typecheck/rust-hir-type-check-pattern.cc | 13 +++++++++--
 gcc/testsuite/rust/compile/issue-3174.rs          | 28 +++++++++++++++++++++++
 gcc/testsuite/rust/compile/nr2/exclude            |  1 +
 4 files changed, 52 insertions(+), 8 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-pattern.cc 
b/gcc/rust/backend/rust-compile-pattern.cc
index 726ade61639a..1e33c4899634 100644
--- a/gcc/rust/backend/rust-compile-pattern.cc
+++ b/gcc/rust/backend/rust-compile-pattern.cc
@@ -481,8 +481,7 @@ CompilePatternBindings::visit (HIR::TupleStructPattern 
&pattern)
                                                      tuple_field_index++,
                                                      pattern->get_locus ());
 
-               ctx->insert_pattern_binding (
-                 pattern->get_mappings ().get_hirid (), binding);
+               CompilePatternBindings::Compile (*pattern, binding, ctx);
              }
          }
        else
@@ -497,8 +496,7 @@ CompilePatternBindings::visit (HIR::TupleStructPattern 
&pattern)
                                                      tuple_field_index++,
                                                      pattern->get_locus ());
 
-               ctx->insert_pattern_binding (
-                 pattern->get_mappings ().get_hirid (), binding);
+               CompilePatternBindings::Compile (*pattern, binding, ctx);
              }
          }
       }
@@ -607,8 +605,16 @@ CompilePatternBindings::visit (HIR::ReferencePattern 
&pattern)
 void
 CompilePatternBindings::visit (HIR::IdentifierPattern &pattern)
 {
-  ctx->insert_pattern_binding (pattern.get_mappings ().get_hirid (),
-                              match_scrutinee_expr);
+  if (!pattern.get_is_ref ())
+    {
+      ctx->insert_pattern_binding (pattern.get_mappings ().get_hirid (),
+                                  match_scrutinee_expr);
+      return;
+    }
+
+  tree ref = address_expression (match_scrutinee_expr,
+                                EXPR_LOCATION (match_scrutinee_expr));
+  ctx->insert_pattern_binding (pattern.get_mappings ().get_hirid (), ref);
 }
 
 void
diff --git a/gcc/rust/typecheck/rust-hir-type-check-pattern.cc 
b/gcc/rust/typecheck/rust-hir-type-check-pattern.cc
index 52d125354d53..765504fa785e 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-pattern.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-pattern.cc
@@ -519,9 +519,18 @@ TypeCheckPattern::visit (HIR::RangePattern &pattern)
 }
 
 void
-TypeCheckPattern::visit (HIR::IdentifierPattern &)
+TypeCheckPattern::visit (HIR::IdentifierPattern &pattern)
 {
-  infered = parent;
+  if (!pattern.get_is_ref ())
+    {
+      infered = parent;
+      return;
+    }
+
+  infered = new TyTy::ReferenceType (pattern.get_mappings ().get_hirid (),
+                                    TyTy::TyVar (parent->get_ref ()),
+                                    pattern.is_mut () ? Mutability::Mut
+                                                      : Mutability::Imm);
 }
 
 void
diff --git a/gcc/testsuite/rust/compile/issue-3174.rs 
b/gcc/testsuite/rust/compile/issue-3174.rs
new file mode 100644
index 000000000000..87588e1ed241
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3174.rs
@@ -0,0 +1,28 @@
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+enum Option {
+    Some(i32),
+    None,
+}
+
+impl Option {
+    fn add(&mut self) {
+        match *self {
+            Option::Some(ref mut a) => *a += 1,
+            Option::None => {}
+        }
+    }
+}
+
+fn main() {
+    unsafe {
+        let mut a = Option::None;
+        a.add();
+        let _s = "%d\n\0";
+        let _s = _s as *const str;
+        let s = _s as *const i8;
+        printf(s, a);
+    }
+}
diff --git a/gcc/testsuite/rust/compile/nr2/exclude 
b/gcc/testsuite/rust/compile/nr2/exclude
index c5c7326500d6..e5e5c12a978a 100644
--- a/gcc/testsuite/rust/compile/nr2/exclude
+++ b/gcc/testsuite/rust/compile/nr2/exclude
@@ -150,4 +150,5 @@ issue-2953-1.rs
 issue-3030.rs
 traits12.rs
 try-trait.rs
+issue-3174.rs
 # please don't delete the trailing newline

Reply via email to