@@ -219,7 +219,8 @@ void ArchetypeBuilder::PotentialArchetype::buildFullName(
219
219
Identifier ArchetypeBuilder::PotentialArchetype::getName () const {
220
220
if (auto assocType = NameOrAssociatedType.dyn_cast <AssociatedTypeDecl *>())
221
221
return assocType->getName ();
222
-
222
+ if (auto typeAlias = NameOrAssociatedType.dyn_cast <TypeAliasDecl *>())
223
+ return typeAlias->getName ();
223
224
return NameOrAssociatedType.get <Identifier>();
224
225
}
225
226
@@ -303,12 +304,12 @@ static void maybeAddSameTypeRequirementForNestedType(
303
304
RequirementSource fromSource,
304
305
ProtocolConformance *superConformance,
305
306
ArchetypeBuilder &builder) {
306
- auto assocType = nestedPA->getResolvedAssociatedType ();
307
- assert (assocType && " Not resolved to an associated type?" );
308
-
309
307
// If there's no super conformance, we're done.
310
308
if (!superConformance) return ;
311
309
310
+ auto assocType = nestedPA->getResolvedAssociatedType ();
311
+ assert (assocType && " Not resolved to an associated type?" );
312
+
312
313
// Dig out the type witness.
313
314
auto concreteType =
314
315
superConformance->getTypeWitness (assocType, builder.getLazyResolver ())
@@ -467,20 +468,73 @@ auto ArchetypeBuilder::PotentialArchetype::getNestedType(
467
468
// archetype conforms.
468
469
for (auto &conforms : ConformsTo) {
469
470
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
472
517
continue ;
473
518
474
- // Resolve this nested type to this associated type.
475
- auto pa = new PotentialArchetype (this , assocType);
476
-
477
519
// If we have resolved this nested type to more than one associated
478
520
// type, create same-type constraints between them.
479
521
RequirementSource source (RequirementSource::Inferred, SourceLoc ());
480
522
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
+ }
484
538
}
485
539
486
540
// Add this resolved nested type.
@@ -677,6 +731,9 @@ ArchetypeBuilder::PotentialArchetype::getType(ArchetypeBuilder &builder) {
677
731
builder.getASTContext ().registerLazyArchetype (arch, builder, this );
678
732
SmallVector<std::pair<Identifier, NestedType>, 4 > FlatNestedTypes;
679
733
for (auto Nested : NestedTypes) {
734
+ // Skip type aliases, which are just shortcuts.
735
+ if (Nested.second .front ()->getTypeAliasDecl ())
736
+ continue ;
680
737
bool anyNotRenamed = false ;
681
738
for (auto NestedPA : Nested.second ) {
682
739
if (!NestedPA->wasRenamed ()) {
@@ -1646,6 +1703,23 @@ bool ArchetypeBuilder::finalize(SourceLoc loc) {
1646
1703
/* FIXME: Should be able to handle this earlier */ pa->getSuperclass ())
1647
1704
return ;
1648
1705
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
+
1649
1723
// Try to typo correct to a nested type name.
1650
1724
Identifier correction = typoCorrectNestedType (pa);
1651
1725
if (correction.empty ()) {
@@ -1702,7 +1776,7 @@ ArrayRef<ArchetypeType *> ArchetypeBuilder::getAllArchetypes() {
1702
1776
continue ;
1703
1777
1704
1778
PotentialArchetype *PA = Entry.second ;
1705
- if (!PA->isConcreteType ()) {
1779
+ if (!PA->isConcreteType () && !PA-> getTypeAliasDecl () ) {
1706
1780
auto Archetype = PA->getType (*this ).castToArchetype ();
1707
1781
GenericParamList::addNestedArchetypes (Archetype, KnownArchetypes,
1708
1782
Impl->AllArchetypes );
@@ -2105,6 +2179,9 @@ addNestedRequirements(
2105
2179
for (const auto &nested : pa->getNestedTypes ()) {
2106
2180
// FIXME: Dropping requirements among different associated types of the
2107
2181
// same name.
2182
+ // Skip type aliases, which are just shortcuts down the tree.
2183
+ if (nested.second .front ()->getTypeAliasDecl ())
2184
+ continue ;
2108
2185
nestedTypes.push_back (std::make_pair (nested.first , nested.second .front ()));
2109
2186
}
2110
2187
std::sort (nestedTypes.begin (), nestedTypes.end (),
0 commit comments