@@ -1957,29 +1957,33 @@ TypeChecker::typeCheckCheckedCast(Type fromType, Type toType,
19571957
19581958 // A cast from a function type to an existential type (except `Any`)
19591959 // or an archetype type (with constraints) cannot succeed
1960- auto toArchetypeType = toType->is <ArchetypeType>();
1961- auto fromFunctionType = fromType->is <FunctionType>();
1962- auto toExistentialType = toType->isAnyExistentialType ();
1963-
1964- auto toConstrainedArchetype = false ;
1965- if (toArchetypeType) {
1966- auto archetype = toType->castTo <ArchetypeType>();
1967- toConstrainedArchetype = !archetype->getConformsTo ().empty ();
1968- }
1969-
1970- if (fromFunctionType &&
1971- (toExistentialType || (toArchetypeType && toConstrainedArchetype))) {
1972- switch (contextKind) {
1973- case CheckedCastContextKind::None:
1974- case CheckedCastContextKind::ConditionalCast:
1975- case CheckedCastContextKind::ForcedCast:
1976- return CheckedCastKind::Unresolved;
1960+ if (fromType->is <FunctionType>()) {
1961+ auto toArchetypeType = toType->is <ArchetypeType>();
1962+ auto toExistentialType = toType->isAnyExistentialType ();
1963+
1964+ auto conformsToAllProtocols = true ;
1965+ if (toArchetypeType) {
1966+ auto archetype = toType->castTo <ArchetypeType>();
1967+ conformsToAllProtocols = llvm::all_of (archetype->getConformsTo (),
1968+ [&](ProtocolDecl *proto) {
1969+ return module ->checkConformance (fromType, proto,
1970+ /* allowMissing=*/ false );
1971+ });
1972+ }
19771973
1978- case CheckedCastContextKind::IsPattern:
1979- case CheckedCastContextKind::EnumElementPattern:
1980- case CheckedCastContextKind::IsExpr:
1981- case CheckedCastContextKind::Coercion:
1982- break ;
1974+ if (toExistentialType || (toArchetypeType && !conformsToAllProtocols)) {
1975+ switch (contextKind) {
1976+ case CheckedCastContextKind::None:
1977+ case CheckedCastContextKind::ConditionalCast:
1978+ case CheckedCastContextKind::ForcedCast:
1979+ return CheckedCastKind::Unresolved;
1980+
1981+ case CheckedCastContextKind::IsPattern:
1982+ case CheckedCastContextKind::EnumElementPattern:
1983+ case CheckedCastContextKind::IsExpr:
1984+ case CheckedCastContextKind::Coercion:
1985+ break ;
1986+ }
19831987 }
19841988 }
19851989
0 commit comments