mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Type checker: Don't attempt metatype-to-object conversions if ObjC interop is disabled.
The post-type-checking error that was here is arguably better QoI, but it is causing ambiguities that break the non-ObjC-compatible build in the stdlib. We shouldn't even attempt these conversions if there's no runtime support to back them up. Swift SVN r27407
This commit is contained in:
@@ -1670,52 +1670,56 @@ ConstraintSystem::matchTypes(Type type1, Type type2, TypeMatchKind kind,
|
||||
}
|
||||
|
||||
// Metatype to object conversion.
|
||||
//
|
||||
// Class and protocol metatypes are interoperable with certain Objective-C
|
||||
// runtime classes, but only when ObjC interop is enabled.
|
||||
|
||||
// These conversions are between concrete types that don't need further
|
||||
// resolution, so we can consider them immediately solved.
|
||||
auto addSolvedRestrictedConstraint
|
||||
= [&](ConversionRestrictionKind restriction) -> SolutionKind {
|
||||
auto constraint = Constraint::createRestricted(*this,
|
||||
ConstraintKind::Subtype,
|
||||
restriction,
|
||||
type1, type2,
|
||||
getConstraintLocator(locator));
|
||||
this->addConstraint(constraint);
|
||||
return SolutionKind::Solved;
|
||||
};
|
||||
|
||||
if (auto meta1 = type1->getAs<MetatypeType>()) {
|
||||
// Class metatypes can be converted to AnyObject.
|
||||
if (meta1->getInstanceType()->mayHaveSuperclass()
|
||||
&& type2->isAnyObject()) {
|
||||
return addSolvedRestrictedConstraint(
|
||||
ConversionRestrictionKind::ClassMetatypeToAnyObject);
|
||||
}
|
||||
// Single @objc protocol value metatypes can be converted to the ObjC
|
||||
// Protocol class type.
|
||||
auto isProtocolClassType = [&](Type t) -> bool {
|
||||
if (auto classDecl = t->getClassOrBoundGenericClass())
|
||||
if (classDecl->getName() == getASTContext().Id_Protocol
|
||||
&& classDecl->getModuleContext()->Name
|
||||
== getASTContext().Id_ObjectiveC)
|
||||
return true;
|
||||
return false;
|
||||
};
|
||||
if (TC.getLangOpts().EnableObjCInterop) {
|
||||
// These conversions are between concrete types that don't need further
|
||||
// resolution, so we can consider them immediately solved.
|
||||
auto addSolvedRestrictedConstraint
|
||||
= [&](ConversionRestrictionKind restriction) -> SolutionKind {
|
||||
auto constraint = Constraint::createRestricted(*this,
|
||||
ConstraintKind::Subtype,
|
||||
restriction,
|
||||
type1, type2,
|
||||
getConstraintLocator(locator));
|
||||
this->addConstraint(constraint);
|
||||
return SolutionKind::Solved;
|
||||
};
|
||||
|
||||
if (auto protoTy = meta1->getInstanceType()->getAs<ProtocolType>()) {
|
||||
if (protoTy->getDecl()->isObjC()
|
||||
&& isProtocolClassType(type2)) {
|
||||
if (auto meta1 = type1->getAs<MetatypeType>()) {
|
||||
if (meta1->getInstanceType()->mayHaveSuperclass()
|
||||
&& type2->isAnyObject()) {
|
||||
return addSolvedRestrictedConstraint(
|
||||
ConversionRestrictionKind::ProtocolMetatypeToProtocolClass);
|
||||
ConversionRestrictionKind::ClassMetatypeToAnyObject);
|
||||
}
|
||||
// Single @objc protocol value metatypes can be converted to the ObjC
|
||||
// Protocol class type.
|
||||
auto isProtocolClassType = [&](Type t) -> bool {
|
||||
if (auto classDecl = t->getClassOrBoundGenericClass())
|
||||
if (classDecl->getName() == getASTContext().Id_Protocol
|
||||
&& classDecl->getModuleContext()->Name
|
||||
== getASTContext().Id_ObjectiveC)
|
||||
return true;
|
||||
return false;
|
||||
};
|
||||
|
||||
if (auto protoTy = meta1->getInstanceType()->getAs<ProtocolType>()) {
|
||||
if (protoTy->getDecl()->isObjC()
|
||||
&& isProtocolClassType(type2)) {
|
||||
return addSolvedRestrictedConstraint(
|
||||
ConversionRestrictionKind::ProtocolMetatypeToProtocolClass);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (auto meta1 = type1->getAs<ExistentialMetatypeType>()) {
|
||||
// Class-constrained existential metatypes can be converted to AnyObject.
|
||||
if (meta1->getInstanceType()->isClassExistentialType()
|
||||
&& type2->isAnyObject()) {
|
||||
return addSolvedRestrictedConstraint(
|
||||
ConversionRestrictionKind::ExistentialMetatypeToAnyObject);
|
||||
if (auto meta1 = type1->getAs<ExistentialMetatypeType>()) {
|
||||
// Class-constrained existential metatypes can be converted to AnyObject.
|
||||
if (meta1->getInstanceType()->isClassExistentialType()
|
||||
&& type2->isAnyObject()) {
|
||||
return addSolvedRestrictedConstraint(
|
||||
ConversionRestrictionKind::ExistentialMetatypeToAnyObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user