Skip to content

Commit b2083db

Browse files
committed
[ConstraintSystem] Add a fix to allow conversion between non-class type and AnyObject
1 parent 1fff12f commit b2083db

File tree

3 files changed

+68
-4
lines changed

3 files changed

+68
-4
lines changed

lib/Sema/CSFix.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1180,3 +1180,40 @@ SpecifyObjectLiteralTypeImport::create(ConstraintSystem &cs,
11801180
ConstraintLocator *locator) {
11811181
return new (cs.getAllocator()) SpecifyObjectLiteralTypeImport(cs, locator);
11821182
}
1183+
1184+
AllowNonClassTypeToConvertToAnyObject::AllowNonClassTypeToConvertToAnyObject(
1185+
ConstraintSystem &cs, Type type, ConstraintLocator *locator)
1186+
: ContextualMismatch(cs, FixKind::AllowNonClassTypeToConvertToAnyObject,
1187+
type, cs.getASTContext().getAnyObjectType(), locator) {
1188+
}
1189+
1190+
bool AllowNonClassTypeToConvertToAnyObject::diagnose(bool asNote) const {
1191+
auto &cs = getConstraintSystem();
1192+
1193+
auto *locator = getLocator();
1194+
if (locator->getPath().empty())
1195+
return false;
1196+
1197+
const auto &last = locator->getPath().back();
1198+
switch (last.getKind()) {
1199+
case ConstraintLocator::ContextualType: {
1200+
ContextualFailure failure(cs, getFromType(), getToType(), locator);
1201+
return failure.diagnose(asNote);
1202+
}
1203+
1204+
case ConstraintLocator::ApplyArgToParam: {
1205+
ArgumentMismatchFailure failure(cs, getFromType(), getToType(), locator);
1206+
return failure.diagnose(asNote);
1207+
}
1208+
1209+
default:
1210+
return false;
1211+
}
1212+
}
1213+
1214+
AllowNonClassTypeToConvertToAnyObject *
1215+
AllowNonClassTypeToConvertToAnyObject::create(ConstraintSystem &cs, Type type,
1216+
ConstraintLocator *locator) {
1217+
return new (cs.getAllocator())
1218+
AllowNonClassTypeToConvertToAnyObject(cs, type, locator);
1219+
}

lib/Sema/CSFix.h

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -235,12 +235,15 @@ enum class FixKind : uint8_t {
235235
/// Closure return type has to be explicitly specified because it can't be
236236
/// inferred in current context e.g. because it's a multi-statement closure.
237237
SpecifyClosureReturnType,
238-
239-
/// Object literal type coudn't be infered because the module where
238+
239+
/// Object literal type coudn't be inferred because the module where
240240
/// the default type that implements the associated literal protocol
241241
/// is declared was not imported.
242242
SpecifyObjectLiteralTypeImport,
243243

244+
/// Allow any type (and not just class or class-constrained type) to
245+
/// be convertible to AnyObject.
246+
AllowNonClassTypeToConvertToAnyObject,
244247
};
245248

246249
class ConstraintFix {
@@ -1655,6 +1658,21 @@ class SpecifyObjectLiteralTypeImport final : public ConstraintFix {
16551658

16561659
};
16571660

1661+
class AllowNonClassTypeToConvertToAnyObject final : public ContextualMismatch {
1662+
AllowNonClassTypeToConvertToAnyObject(ConstraintSystem &cs, Type type,
1663+
ConstraintLocator *locator);
1664+
1665+
public:
1666+
std::string getName() const {
1667+
return "allow non-class type to convert to 'AnyObject'";
1668+
}
1669+
1670+
bool diagnose(bool asNote = false) const;
1671+
1672+
static AllowNonClassTypeToConvertToAnyObject *
1673+
create(ConstraintSystem &cs, Type type, ConstraintLocator *locator);
1674+
};
1675+
16581676
} // end namespace constraints
16591677
} // end namespace swift
16601678

lib/Sema/CSSimplify.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2095,9 +2095,17 @@ ConstraintSystem::matchExistentialTypes(Type type1, Type type2,
20952095
// Subtype relation to AnyObject also allows class-bound
20962096
// existentials that are not @objc and therefore carry
20972097
// witness tables.
2098-
if (!type1->isClassExistentialType() &&
2099-
!type1->mayHaveSuperclass())
2098+
if (!type1->isClassExistentialType() && !type1->mayHaveSuperclass()) {
2099+
if (shouldAttemptFixes()) {
2100+
auto *fix = AllowNonClassTypeToConvertToAnyObject::create(
2101+
*this, type1, getConstraintLocator(locator));
2102+
2103+
return recordFix(fix) ? getTypeMatchFailure(locator)
2104+
: getTypeMatchSuccess();
2105+
}
2106+
21002107
return getTypeMatchFailure(locator);
2108+
}
21012109
}
21022110

21032111
// Keep going.
@@ -8837,6 +8845,7 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyFixConstraint(
88378845
case FixKind::AllowMutatingMemberOnRValueBase:
88388846
case FixKind::AllowTupleSplatForSingleParameter:
88398847
case FixKind::AllowInvalidUseOfTrailingClosure:
8848+
case FixKind::AllowNonClassTypeToConvertToAnyObject:
88408849
case FixKind::SpecifyClosureReturnType:
88418850
llvm_unreachable("handled elsewhere");
88428851
}

0 commit comments

Comments
 (0)