diff options
author | Philip Herron <philip.herron@embecosm.com> | 2022-04-28 13:09:15 +0100 |
---|---|---|
committer | Philip Herron <philip.herron@embecosm.com> | 2022-04-28 13:09:15 +0100 |
commit | be158fc97f7f4d43d60797f2af27c86753b0ffb5 (patch) | |
tree | 3d0f3aaef56b6190bf19ef2722add0047afce145 /gcc | |
parent | 712ae2f173df0c2d9018bf5ce708ffbbaee10d64 (diff) | |
download | gcc-be158fc97f7f4d43d60797f2af27c86753b0ffb5.zip gcc-be158fc97f7f4d43d60797f2af27c86753b0ffb5.tar.gz gcc-be158fc97f7f4d43d60797f2af27c86753b0ffb5.tar.bz2 |
Complete refactor of generic traits handling
From PR #1086 I introduced a new setup_associated_types2 interface which
is used to ensure we handle the complex associated types in libcore slices
but this interface was inconsistant as well as the get_projected_type.
This path refactors the code base to get rid of the old
setup_associated_types interface in favour of this new one. It also removes
the get_projected_type interface which was not going to work either.
Fixes #1105
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/backend/rust-compile-implitem.cc | 1 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-item.cc | 1 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-resolve-path.cc | 15 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-path-probe.h | 12 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-trait-ref.h | 11 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-trait-resolve.cc | 64 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-path.cc | 71 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-type.cc | 67 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty.cc | 22 |
9 files changed, 67 insertions, 197 deletions
diff --git a/gcc/rust/backend/rust-compile-implitem.cc b/gcc/rust/backend/rust-compile-implitem.cc index 7cc214c..9dc6d14 100644 --- a/gcc/rust/backend/rust-compile-implitem.cc +++ b/gcc/rust/backend/rust-compile-implitem.cc @@ -52,6 +52,7 @@ CompileTraitItem::visit (HIR::TraitItemFunc &func) rust_assert (concrete->get_kind () == TyTy::TypeKind::FNDEF); TyTy::FnType *fntype = static_cast<TyTy::FnType *> (concrete); + fntype->monomorphize (); // items can be forward compiled which means we may not need to invoke this // code. We might also have already compiled this generic function as well. diff --git a/gcc/rust/backend/rust-compile-item.cc b/gcc/rust/backend/rust-compile-item.cc index 80b7ceb..969c852 100644 --- a/gcc/rust/backend/rust-compile-item.cc +++ b/gcc/rust/backend/rust-compile-item.cc @@ -127,6 +127,7 @@ CompileItem::visit (HIR::Function &function) { rust_assert (concrete->get_kind () == TyTy::TypeKind::FNDEF); fntype = static_cast<TyTy::FnType *> (concrete); + fntype->monomorphize (); } } diff --git a/gcc/rust/backend/rust-compile-resolve-path.cc b/gcc/rust/backend/rust-compile-resolve-path.cc index 2ad672d..55a2fff 100644 --- a/gcc/rust/backend/rust-compile-resolve-path.cc +++ b/gcc/rust/backend/rust-compile-resolve-path.cc @@ -251,21 +251,6 @@ HIRCompileBase::query_compile (HirId ref, TyTy::BaseType *lookup, rust_assert (ok); // found rust_assert (trait_item_ref->is_optional ()); // has definition - Analysis::NodeMapping trait_mappings - = trait_item_ref->get_parent_trait_mappings (); - - HirId associated_impl_id; - ok = ctx->get_tyctx ()->lookup_associated_impl_mapping_for_self ( - trait_mappings.get_hirid (), receiver, &associated_impl_id); - rust_assert (ok); - - Resolver::AssociatedImplTrait *associated = nullptr; - bool found_associated_trait_impl - = ctx->get_tyctx ()->lookup_associated_trait_impl ( - associated_impl_id, &associated); - rust_assert (found_associated_trait_impl); - associated->setup_associated_types (); - return CompileTraitItem::Compile ( trait_item_ref->get_hir_trait_item (), ctx, lookup, true, expr_locus); diff --git a/gcc/rust/typecheck/rust-hir-path-probe.h b/gcc/rust/typecheck/rust-hir-path-probe.h index fda505a..348b9f7 100644 --- a/gcc/rust/typecheck/rust-hir-path-probe.h +++ b/gcc/rust/typecheck/rust-hir-path-probe.h @@ -326,18 +326,6 @@ protected: } TyTy::BaseType *trait_item_tyty = trait_item_ref->get_tyty (); - if (impl != nullptr && !is_reciever_generic ()) - - { - HirId impl_block_id = impl->get_mappings ().get_hirid (); - AssociatedImplTrait *lookup_associated = nullptr; - bool found_impl_trait - = context->lookup_associated_trait_impl (impl_block_id, - &lookup_associated); - // see testsuite/rust/compile/torture/traits10.rs this can be false - if (found_impl_trait) - lookup_associated->setup_associated_types (); - } // we can substitute the Self with the receiver here if (trait_item_tyty->get_kind () == TyTy::TypeKind::FNDEF) diff --git a/gcc/rust/typecheck/rust-hir-trait-ref.h b/gcc/rust/typecheck/rust-hir-trait-ref.h index a12736f..6eec461 100644 --- a/gcc/rust/typecheck/rust-hir-trait-ref.h +++ b/gcc/rust/typecheck/rust-hir-trait-ref.h @@ -454,18 +454,11 @@ public: TyTy::BaseType *get_self () { return self; } - void setup_associated_types (); - - void setup_associated_types2 (const TyTy::BaseType *self, - const TyTy::TypeBoundPredicate &bound); + void setup_associated_types (const TyTy::BaseType *self, + const TyTy::TypeBoundPredicate &bound); void reset_associated_types (); - TyTy::BaseType *get_projected_type (const TraitItemReference *trait_item_ref, - TyTy::BaseType *reciever, HirId ref, - HIR::GenericArgs &trait_generics, - Location expr_locus); - private: TraitReference *trait; HIR::ImplBlock *impl; diff --git a/gcc/rust/typecheck/rust-hir-trait-resolve.cc b/gcc/rust/typecheck/rust-hir-trait-resolve.cc index 5681ebd..e7fe0e0 100644 --- a/gcc/rust/typecheck/rust-hir-trait-resolve.cc +++ b/gcc/rust/typecheck/rust-hir-trait-resolve.cc @@ -154,29 +154,7 @@ TraitItemReference::associated_type_reset () const } void -AssociatedImplTrait::setup_associated_types () -{ - ImplTypeIterator iter (*impl, [&] (HIR::TypeAlias &type) { - TraitItemReference *resolved_trait_item = nullptr; - bool ok = trait->lookup_trait_item (type.get_new_type_name (), - &resolved_trait_item); - if (!ok) - return; - if (resolved_trait_item->get_trait_item_type () - != TraitItemReference::TraitItemType::TYPE) - return; - - TyTy::BaseType *lookup; - if (!context->lookup_type (type.get_mappings ().get_hirid (), &lookup)) - return; - - resolved_trait_item->associated_type_set (lookup); - }); - iter.go (); -} - -void -AssociatedImplTrait::setup_associated_types2 ( +AssociatedImplTrait::setup_associated_types ( const TyTy::BaseType *self, const TyTy::TypeBoundPredicate &bound) { // compute the constrained impl block generic arguments based on self and the @@ -390,46 +368,6 @@ TraitItemReference::is_object_safe () const return false; } -TyTy::BaseType * -AssociatedImplTrait::get_projected_type ( - const TraitItemReference *trait_item_ref, TyTy::BaseType *receiver, HirId ref, - HIR::GenericArgs &trait_generics, Location expr_locus) -{ - TyTy::BaseType *trait_item_tyty = trait_item_ref->get_tyty ()->clone (); - - // we can substitute the Self with the receiver here - if (trait_item_tyty->get_kind () == TyTy::TypeKind::FNDEF) - { - TyTy::FnType *fn = static_cast<TyTy::FnType *> (trait_item_tyty); - TyTy::SubstitutionParamMapping *param = nullptr; - for (auto ¶m_mapping : fn->get_substs ()) - { - const HIR::TypeParam &type_param = param_mapping.get_generic_param (); - if (type_param.get_type_representation ().compare ("Self") == 0) - { - param = ¶m_mapping; - break; - } - } - rust_assert (param != nullptr); - - std::vector<TyTy::SubstitutionArg> mappings; - mappings.push_back (TyTy::SubstitutionArg (param, receiver->clone ())); - - TyTy::SubstitutionArgumentMappings args (std::move (mappings), - expr_locus); - trait_item_tyty = SubstMapperInternal::Resolve (trait_item_tyty, args); - } - - if (!trait_generics.is_empty ()) - { - trait_item_tyty - = SubstMapper::Resolve (trait_item_tyty, expr_locus, &trait_generics); - } - - return trait_item_tyty; -} - // rust-hir-path-probe.h void diff --git a/gcc/rust/typecheck/rust-hir-type-check-path.cc b/gcc/rust/typecheck/rust-hir-type-check-path.cc index 9960e76..3823c57 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-path.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-path.cc @@ -67,41 +67,41 @@ TypeCheckExpr::visit (HIR::QualifiedPathInExpression &expr) // inherit the bound root->inherit_bounds ({specified_bound}); - // we need resolve to the impl block - NodeId impl_resolved_id = UNKNOWN_NODEID; - bool ok = resolver->lookup_resolved_name ( - qual_path_type.get_mappings ().get_nodeid (), &impl_resolved_id); - rust_assert (ok); - - HirId impl_block_id; - ok = mappings->lookup_node_to_hir (expr.get_mappings ().get_crate_num (), - impl_resolved_id, &impl_block_id); - rust_assert (ok); - - AssociatedImplTrait *lookup_associated = nullptr; - bool found_impl_trait - = context->lookup_associated_trait_impl (impl_block_id, &lookup_associated); - rust_assert (found_impl_trait); - + // lookup the associated item from the specified bound HIR::PathExprSegment &item_seg = expr.get_segments ().at (0); - - const TraitItemReference *trait_item_ref = nullptr; - ok = trait_ref->lookup_trait_item (item_seg.get_segment ().as_string (), - &trait_item_ref); - if (!ok) + HIR::PathIdentSegment item_seg_identifier = item_seg.get_segment (); + TyTy::TypeBoundPredicateItem item + = specified_bound.lookup_associated_item (item_seg_identifier.as_string ()); + if (item.is_error ()) { rust_error_at (item_seg.get_locus (), "unknown associated item"); return; } - HIR::GenericArgs trait_generics = qual_path_type.trait_has_generic_args () - ? qual_path_type.get_trait_generic_args () - : HIR::GenericArgs::create_empty (); + // infer the root type + infered = item.get_tyty_for_receiver (root); - lookup_associated->setup_associated_types (); - infered = lookup_associated->get_projected_type ( - trait_item_ref, root, item_seg.get_mappings ().get_hirid (), trait_generics, - item_seg.get_locus ()); + // we need resolve to the impl block + NodeId impl_resolved_id = UNKNOWN_NODEID; + bool have_associated_impl = resolver->lookup_resolved_name ( + qual_path_type.get_mappings ().get_nodeid (), &impl_resolved_id); + AssociatedImplTrait *lookup_associated = nullptr; + if (have_associated_impl) + { + HirId impl_block_id; + bool ok + = mappings->lookup_node_to_hir (expr.get_mappings ().get_crate_num (), + impl_resolved_id, &impl_block_id); + rust_assert (ok); + + bool found_impl_trait + = context->lookup_associated_trait_impl (impl_block_id, + &lookup_associated); + if (found_impl_trait) + { + lookup_associated->setup_associated_types (root, specified_bound); + } + } // turbo-fish segment path::<ty> if (item_seg.has_generic_args ()) @@ -119,6 +119,7 @@ TypeCheckExpr::visit (HIR::QualifiedPathInExpression &expr) } // continue on as a path-in-expression + const TraitItemReference *trait_item_ref = item.get_raw_item (); NodeId root_resolved_node_id = trait_item_ref->get_mappings ().get_nodeid (); bool fully_resolved = expr.get_segments ().size () <= 1; @@ -348,20 +349,6 @@ TypeCheckExpr::resolve_segments (NodeId root_resolved_node_id, HIR::ImplBlock *impl = candidate.item.trait.impl; if (impl != nullptr) { - AssociatedImplTrait *lookup_associated = nullptr; - bool found_impl_trait = context->lookup_associated_trait_impl ( - impl->get_mappings ().get_hirid (), &lookup_associated); - - // setup associated mappings if possible we might be resolving a - // path within a default implementation of a trait function - // see: testsuite/rust/compile/torture/traits16.rs - if (found_impl_trait) - lookup_associated->setup_associated_types (); - - // we need a new ty_ref_id for this trait item - tyseg = tyseg->clone (); - tyseg->set_ty_ref (mappings->get_next_hir_id ()); - // get the associated impl block associated_impl_block = impl; } diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.cc b/gcc/rust/typecheck/rust-hir-type-check-type.cc index 914bebb..bd40344 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-type.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-type.cc @@ -142,31 +142,35 @@ TypeCheckType::visit (HIR::QualifiedPathInType &path) return; } + // get the predicate for the bound + auto specified_bound + = get_predicate_from_bound (*qual_path_type.get_trait ().get ()); + if (specified_bound.is_error ()) + return; + + // inherit the bound + root->inherit_bounds ({specified_bound}); + + // lookup the associated item from the specified bound std::unique_ptr<HIR::TypePathSegment> &item_seg = path.get_associated_segment (); - const TraitItemReference *trait_item_ref = nullptr; - bool ok - = trait_ref->lookup_trait_item (item_seg->get_ident_segment ().as_string (), - &trait_item_ref); - if (!ok) + HIR::PathIdentSegment item_seg_identifier = item_seg->get_ident_segment (); + TyTy::TypeBoundPredicateItem item + = specified_bound.lookup_associated_item (item_seg_identifier.as_string ()); + if (item.is_error ()) { rust_error_at (item_seg->get_locus (), "unknown associated item"); return; } - // this will be the placeholder from the trait but we may be able to project - // it based on the impl block - translated = trait_item_ref->get_tyty (); - - // this is the associated generics we need to potentially apply - HIR::GenericArgs trait_generics = qual_path_type.trait_has_generic_args () - ? qual_path_type.get_trait_generic_args () - : HIR::GenericArgs::create_empty (); + // infer the root type + translated = item.get_tyty_for_receiver (root); // we need resolve to the impl block NodeId impl_resolved_id = UNKNOWN_NODEID; bool have_associated_impl = resolver->lookup_resolved_name ( qual_path_type.get_mappings ().get_nodeid (), &impl_resolved_id); + AssociatedImplTrait *lookup_associated = nullptr; if (have_associated_impl) { HirId impl_block_id; @@ -175,30 +179,16 @@ TypeCheckType::visit (HIR::QualifiedPathInType &path) impl_resolved_id, &impl_block_id); rust_assert (ok); - AssociatedImplTrait *lookup_associated = nullptr; bool found_impl_trait = context->lookup_associated_trait_impl (impl_block_id, &lookup_associated); - rust_assert (found_impl_trait); - - // project - lookup_associated->setup_associated_types (); - translated = lookup_associated->get_projected_type ( - trait_item_ref, root, item_seg->get_mappings ().get_hirid (), - trait_generics, item_seg->get_locus ()); - } - - if (translated->get_kind () == TyTy::TypeKind::PLACEHOLDER) - { - // lets grab the actual projection type - TyTy::PlaceholderType *p - = static_cast<TyTy::PlaceholderType *> (translated); - if (p->can_resolve ()) + if (found_impl_trait) { - translated = p->resolve (); + lookup_associated->setup_associated_types (root, specified_bound); } } + // turbo-fish segment path::<ty> if (item_seg->get_type () == HIR::TypePathSegment::SegmentType::GENERIC) { HIR::TypePathSegmentGeneric &generic_seg @@ -222,6 +212,7 @@ TypeCheckType::visit (HIR::QualifiedPathInType &path) } // continue on as a path-in-expression + const TraitItemReference *trait_item_ref = item.get_raw_item (); NodeId root_resolved_node_id = trait_item_ref->get_mappings ().get_nodeid (); bool fully_resolved = path.get_segments ().empty (); if (fully_resolved) @@ -448,22 +439,6 @@ TypeCheckType::resolve_segments ( { resolved_node_id = candidate.item.trait.item_ref->get_mappings ().get_nodeid (); - - // lookup the associated-impl-trait - HIR::ImplBlock *impl = candidate.item.trait.impl; - if (impl != nullptr && !reciever_is_generic) - { - AssociatedImplTrait *lookup_associated = nullptr; - bool found_impl_trait = context->lookup_associated_trait_impl ( - impl->get_mappings ().get_hirid (), &lookup_associated); - rust_assert (found_impl_trait); - - lookup_associated->setup_associated_types (); - - // we need a new ty_ref_id for this trait item - tyseg = tyseg->clone (); - tyseg->set_ty_ref (mappings->get_next_hir_id ()); - } } if (seg->is_generic_segment ()) diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc index 0673d20..7302b06 100644 --- a/gcc/rust/typecheck/rust-tyty.cc +++ b/gcc/rust/typecheck/rust-tyty.cc @@ -826,22 +826,23 @@ SubstitutionRef::monomorphize () bool found_impl_trait = context->lookup_associated_trait_impl (impl_block_id, &associated); - rust_assert (found_impl_trait); - - bool found_trait - = specified_bound_ref->is_equal (*bound_trait_ref); - bool found_self - = associated->get_self ()->can_eq (binding, false); - if (found_trait && found_self) + if (found_impl_trait) { - associated_impl_trait = associated; - break; + bool found_trait + = specified_bound_ref->is_equal (*bound_trait_ref); + bool found_self + = associated->get_self ()->can_eq (binding, false); + if (found_trait && found_self) + { + associated_impl_trait = associated; + break; + } } } if (associated_impl_trait != nullptr) { - associated_impl_trait->setup_associated_types2 (binding, bound); + associated_impl_trait->setup_associated_types (binding, bound); } } } @@ -2974,6 +2975,7 @@ TypeCheckCallExpr::visit (ADTType &type) void TypeCheckCallExpr::visit (FnType &type) { + type.monomorphize (); if (call.num_params () != type.num_params ()) { if (type.is_varadic ()) |