Skip to content

Commit

Permalink
gccrs: match arms are a LUB
Browse files Browse the repository at this point in the history
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.

gcc/rust/ChangeLog:

	* backend/rust-compile-expr.cc (CompileExpr::visit): implement coercion
	* typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): this is a least upper bound coercion
	* typecheck/rust-unify.cc (UnifyRules::go): remove unify ! coercion

Signed-off-by: Philip Herron <[email protected]>
  • Loading branch information
philberty committed Jan 9, 2025
1 parent 1eaf085 commit cf01700
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 14 deletions.
13 changes: 12 additions & 1 deletion gcc/rust/backend/rust-compile-expr.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1148,8 +1148,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);

Expand Down
7 changes: 4 additions & 3 deletions gcc/rust/typecheck/rust-hir-type-check-expr.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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 ());
}
}

Expand Down
10 changes: 0 additions & 10 deletions gcc/rust/typecheck/rust-unify.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
// <http://www.gnu.org/licenses/>.

#include "rust-unify.h"
#include "rust-tyty.h"

namespace Rust {
namespace Resolver {
Expand Down Expand Up @@ -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:
Expand Down

0 comments on commit cf01700

Please sign in to comment.