diff options
author | Philip Herron <herron.philip@googlemail.com> | 2023-02-27 13:34:30 +0000 |
---|---|---|
committer | Philip Herron <philip.herron@embecosm.com> | 2023-02-28 20:38:35 +0000 |
commit | bd4556fb65c64396fc6a429bc03b58932dc3c263 (patch) | |
tree | fa250fa0bb991bc10f1adbe0027b12cb4ef61aa0 /gcc | |
parent | 4b43f026aac8f0b9a918082551abca6bfa4d9912 (diff) | |
download | gcc-bd4556fb65c64396fc6a429bc03b58932dc3c263.zip gcc-bd4556fb65c64396fc6a429bc03b58932dc3c263.tar.gz gcc-bd4556fb65c64396fc6a429bc03b58932dc3c263.tar.bz2 |
gccrs: Allow infer vars on the lhs too
We should allow implicit inference on the expected side too not just the
receiver.
Signed-off-by: Philip Herron <herron.philip@googlemail.com>
gcc/rust/ChangeLog:
* typecheck/rust-unify.cc (UnifyRules::go): allow lhs infer vars
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/typecheck/rust-unify.cc | 58 |
1 files changed, 42 insertions, 16 deletions
diff --git a/gcc/rust/typecheck/rust-unify.cc b/gcc/rust/typecheck/rust-unify.cc index 37ef71e..70210aa 100644 --- a/gcc/rust/typecheck/rust-unify.cc +++ b/gcc/rust/typecheck/rust-unify.cc @@ -149,26 +149,52 @@ UnifyRules::go () } } - // inject inference vars if required - bool got_param = rtype->get_kind () == TyTy::TypeKind::PARAM; - bool lhs_is_infer_var = ltype->get_kind () == TyTy::TypeKind::INFER; - bool expected_is_concrete = ltype->is_concrete () && !lhs_is_infer_var; - bool needs_infer = expected_is_concrete && got_param; - if (infer_flag && needs_infer) + if (infer_flag) { - TyTy::ParamType *p = static_cast<TyTy::ParamType *> (rtype); - TyTy::TyVar iv = TyTy::TyVar::get_implicit_infer_var (rhs.get_locus ()); - rust_assert (iv.get_tyty ()->get_kind () == TyTy::TypeKind::INFER); - TyTy::InferType *i = static_cast<TyTy::InferType *> (iv.get_tyty ()); + bool rgot_param = rtype->get_kind () == TyTy::TypeKind::PARAM; + bool lhs_is_infer_var = ltype->get_kind () == TyTy::TypeKind::INFER; + bool expected_is_concrete = ltype->is_concrete () && !lhs_is_infer_var; + bool rneeds_infer = expected_is_concrete && rgot_param; - infers.push_back ({p->get_ref (), p->get_ty_ref (), p, i}); + bool lgot_param = ltype->get_kind () == TyTy::TypeKind::PARAM; + bool rhs_is_infer_var = rtype->get_kind () == TyTy::TypeKind::INFER; + bool receiver_is_concrete = rtype->is_concrete () && !rhs_is_infer_var; + bool lneeds_infer = receiver_is_concrete && lgot_param; - // FIXME - // this is hacky to set the implicit param lets make this a function - p->set_ty_ref (i->get_ref ()); + if (rneeds_infer) + { + TyTy::ParamType *p = static_cast<TyTy::ParamType *> (rtype); + TyTy::TyVar iv + = TyTy::TyVar::get_implicit_infer_var (rhs.get_locus ()); + rust_assert (iv.get_tyty ()->get_kind () == TyTy::TypeKind::INFER); + TyTy::InferType *i = static_cast<TyTy::InferType *> (iv.get_tyty ()); + + infers.push_back ({p->get_ref (), p->get_ty_ref (), p, i}); + + // FIXME + // this is hacky to set the implicit param lets make this a function + p->set_ty_ref (i->get_ref ()); + + // set the rtype now to the new inference var + rtype = i; + } + else if (lneeds_infer) + { + TyTy::ParamType *p = static_cast<TyTy::ParamType *> (ltype); + TyTy::TyVar iv + = TyTy::TyVar::get_implicit_infer_var (lhs.get_locus ()); + rust_assert (iv.get_tyty ()->get_kind () == TyTy::TypeKind::INFER); + TyTy::InferType *i = static_cast<TyTy::InferType *> (iv.get_tyty ()); + + infers.push_back ({p->get_ref (), p->get_ty_ref (), p, i}); - // set the rtype now to the new inference var - rtype = i; + // FIXME + // this is hacky to set the implicit param lets make this a function + p->set_ty_ref (i->get_ref ()); + + // set the rtype now to the new inference var + ltype = i; + } } switch (ltype->get_kind ()) |