@@ -4473,21 +4473,27 @@ TypeChecker::conformsToProtocol(Type T, ProtocolDecl *Proto, DeclContext *DC,
4473
4473
bool
4474
4474
TypeChecker::couldDynamicallyConformToProtocol (Type type, ProtocolDecl *Proto,
4475
4475
DeclContext *DC) {
4476
- // We may have types that can dynamically conform to a protocol, e.g. a non-final
4477
- // class which might have a subclass that conforms to the protocol, or standard
4478
- // library collection types such as Array, Set or Dictionary which have custom
4479
- // casting machinery implemented in situations like:
4480
- //
4481
- // func encodable(_ value: Encodable) {
4482
- // _ = value as! [String : Encodable]
4483
- // }
4484
- //
4476
+ // A generic archetype may have protocol conformances we cannot know
4477
+ // statically.
4478
+ if (type->is <ArchetypeType>())
4479
+ return true ;
4480
+
4481
+ // A non-final class might have a subclass that conforms to the protocol.
4485
4482
if (auto *classDecl = type->getClassOrBoundGenericClass ()) {
4486
4483
if (!classDecl->isFinal ())
4487
4484
return true ;
4488
4485
}
4489
4486
4490
4487
ModuleDecl *M = DC->getParentModule ();
4488
+ // For standard library collection types such as Array, Set or Dictionary
4489
+ // which have custom casting machinery implemented in situations like:
4490
+ //
4491
+ // func encodable(_ value: Encodable) {
4492
+ // _ = value as! [String : Encodable]
4493
+ // }
4494
+ // we are skipping checking conditional requirements using lookupConformance,
4495
+ // as an intermediate collection cast can dynamically change if the conditions
4496
+ // are met or not.
4491
4497
if (type->isKnownStdlibCollectionType ())
4492
4498
return !M->lookupConformance (type, Proto).isInvalid ();
4493
4499
return !conformsToProtocol (type, Proto, DC).isInvalid ();
0 commit comments