aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPhilip Herron <philip.herron@embecosm.com>2022-04-28 13:09:15 +0100
committerPhilip Herron <philip.herron@embecosm.com>2022-04-28 13:09:15 +0100
commitbe158fc97f7f4d43d60797f2af27c86753b0ffb5 (patch)
tree3d0f3aaef56b6190bf19ef2722add0047afce145 /gcc
parent712ae2f173df0c2d9018bf5ce708ffbbaee10d64 (diff)
downloadgcc-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.cc1
-rw-r--r--gcc/rust/backend/rust-compile-item.cc1
-rw-r--r--gcc/rust/backend/rust-compile-resolve-path.cc15
-rw-r--r--gcc/rust/typecheck/rust-hir-path-probe.h12
-rw-r--r--gcc/rust/typecheck/rust-hir-trait-ref.h11
-rw-r--r--gcc/rust/typecheck/rust-hir-trait-resolve.cc64
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-path.cc71
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-type.cc67
-rw-r--r--gcc/rust/typecheck/rust-tyty.cc22
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 &param_mapping : fn->get_substs ())
- {
- const HIR::TypeParam &type_param = param_mapping.get_generic_param ();
- if (type_param.get_type_representation ().compare ("Self") == 0)
- {
- param = &param_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 ())