@@ -1631,6 +1631,58 @@ ConstraintSystem::matchTypes(Type type1, Type type2, TypeMatchKind kind,
1631
1631
conversionsOrFixes.push_back (ConversionRestrictionKind::Superclass);
1632
1632
}
1633
1633
1634
+ // Metatype to object conversion.
1635
+
1636
+ if (getASTContext ().LangOpts .EnableMetatypeToObjectConversions ) {
1637
+ // These conversions are between concrete types that don't need further
1638
+ // resolution, so we can consider them immediately solved.
1639
+ auto addSolvedRestrictedConstraint
1640
+ = [&](ConversionRestrictionKind restriction) -> SolutionKind {
1641
+ auto constraint = Constraint::createRestricted (*this ,
1642
+ ConstraintKind::Subtype,
1643
+ restriction,
1644
+ type1, type2,
1645
+ getConstraintLocator (locator));
1646
+ this ->addConstraint (constraint);
1647
+ return SolutionKind::Solved;
1648
+ };
1649
+
1650
+ if (auto meta1 = type1->getAs <MetatypeType>()) {
1651
+ // Class metatypes can be converted to AnyObject.
1652
+ if (meta1->getInstanceType ()->mayHaveSuperclass ()
1653
+ && type2->isAnyObject ()) {
1654
+ return addSolvedRestrictedConstraint (
1655
+ ConversionRestrictionKind::ClassMetatypeToAnyObject);
1656
+ }
1657
+ // Single @objc protocol value metatypes can be converted to the ObjC
1658
+ // Protocol class type.
1659
+ auto isProtocolClassType = [&](Type t) -> bool {
1660
+ if (auto classDecl = t->getClassOrBoundGenericClass ())
1661
+ if (classDecl->getName () == getASTContext ().Id_Protocol
1662
+ && classDecl->getModuleContext ()->Name
1663
+ == getASTContext ().Id_ObjectiveC )
1664
+ return true ;
1665
+ return false ;
1666
+ };
1667
+
1668
+ if (auto protoTy = meta1->getInstanceType ()->getAs <ProtocolType>()) {
1669
+ if (protoTy->getDecl ()->isObjC ()
1670
+ && isProtocolClassType (type2)) {
1671
+ return addSolvedRestrictedConstraint (
1672
+ ConversionRestrictionKind::ProtocolMetatypeToProtocolClass);
1673
+ }
1674
+ }
1675
+ }
1676
+ if (auto meta1 = type1->getAs <ExistentialMetatypeType>()) {
1677
+ // Class-constrained existential metatypes can be converted to AnyObject.
1678
+ if (meta1->getInstanceType ()->isClassExistentialType ()
1679
+ && type2->isAnyObject ()) {
1680
+ return addSolvedRestrictedConstraint (
1681
+ ConversionRestrictionKind::ExistentialMetatypeToAnyObject);
1682
+ }
1683
+ }
1684
+ }
1685
+
1634
1686
// Implicit array conversions.
1635
1687
if (kind >= TypeMatchKind::Conversion) {
1636
1688
if (isArrayType (desugar1) && isArrayType (desugar2)) {
@@ -3035,6 +3087,14 @@ ConstraintSystem::simplifyRestrictedConstraint(ConversionRestrictionKind restric
3035
3087
matchKind, subFlags, locator);
3036
3088
}
3037
3089
3090
+ case ConversionRestrictionKind::ClassMetatypeToAnyObject:
3091
+ case ConversionRestrictionKind::ExistentialMetatypeToAnyObject:
3092
+ case ConversionRestrictionKind::ProtocolMetatypeToProtocolClass: {
3093
+ // Nothing more to solve.
3094
+ addContextualScore ();
3095
+ return SolutionKind::Solved;
3096
+ }
3097
+
3038
3098
// T < U ===> Array<T> <c Array<U>
3039
3099
case ConversionRestrictionKind::ArrayUpcast: {
3040
3100
auto t1 = type1->getDesugaredType ();
0 commit comments