diff options
author | Philip Herron <philip.herron@embecosm.com> | 2021-09-17 14:29:02 +0100 |
---|---|---|
committer | Philip Herron <philip.herron@embecosm.com> | 2021-09-17 15:46:43 +0100 |
commit | 135807db03756de55e6368b07a9884134160867e (patch) | |
tree | 2e2a1a82f3fb8b4dc43e780270d7bc473505b443 /gcc | |
parent | e29a8a4172ae5c4f85d0e21d7edfaf934744c9fb (diff) | |
download | gcc-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.h | 31 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty.cc | 8 |
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 (), |