TyTy::BaseType *get_self () { return self; }
- void setup_associated_types (const TyTy::BaseType *self,
- const TyTy::TypeBoundPredicate &bound);
+ TyTy::BaseType *
+ setup_associated_types (const TyTy::BaseType *self,
+ const TyTy::TypeBoundPredicate &bound);
void reset_associated_types ();
placeholder->clear_associated_type ();
}
-void
+TyTy::BaseType *
AssociatedImplTrait::setup_associated_types (
const TyTy::BaseType *self, const TyTy::TypeBoundPredicate &bound)
{
- if (!bound.contains_associated_types ())
- return;
-
// compute the constrained impl block generic arguments based on self and the
// higher ranked trait bound
TyTy::BaseType *receiver = self->clone ();
TyTy::TyWithLocation (receiver), TyTy::TyWithLocation (impl_self_infer),
impl_predicate.get_locus ());
rust_assert (result->get_kind () != TyTy::TypeKind::ERROR);
+ TyTy::BaseType *self_result = result;
// unify the bounds arguments
std::vector<TyTy::BaseType *> hrtb_bound_arguments;
}
if (impl_trait_predicate_args.size () != hrtb_bound_arguments.size ())
- return;
+ return self_result;
for (size_t i = 0; i < impl_trait_predicate_args.size (); i++)
{
resolved_trait_item->associated_type_set (substituted);
});
iter.go ();
+
+ return self_result;
}
void
if (associated_impl_block != nullptr)
{
- // get the type of the parent Self
- HirId impl_ty_id
- = associated_impl_block->get_type ()->get_mappings ().get_hirid ();
+ // associated types
+ HirId impl_block_id
+ = associated_impl_block->get_mappings ().get_hirid ();
+
+ AssociatedImplTrait *associated = nullptr;
+ bool found_impl_trait
+ = context->lookup_associated_trait_impl (impl_block_id,
+ &associated);
TyTy::BaseType *impl_block_ty = nullptr;
- bool ok = query_type (impl_ty_id, &impl_block_ty);
- rust_assert (ok);
+ if (found_impl_trait)
+ {
+ TyTy::TypeBoundPredicate predicate (*associated->get_trait (),
+ seg.get_locus ());
+ impl_block_ty
+ = associated->setup_associated_types (prev_segment, predicate);
+ }
+ else
+ {
+ // get the type of the parent Self
+ HirId impl_ty_id = associated_impl_block->get_type ()
+ ->get_mappings ()
+ .get_hirid ();
- if (impl_block_ty->needs_generic_substitutions ())
- impl_block_ty
- = SubstMapper::InferSubst (impl_block_ty, seg.get_locus ());
+ bool ok = query_type (impl_ty_id, &impl_block_ty);
+ rust_assert (ok);
+
+ if (impl_block_ty->needs_generic_substitutions ())
+ impl_block_ty
+ = SubstMapper::InferSubst (impl_block_ty, seg.get_locus ());
+ }
prev_segment = unify_site (seg.get_mappings ().get_hirid (),
TyTy::TyWithLocation (prev_segment),
void
TypeCheckCallExpr::visit (FnType &type)
{
- type.monomorphize ();
if (call.num_params () != type.num_params ())
{
if (type.is_varadic ())
--- /dev/null
+trait Foo<T> {
+ type A;
+
+ fn test(a: Self::A) -> Self::A {
+ a
+ }
+}
+
+struct Bar<T>(T);
+impl<T> Foo<T> for Bar<i32> {
+ type A = T;
+}
+
+fn main() {
+ let a;
+ a = Bar(123);
+
+ let b;
+ b = Bar::test(a.0);
+}