aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPhilip Herron <philip.herron@embecosm.com>2021-09-17 14:29:02 +0100
committerPhilip Herron <philip.herron@embecosm.com>2021-09-17 15:46:43 +0100
commit135807db03756de55e6368b07a9884134160867e (patch)
tree2e2a1a82f3fb8b4dc43e780270d7bc473505b443 /gcc
parente29a8a4172ae5c4f85d0e21d7edfaf934744c9fb (diff)
downloadgcc-135807db03756de55e6368b07a9884134160867e.zip
gcc-135807db03756de55e6368b07a9884134160867e.tar.gz
gcc-135807db03756de55e6368b07a9884134160867e.tar.bz2
When calling functions the arguments are a coercion site
This changes all type checking of arguments to function calls to be coercion sites instead of unifications. This allows for cases like mutable pointers being coerced to immutable reference for example.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/typecheck/rust-tyty-coercion.h31
-rw-r--r--gcc/rust/typecheck/rust-tyty.cc8
2 files changed, 35 insertions, 4 deletions
diff --git a/gcc/rust/typecheck/rust-tyty-coercion.h b/gcc/rust/typecheck/rust-tyty-coercion.h
index 2d59e88..5ab8542 100644
--- a/gcc/rust/typecheck/rust-tyty-coercion.h
+++ b/gcc/rust/typecheck/rust-tyty-coercion.h
@@ -1326,6 +1326,37 @@ public:
: BaseCoercionRules (base), base (base)
{}
+ BaseType *coerce (BaseType *other) override final
+ {
+ if (!base->can_resolve ())
+ return BaseCoercionRules::coerce (other);
+
+ BaseType *lookup = base->resolve ();
+ return lookup->unify (other);
+ }
+
+ void visit (PlaceholderType &type) override
+ {
+ if (base->get_symbol ().compare (type.get_symbol ()) != 0)
+ {
+ BaseCoercionRules::visit (type);
+ return;
+ }
+
+ resolved = type.clone ();
+ }
+
+ void visit (InferType &type) override
+ {
+ if (type.get_infer_kind () != InferType::InferTypeKind::GENERAL)
+ {
+ BaseCoercionRules::visit (type);
+ return;
+ }
+
+ resolved = base->clone ();
+ }
+
private:
BaseType *get_base () override { return base; }
diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc
index dd33975..bfe1043 100644
--- a/gcc/rust/typecheck/rust-tyty.cc
+++ b/gcc/rust/typecheck/rust-tyty.cc
@@ -2358,7 +2358,7 @@ TypeCheckCallExpr::visit (ADTType &type)
return false;
}
- auto res = field_tyty->unify (arg);
+ auto res = field_tyty->coerce (arg);
if (res->get_kind () == TyTy::TypeKind::ERROR)
{
return false;
@@ -2420,7 +2420,7 @@ TypeCheckCallExpr::visit (FnType &type)
if (i < type.num_params ())
{
auto fnparam = type.param_at (i);
- resolved_argument_type = fnparam.second->unify (argument_expr_tyty);
+ resolved_argument_type = fnparam.second->coerce (argument_expr_tyty);
if (argument_expr_tyty->get_kind () == TyTy::TypeKind::ERROR)
{
rust_error_at (param->get_locus (),
@@ -2479,7 +2479,7 @@ TypeCheckCallExpr::visit (FnPtr &type)
return false;
}
- auto resolved_argument_type = fnparam->unify (argument_expr_tyty);
+ auto resolved_argument_type = fnparam->coerce (argument_expr_tyty);
if (argument_expr_tyty->get_kind () == TyTy::TypeKind::ERROR)
{
rust_error_at (param->get_locus (),
@@ -2530,7 +2530,7 @@ TypeCheckMethodCallExpr::visit (FnType &type)
return false;
}
- auto resolved_argument_type = fnparam.second->unify (argument_expr_tyty);
+ auto resolved_argument_type = fnparam.second->coerce (argument_expr_tyty);
if (argument_expr_tyty->get_kind () == TyTy::TypeKind::ERROR)
{
rust_error_at (param->get_locus (),