@@ -3862,58 +3862,86 @@ ResolveWitnessResult ConformanceChecker::resolveTypeWitnessViaLookup(
3862
3862
abort ();
3863
3863
}
3864
3864
3865
+ NLOptions subOptions = (NL_QualifiedDefault | NL_OnlyTypes | NL_ProtocolMembers);
3866
+
3865
3867
// Look for a member type with the same name as the associated type.
3866
- auto candidates = TypeChecker::lookupMemberType (
3867
- DC, Adoptee, assocType->createNameRef (),
3868
- NameLookupFlags::ProtocolMembers);
3868
+ SmallVector<ValueDecl *, 4 > candidates;
3869
+
3870
+ DC->lookupQualified (Adoptee->getAnyNominal (),
3871
+ assocType->createNameRef (),
3872
+ subOptions, candidates);
3869
3873
3870
3874
// If there aren't any candidates, we're done.
3871
- if (! candidates) {
3875
+ if (candidates. empty () ) {
3872
3876
return ResolveWitnessResult::Missing;
3873
3877
}
3874
3878
3875
3879
// Determine which of the candidates is viable.
3876
3880
SmallVector<LookupTypeResultEntry, 2 > viable;
3877
3881
SmallVector<std::pair<TypeDecl *, CheckTypeWitnessResult>, 2 > nonViable;
3882
+ SmallPtrSet<CanType, 4 > viableTypes;
3883
+
3878
3884
for (auto candidate : candidates) {
3879
- // Skip nested generic types.
3880
- if (auto *genericDecl = dyn_cast<GenericTypeDecl>(candidate.Member )) {
3881
- // If the declaration has generic parameters, it cannot witness an
3882
- // associated type.
3883
- if (genericDecl->isGeneric ())
3884
- continue ;
3885
+ auto *typeDecl = cast<TypeDecl>(candidate);
3885
3886
3886
- // As a narrow fix for a source compatibility issue with SwiftUI's
3887
- // swiftinterface, allow the conformance if the underlying type of
3888
- // the typealias is Never.
3889
- //
3890
- // FIXME: This should be conditionalized on a new language version.
3891
- bool skipRequirementCheck = false ;
3892
- if (auto *typeAliasDecl = dyn_cast<TypeAliasDecl>(candidate.Member )) {
3893
- if (typeAliasDecl->getUnderlyingType ()->isUninhabited ())
3894
- skipRequirementCheck = true ;
3895
- }
3887
+ // Skip other associated types.
3888
+ if (isa<AssociatedTypeDecl>(typeDecl))
3889
+ continue ;
3896
3890
3897
- // If the type comes from a constrained extension or has a 'where'
3898
- // clause, check those requirements now.
3899
- if (!skipRequirementCheck &&
3900
- !TypeChecker::checkContextualRequirements (genericDecl, Adoptee,
3901
- SourceLoc (), DC)) {
3902
- continue ;
3903
- }
3891
+ auto *genericDecl = cast<GenericTypeDecl>(typeDecl);
3892
+
3893
+ // If the declaration has generic parameters, it cannot witness an
3894
+ // associated type.
3895
+ if (genericDecl->isGeneric ())
3896
+ continue ;
3897
+
3898
+ // As a narrow fix for a source compatibility issue with SwiftUI's
3899
+ // swiftinterface, allow the conformance if the underlying type of
3900
+ // the typealias is Never.
3901
+ //
3902
+ // FIXME: This should be conditionalized on a new language version.
3903
+ bool skipRequirementCheck = false ;
3904
+ if (auto *typeAliasDecl = dyn_cast<TypeAliasDecl>(typeDecl)) {
3905
+ if (typeAliasDecl->getUnderlyingType ()->isUninhabited ())
3906
+ skipRequirementCheck = true ;
3904
3907
}
3905
3908
3906
3909
// Skip typealiases with an unbound generic type as their underlying type.
3907
- if (auto *typeAliasDecl = dyn_cast<TypeAliasDecl>(candidate. Member ))
3910
+ if (auto *typeAliasDecl = dyn_cast<TypeAliasDecl>(typeDecl ))
3908
3911
if (typeAliasDecl->getDeclaredInterfaceType ()->is <UnboundGenericType>())
3909
3912
continue ;
3910
3913
3914
+ // Skip dependent protocol typealiases.
3915
+ //
3916
+ // FIXME: This should not be necessary.
3917
+ if (auto *typeAliasDecl = dyn_cast<TypeAliasDecl>(typeDecl)) {
3918
+ if (isa<ProtocolDecl>(typeAliasDecl->getDeclContext ()) &&
3919
+ typeAliasDecl->getUnderlyingType ()->getCanonicalType ()
3920
+ ->hasTypeParameter ()) {
3921
+ continue ;
3922
+ }
3923
+ }
3924
+
3925
+ // If the type comes from a constrained extension or has a 'where'
3926
+ // clause, check those requirements now.
3927
+ if (!skipRequirementCheck &&
3928
+ !TypeChecker::checkContextualRequirements (genericDecl, Adoptee,
3929
+ SourceLoc (), DC)) {
3930
+ continue ;
3931
+ }
3932
+
3933
+ auto memberType = TypeChecker::substMemberTypeWithBase (DC->getParentModule (),
3934
+ typeDecl, Adoptee);
3935
+
3936
+ if (!viableTypes.insert (memberType->getCanonicalType ()).second )
3937
+ continue ;
3938
+
3911
3939
// Check this type against the protocol requirements.
3912
3940
if (auto checkResult =
3913
- checkTypeWitness (candidate. MemberType , assocType, Conformance)) {
3914
- nonViable.push_back ({candidate. Member , checkResult});
3941
+ checkTypeWitness (memberType , assocType, Conformance)) {
3942
+ nonViable.push_back ({typeDecl , checkResult});
3915
3943
} else {
3916
- viable.push_back (candidate );
3944
+ viable.push_back ({typeDecl, memberType, nullptr } );
3917
3945
}
3918
3946
}
3919
3947
0 commit comments