@@ -242,21 +242,8 @@ bool TypeResolution::areSameType(Type type1, Type type2) const {
242242 }
243243 }
244244
245- // Otherwise, perform a structural check.
246245 assert (stage == TypeResolutionStage::Structural);
247-
248- // FIXME: We should be performing a deeper equality check here.
249- // If both refer to associated types with the same name, they'll implicitly
250- // be considered equivalent.
251- auto depMem1 = type1->getAs <DependentMemberType>();
252- if (!depMem1) return false ;
253-
254- auto depMem2 = type2->getAs <DependentMemberType>();
255- if (!depMem2) return false ;
256-
257- if (depMem1->getName () != depMem2->getName ()) return false ;
258-
259- return areSameType (depMem1->getBase (), depMem2->getBase ());
246+ return false ;
260247}
261248
262249Type TypeChecker::getOptionalType (SourceLoc loc, Type elementType) {
@@ -430,7 +417,7 @@ Type TypeResolution::resolveTypeInContext(TypeDecl *typeDecl,
430417 selfType = foundDC->getSelfInterfaceType ();
431418
432419 if (selfType->is <GenericTypeParamType>()) {
433- if (typeDecl->getDeclContext ()-> getSelfProtocolDecl ( )) {
420+ if (isa<ProtocolDecl>( typeDecl->getDeclContext ())) {
434421 if (isa<AssociatedTypeDecl>(typeDecl) ||
435422 (isa<TypeAliasDecl>(typeDecl) &&
436423 !cast<TypeAliasDecl>(typeDecl)->isGeneric () &&
@@ -1434,6 +1421,23 @@ static Type resolveTopLevelIdentTypeComponent(TypeResolution resolution,
14341421 auto globals = TypeChecker::lookupUnqualifiedType (DC, id, comp->getLoc (),
14351422 lookupOptions);
14361423
1424+ // If we're doing structural resolution and one of the results is an
1425+ // associated type, ignore any other results found from the same
1426+ // DeclContext; they are going to be protocol typealiases, possibly
1427+ // from constrained extensions, and trying to compute their type in
1428+ // resolveTypeInContext() might hit request cycles since structural
1429+ // resolution is performed while computing the requirement signature
1430+ // of the protocol.
1431+ DeclContext *assocTypeDC = nullptr ;
1432+ if (resolution.getStage () == TypeResolutionStage::Structural) {
1433+ for (const auto &entry : globals) {
1434+ if (isa<AssociatedTypeDecl>(entry.getValueDecl ())) {
1435+ assocTypeDC = entry.getDeclContext ();
1436+ break ;
1437+ }
1438+ }
1439+ }
1440+
14371441 // Process the names we found.
14381442 Type current;
14391443 TypeDecl *currentDecl = nullptr ;
@@ -1443,6 +1447,13 @@ static Type resolveTopLevelIdentTypeComponent(TypeResolution resolution,
14431447 auto *foundDC = entry.getDeclContext ();
14441448 auto *typeDecl = cast<TypeDecl>(entry.getValueDecl ());
14451449
1450+ // See the comment above.
1451+ if (assocTypeDC != nullptr &&
1452+ foundDC == assocTypeDC && !isa<AssociatedTypeDecl>(typeDecl))
1453+ continue ;
1454+
1455+ // Compute the type of the found declaration when referenced from this
1456+ // location.
14461457 Type type = resolveTypeDecl (typeDecl, foundDC, resolution, silParams, comp);
14471458 if (type->is <ErrorType>())
14481459 return type;
0 commit comments