@@ -658,6 +658,17 @@ void PropertyMap::addProperty(
658658// /
659659// / - concrete vs superclass
660660// / - concrete vs layout
661+ // /
662+ // / Note that we allow a subclass existential 'any C & P' to satisfy a
663+ // / superclass requirement 'C' as long as 'P' is an @objc protocol.
664+ // /
665+ // / This is not fully sound because 'any C & P' is not substitutable for
666+ // / 'C' if the code calls static method or required initializers on 'C',
667+ // / but existing code out there relies on this working.
668+ // /
669+ // / A more refined check would ensure that 'C' had no required initializers
670+ // / and that 'P' was self-conforming; or we could ban this entirely in a
671+ // / future -swift-version mode.
661672void PropertyMap::checkConcreteTypeRequirements () {
662673 bool debug = Debug.contains (DebugFlags::ConcreteUnification);
663674
@@ -669,6 +680,8 @@ void PropertyMap::checkConcreteTypeRequirements() {
669680 // If the concrete type is not a class and we have a superclass
670681 // requirement, we have a conflict.
671682 if (!concreteType.getConcreteType ()->getClassOrBoundGenericClass () &&
683+ !(concreteType.getConcreteType ()->isObjCExistentialType () &&
684+ concreteType.getConcreteType ()->getSuperclass ()) &&
672685 props->hasSuperclassBound ()) {
673686 const auto &req = props->getSuperclassRequirement ();
674687 for (auto pair : req.SuperclassRules ) {
@@ -677,26 +690,35 @@ void PropertyMap::checkConcreteTypeRequirements() {
677690 }
678691 }
679692
680- if (checkRuleOnce (concreteTypeRule)) {
681- if (concreteType.getConcreteType ()->getClassOrBoundGenericClass ()) {
682- // A rule (T.[concrete: C] => T) where C is a class type induces a rule
683- // (T.[superclass: C] => T).
684- auto superclassSymbol = Symbol::forSuperclass (
685- concreteType.getConcreteType (),
686- concreteType.getSubstitutions (),
687- Context);
688-
689- recordRelation (props->getKey (), concreteTypeRule,
690- superclassSymbol, System, debug);
691- }
693+ // If the concrete type does not satisfy a class layout constraint and
694+ // we have such a layout requirement, we have a conflict.
695+ if (!concreteType.getConcreteType ()->satisfiesClassConstraint () &&
696+ props->LayoutRule &&
697+ props->Layout ->isClass ()) {
698+ if (checkRulePairOnce (concreteTypeRule, *props->LayoutRule ))
699+ System.recordConflict (concreteTypeRule, *props->LayoutRule );
700+ }
692701
693- // A rule (T.[concrete: C] => T) where C is a class type induces a rule
694- // (T.[layout: L] => T), where L is either AnyObject or _NativeObject.
702+ if (checkRuleOnce (concreteTypeRule)) {
695703 if (concreteType.getConcreteType ()->satisfiesClassConstraint ()) {
696704 Type superclassType = concreteType.getConcreteType ();
697705 if (!superclassType->getClassOrBoundGenericClass ())
698706 superclassType = superclassType->getSuperclass ();
699707
708+ if (superclassType) {
709+ // A rule (T.[concrete: C] => T) where C is a class type induces a rule
710+ // (T.[superclass: C] => T).
711+ auto superclassSymbol = Symbol::forSuperclass (
712+ superclassType->getCanonicalType (),
713+ concreteType.getSubstitutions (),
714+ Context);
715+
716+ recordRelation (props->getKey (), concreteTypeRule,
717+ superclassSymbol, System, debug);
718+ }
719+
720+ // A rule (T.[concrete: C] => T) where C is a class type induces a rule
721+ // (T.[layout: L] => T), where L is either AnyObject or _NativeObject.
700722 auto layoutConstraint = LayoutConstraintKind::Class;
701723 if (superclassType)
702724 if (auto *classDecl = superclassType->getClassOrBoundGenericClass ())
@@ -711,15 +733,6 @@ void PropertyMap::checkConcreteTypeRequirements() {
711733 layoutSymbol, System, debug);
712734 }
713735 }
714-
715- // If the concrete type does not satisfy a class layout constraint and
716- // we have such a layout requirement, we have a conflict.
717- if (!concreteType.getConcreteType ()->satisfiesClassConstraint () &&
718- props->LayoutRule &&
719- props->Layout ->isClass ()) {
720- if (checkRulePairOnce (concreteTypeRule, *props->LayoutRule ))
721- System.recordConflict (concreteTypeRule, *props->LayoutRule );
722- }
723736 }
724737 }
725738}
0 commit comments