[gcc/devel/rust/master] gccrs: match arms are a LUB

Thomas Schwinge tschwinge@gcc.gnu.org
Wed Mar 26 14:03:37 GMT 2025


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

commit b4a525ce39716cd1e9355b8503c78f3dd0fdbbb3
Author: Philip Herron <herron.philip@googlemail.com>
Date:   Thu Jan 9 16:47:47 2025 +0000

    gccrs: match arms are a LUB
    
    Unify rules are not the same as coercion rules. The coercion of ! is
    allowed to any type but not for a unify site which is different.
    
    Match arms are another least upper bound coercion.
    
    gcc/rust/ChangeLog:
    
            * backend/rust-compile-expr.cc (CompileExpr::visit): implement coercion
            * typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): this is an LUB
            * typecheck/rust-unify.cc (UnifyRules::go): remove unify ! coercion
    
    Signed-off-by: Philip Herron <herron.philip@googlemail.com>

Diff:
---
 gcc/rust/backend/rust-compile-expr.cc          | 13 ++++++++++++-
 gcc/rust/typecheck/rust-hir-type-check-expr.cc |  7 ++++---
 gcc/rust/typecheck/rust-unify.cc               | 10 ----------
 3 files changed, 16 insertions(+), 14 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-expr.cc b/gcc/rust/backend/rust-compile-expr.cc
index 6a0db31efe8a..c24a22a3118f 100644
--- a/gcc/rust/backend/rust-compile-expr.cc
+++ b/gcc/rust/backend/rust-compile-expr.cc
@@ -1156,8 +1156,19 @@ CompileExpr::visit (HIR::MatchExpr &expr)
 	  location_t arm_locus = kase_arm.get_locus ();
 	  tree kase_expr_tree = CompileExpr::Compile (kase.get_expr (), ctx);
 	  tree result_reference = Backend::var_expression (tmp, arm_locus);
+
+	  TyTy::BaseType *actual = nullptr;
+	  bool ok = ctx->get_tyctx ()->lookup_type (
+	    kase.get_expr ().get_mappings ().get_hirid (), &actual);
+	  rust_assert (ok);
+
+	  tree coerced_result
+	    = coercion_site (kase.get_expr ().get_mappings ().get_hirid (),
+			     kase_expr_tree, actual, expr_tyty,
+			     expr.get_locus (), arm_locus);
+
 	  tree assignment
-	    = Backend::assignment_statement (result_reference, kase_expr_tree,
+	    = Backend::assignment_statement (result_reference, coerced_result,
 					     arm_locus);
 	  ctx->add_statement (assignment);
 
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
index c968226fc14d..2554a72dc2a7 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
@@ -1532,9 +1532,10 @@ TypeCheckExpr::visit (HIR::MatchExpr &expr)
   for (size_t i = 1; i < kase_block_tys.size (); i++)
     {
       TyTy::BaseType *kase_ty = kase_block_tys.at (i);
-      infered = unify_site (expr.get_mappings ().get_hirid (),
-			    TyTy::TyWithLocation (infered),
-			    TyTy::TyWithLocation (kase_ty), expr.get_locus ());
+      infered
+	= coercion_site (expr.get_mappings ().get_hirid (),
+			 TyTy::TyWithLocation (infered),
+			 TyTy::TyWithLocation (kase_ty), expr.get_locus ());
     }
 }
 
diff --git a/gcc/rust/typecheck/rust-unify.cc b/gcc/rust/typecheck/rust-unify.cc
index d5344036fcc1..e0aa68943961 100644
--- a/gcc/rust/typecheck/rust-unify.cc
+++ b/gcc/rust/typecheck/rust-unify.cc
@@ -17,7 +17,6 @@
 // <http://www.gnu.org/licenses/>.
 
 #include "rust-unify.h"
-#include "rust-tyty.h"
 
 namespace Rust {
 namespace Resolver {
@@ -238,15 +237,6 @@ UnifyRules::go ()
 	}
     }
 
-  // The never type should always get coerced to the type it's being matched
-  // against, so in that case, ltype. This avoids doing the same check in all
-  // the `expect_*` functions.
-  // However, this does not work if we have an annoying ltype - like INFER.
-  // TODO: Is ltype == Infer the only special case here? What about projections?
-  // references?
-  if (rtype->get_kind () == TyTy::NEVER && ltype->get_kind () != TyTy::INFER)
-    return ltype->clone ();
-
   switch (ltype->get_kind ())
     {
     case TyTy::INFER:


More information about the Gcc-cvs mailing list