@@ -219,7 +219,8 @@ void ArchetypeBuilder::PotentialArchetype::buildFullName(
219219Identifier ArchetypeBuilder::PotentialArchetype::getName () const {
220220 if (auto assocType = NameOrAssociatedType.dyn_cast <AssociatedTypeDecl *>())
221221 return assocType->getName ();
222-
222+ if (auto typeAlias = NameOrAssociatedType.dyn_cast <TypeAliasDecl *>())
223+ return typeAlias->getName ();
223224 return NameOrAssociatedType.get <Identifier>();
224225}
225226
@@ -303,12 +304,12 @@ static void maybeAddSameTypeRequirementForNestedType(
303304 RequirementSource fromSource,
304305 ProtocolConformance *superConformance,
305306 ArchetypeBuilder &builder) {
306- auto assocType = nestedPA->getResolvedAssociatedType ();
307- assert (assocType && " Not resolved to an associated type?" );
308-
309307 // If there's no super conformance, we're done.
310308 if (!superConformance) return ;
311309
310+ auto assocType = nestedPA->getResolvedAssociatedType ();
311+ assert (assocType && " Not resolved to an associated type?" );
312+
312313 // Dig out the type witness.
313314 auto concreteType =
314315 superConformance->getTypeWitness (assocType, builder.getLazyResolver ())
@@ -467,20 +468,73 @@ auto ArchetypeBuilder::PotentialArchetype::getNestedType(
467468 // archetype conforms.
468469 for (auto &conforms : ConformsTo) {
469470 for (auto member : conforms.first ->lookupDirect (nestedName)) {
470- auto assocType = dyn_cast<AssociatedTypeDecl>(member);
471- if (!assocType)
471+ PotentialArchetype *pa;
472+
473+ if (auto assocType = dyn_cast<AssociatedTypeDecl>(member)) {
474+ // Resolve this nested type to this associated type.
475+ pa = new PotentialArchetype (this , assocType);
476+ } else if (auto alias = dyn_cast<TypeAliasDecl>(member)) {
477+ // Resolve this nested type to this type alias.
478+ pa = new PotentialArchetype (this , alias);
479+
480+ if (!alias->hasUnderlyingType ())
481+ builder.getLazyResolver ()->resolveDeclSignature (alias);
482+ if (!alias->hasUnderlyingType ())
483+ continue ;
484+
485+ auto type = alias->getUnderlyingType ();
486+ if (auto archetype = type->getAs <ArchetypeType>()) {
487+ auto containingProtocol = cast<ProtocolDecl>(alias->getParent ());
488+ SmallVector<Identifier, 4 > identifiers;
489+
490+ // Go up archetype parents until we find our containing protocol.
491+ while (archetype->getSelfProtocol () != containingProtocol) {
492+ identifiers.push_back (archetype->getName ());
493+ archetype = archetype->getParent ();
494+ if (!archetype)
495+ break ;
496+ }
497+ if (!archetype)
498+ continue ;
499+
500+ // Go down our PAs until we find the referenced PA.
501+ auto existingPA = this ;
502+ while (identifiers.size ()) {
503+ existingPA = existingPA->getNestedType (identifiers.back (), builder);
504+ identifiers.pop_back ();
505+ }
506+ pa->Representative = existingPA;
507+ RequirementSource source (RequirementSource::Inferred, SourceLoc ());
508+ pa->SameTypeSource = source;
509+ } else if (type->hasArchetype ()) {
510+ // This is a complex type involving other associatedtypes, we'll fail
511+ // to resolve and get a special diagnosis in finalize.
512+ continue ;
513+ } else {
514+ pa->ArchetypeOrConcreteType = NestedType::forConcreteType (type);
515+ }
516+ } else
472517 continue ;
473518
474- // Resolve this nested type to this associated type.
475- auto pa = new PotentialArchetype (this , assocType);
476-
477519 // If we have resolved this nested type to more than one associated
478520 // type, create same-type constraints between them.
479521 RequirementSource source (RequirementSource::Inferred, SourceLoc ());
480522 if (!nested.empty ()) {
481- pa->Representative = nested.front ()->getRepresentative ();
482- pa->Representative ->EquivalenceClass .push_back (pa);
483- pa->SameTypeSource = source;
523+ auto existing = nested.front ();
524+ if (auto alias = existing->getTypeAliasDecl ()) {
525+ // If we found a typealias first, and now have an associatedtype
526+ // with the same name, it was a Swift 2 style declaration of the
527+ // type an inherited associatedtype should be bound to. In such a
528+ // case we want to make sure the associatedtype is frontmost to
529+ // generate generics/witness lists correctly, and the alias
530+ // will be unused/useless for generic constraining anyway.
531+ alias->setInvalid ();
532+ nested.clear ();
533+ } else {
534+ pa->Representative = existing->getRepresentative ();
535+ pa->Representative ->EquivalenceClass .push_back (pa);
536+ pa->SameTypeSource = source;
537+ }
484538 }
485539
486540 // Add this resolved nested type.
@@ -677,6 +731,9 @@ ArchetypeBuilder::PotentialArchetype::getType(ArchetypeBuilder &builder) {
677731 builder.getASTContext ().registerLazyArchetype (arch, builder, this );
678732 SmallVector<std::pair<Identifier, NestedType>, 4 > FlatNestedTypes;
679733 for (auto Nested : NestedTypes) {
734+ // Skip type aliases, which are just shortcuts.
735+ if (Nested.second .front ()->getTypeAliasDecl ())
736+ continue ;
680737 bool anyNotRenamed = false ;
681738 for (auto NestedPA : Nested.second ) {
682739 if (!NestedPA->wasRenamed ()) {
@@ -1646,6 +1703,23 @@ bool ArchetypeBuilder::finalize(SourceLoc loc) {
16461703 /* FIXME: Should be able to handle this earlier */ pa->getSuperclass ())
16471704 return ;
16481705
1706+ // If a typealias with this name exists in one of the parent protocols,
1707+ // give a special diagnosis.
1708+ auto parentConformances = pa->getParent ()->getConformsTo ();
1709+ for (auto &conforms : parentConformances) {
1710+ for (auto member : conforms.first ->getMembers ()) {
1711+ auto typealias = dyn_cast<TypeAliasDecl>(member);
1712+ if (!typealias || typealias->getName () != pa->getName ())
1713+ continue ;
1714+
1715+ Context.Diags .diagnose (loc, diag::invalid_member_type_alias,
1716+ pa->getName ());
1717+ invalid = true ;
1718+ pa->setInvalid ();
1719+ return ;
1720+ }
1721+ }
1722+
16491723 // Try to typo correct to a nested type name.
16501724 Identifier correction = typoCorrectNestedType (pa);
16511725 if (correction.empty ()) {
@@ -1702,7 +1776,7 @@ ArrayRef<ArchetypeType *> ArchetypeBuilder::getAllArchetypes() {
17021776 continue ;
17031777
17041778 PotentialArchetype *PA = Entry.second ;
1705- if (!PA->isConcreteType ()) {
1779+ if (!PA->isConcreteType () && !PA-> getTypeAliasDecl () ) {
17061780 auto Archetype = PA->getType (*this ).castToArchetype ();
17071781 GenericParamList::addNestedArchetypes (Archetype, KnownArchetypes,
17081782 Impl->AllArchetypes );
@@ -2105,6 +2179,9 @@ addNestedRequirements(
21052179 for (const auto &nested : pa->getNestedTypes ()) {
21062180 // FIXME: Dropping requirements among different associated types of the
21072181 // same name.
2182+ // Skip type aliases, which are just shortcuts down the tree.
2183+ if (nested.second .front ()->getTypeAliasDecl ())
2184+ continue ;
21082185 nestedTypes.push_back (std::make_pair (nested.first , nested.second .front ()));
21092186 }
21102187 std::sort (nestedTypes.begin (), nestedTypes.end (),
0 commit comments