diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-expr.h | 128 |
1 files changed, 67 insertions, 61 deletions
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h index 8c34b6c..5d6017c 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-expr.h +++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h @@ -1264,7 +1264,6 @@ protected: const TyTy::BaseType *root = lhs->get_root (); // look up lang item for arithmetic type - std::vector<PathProbeCandidate> candidates; std::string associated_item_name = Analysis::RustLangItem::ToString (lang_item_type); DefId respective_lang_item_id = UNKNOWN_DEFID; @@ -1272,28 +1271,34 @@ protected: = mappings->lookup_lang_item (lang_item_type, &respective_lang_item_id); // probe for the lang-item - if (lang_item_defined) - { - bool receiver_is_type_param - = root->get_kind () == TyTy::TypeKind::PARAM; - bool receiver_is_dyn = root->get_kind () == TyTy::TypeKind::DYNAMIC; - - bool receiver_is_generic = receiver_is_type_param || receiver_is_dyn; - bool probe_bounds = true; - bool probe_impls = !receiver_is_generic; - bool ignore_mandatory_trait_items = !receiver_is_generic; - - candidates = PathProbeType::Probe ( - root, HIR::PathIdentSegment (associated_item_name), probe_impls, - probe_bounds, ignore_mandatory_trait_items, respective_lang_item_id); - } + if (!lang_item_defined) + return false; + + bool receiver_is_type_param = root->get_kind () == TyTy::TypeKind::PARAM; + bool receiver_is_dyn = root->get_kind () == TyTy::TypeKind::DYNAMIC; + bool receiver_is_generic = receiver_is_type_param || receiver_is_dyn; + bool probe_bounds = true; + bool probe_impls = !receiver_is_generic; + bool ignore_mandatory_trait_items = !receiver_is_generic; - // autoderef + auto candidates = PathProbeType::Probe ( + root, HIR::PathIdentSegment (associated_item_name), probe_impls, + probe_bounds, ignore_mandatory_trait_items, respective_lang_item_id); + + // autoderef to find the relevant method std::vector<Adjustment> adjustments; PathProbeCandidate *resolved_candidate = MethodResolution::Select (candidates, lhs, adjustments); + if (resolved_candidate == nullptr) + return false; + + bool have_implementation_for_lang_item = resolved_candidate != nullptr; + if (!have_implementation_for_lang_item) + return false; // mark the required tree addressable + Adjuster adj (lhs); + TyTy::BaseType *receiver_adjusted_self_ty = adj.adjust_type (adjustments); if (Adjuster::needs_address (adjustments)) AddressTakenResolver::SetAddressTaken (*expr.get_expr ().get ()); @@ -1301,56 +1306,45 @@ protected: // handle the case where we are within the impl block for this lang_item // otherwise we end up with a recursive operator overload such as the i32 // operator overload trait - if (lang_item_defined && resolved_candidate != nullptr) + TypeCheckContextItem &fn_context = context->peek_context (); + if (fn_context.get_type () == TypeCheckContextItem::ItemType::IMPL_ITEM) { - TypeCheckContextItem &fn_context = context->peek_context (); - if (fn_context.get_type () == TypeCheckContextItem::ItemType::IMPL_ITEM) - { - auto &impl_item = fn_context.get_impl_item (); - HIR::ImplBlock *parent = impl_item.first; - HIR::Function *fn = impl_item.second; + auto &impl_item = fn_context.get_impl_item (); + HIR::ImplBlock *parent = impl_item.first; + HIR::Function *fn = impl_item.second; - if (parent->has_trait_ref () - && fn->get_function_name ().compare (associated_item_name) == 0) + if (parent->has_trait_ref () + && fn->get_function_name ().compare (associated_item_name) == 0) + { + TraitReference *trait_reference + = TraitResolver::Lookup (*parent->get_trait_ref ().get ()); + if (!trait_reference->is_error ()) { - TraitReference *trait_reference - = TraitResolver::Lookup (*parent->get_trait_ref ().get ()); - if (!trait_reference->is_error ()) - { - TyTy::BaseType *lookup = nullptr; - bool ok - = context->lookup_type (fn->get_mappings ().get_hirid (), - &lookup); - rust_assert (ok); - rust_assert (lookup->get_kind () == TyTy::TypeKind::FNDEF); - - TyTy::FnType *fntype = static_cast<TyTy::FnType *> (lookup); - rust_assert (fntype->is_method ()); - - Adjuster adj (lhs); - TyTy::BaseType *adjusted = adj.adjust_type (adjustments); - - bool is_lang_item_impl - = trait_reference->get_mappings ().get_defid () - == respective_lang_item_id; - bool self_is_lang_item_self - = fntype->get_self_type ()->is_equal (*adjusted); - bool recursive_operator_overload - = is_lang_item_impl && self_is_lang_item_self; - - lang_item_defined = !recursive_operator_overload; - } + TyTy::BaseType *lookup = nullptr; + bool ok + = context->lookup_type (fn->get_mappings ().get_hirid (), + &lookup); + rust_assert (ok); + rust_assert (lookup->get_kind () == TyTy::TypeKind::FNDEF); + + TyTy::FnType *fntype = static_cast<TyTy::FnType *> (lookup); + rust_assert (fntype->is_method ()); + + bool is_lang_item_impl + = trait_reference->get_mappings ().get_defid () + == respective_lang_item_id; + bool self_is_lang_item_self + = fntype->get_self_type ()->is_equal ( + *receiver_adjusted_self_ty); + bool recursive_operator_overload + = is_lang_item_impl && self_is_lang_item_self; + + if (recursive_operator_overload) + return false; } } } - bool have_implementation_for_lang_item = resolved_candidate != nullptr; - if (!lang_item_defined || !have_implementation_for_lang_item) - { - // no operator overload exists for this - return false; - } - // now its just like a method-call-expr context->insert_receiver (expr.get_mappings ().get_hirid (), lhs); @@ -1425,8 +1419,20 @@ protected: } } + // handle generics + if (!receiver_is_type_param) + { + if (lookup->needs_generic_substitutions ()) + { + lookup = SubstMapper::InferSubst (lookup, expr.get_locus ()); + } + } + // type check the arguments if required TyTy::FnType *type = static_cast<TyTy::FnType *> (lookup); + rust_assert (type->num_params () > 0); + auto fnparam = type->param_at (0); + fnparam.second->unify (receiver_adjusted_self_ty); // typecheck the self if (rhs == nullptr) { rust_assert (type->num_params () == 1); @@ -1439,7 +1445,7 @@ protected: } // get the return type - TyTy::BaseType *function_ret_tyty = fn->get_return_type ()->clone (); + TyTy::BaseType *function_ret_tyty = type->get_return_type ()->clone (); // store the expected fntype context->insert_operator_overload (expr.get_mappings ().get_hirid (), type); |