diff options
author | Philip Herron <philip.herron@embecosm.com> | 2021-11-24 18:16:37 +0000 |
---|---|---|
committer | Philip Herron <philip.herron@embecosm.com> | 2021-11-25 14:11:10 +0000 |
commit | 12b7154e90f676222262fe3d6935a950805a8566 (patch) | |
tree | 80b6d67075bf8d3adb1ceefdc039b30e6d0cb306 /gcc | |
parent | 717b6da459b26ace9a3c303cfa5e485ff8935709 (diff) | |
download | gcc-12b7154e90f676222262fe3d6935a950805a8566.zip gcc-12b7154e90f676222262fe3d6935a950805a8566.tar.gz gcc-12b7154e90f676222262fe3d6935a950805a8566.tar.bz2 |
improve the error handling on operator overload cases
This operator overloading function was extracted from the callers within
compound assignment etc, where we needed to be able to fall back to code
within the same function. This improves the error handling to return early
when there are no such lang-items or no available method instead of trying
to continue. It flattens the conditional's previously required in the code
path.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-expr.h | 114 |
1 files changed, 54 insertions, 60 deletions
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h index fb1cd97..4923426 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-expr.h +++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h @@ -1260,7 +1260,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; @@ -1268,26 +1267,30 @@ 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; - // autoderef + 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; + + 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 if (Adjuster::needs_address (adjustments)) @@ -1297,56 +1300,47 @@ 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 ()); + + 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; + + 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); |