Skip to content

Commit 831f086

Browse files
committed
Override checking: use an enum instead of a boolean flag.
No functionality change, but the next commit will add another case to the enum.
1 parent 152eeaa commit 831f086

File tree

3 files changed

+29
-13
lines changed

3 files changed

+29
-13
lines changed

include/swift/AST/Types.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,16 @@ enum class TypeTraitResult {
221221
Is,
222222
};
223223

224+
/// Specifies which normally-unsafe type mismatches should be accepted when
225+
/// checking overrides.
226+
enum class OverrideMatchMode {
227+
/// Only accept overrides that are properly covariant.
228+
Strict,
229+
/// Allow a parameter with IUO type to be overridden by a parameter with non-
230+
/// optional type.
231+
AllowNonOptionalForIUOParam,
232+
};
233+
224234
/// TypeBase - Base class for all types in Swift.
225235
class alignas(1 << TypeAlignInBits) TypeBase {
226236

@@ -653,7 +663,7 @@ class alignas(1 << TypeAlignInBits) TypeBase {
653663

654664
/// \brief Determines whether this type is permitted as a method override
655665
/// of the \p other.
656-
bool canOverride(Type other, bool allowUnsafeParameterOverride,
666+
bool canOverride(Type other, OverrideMatchMode matchMode,
657667
LazyResolver *resolver);
658668

659669
/// \brief Determines whether this type has a retainable pointer

lib/AST/Type.cpp

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2232,7 +2232,7 @@ bool TypeBase::isTriviallyRepresentableIn(ForeignLanguage language,
22322232
/// Is t1 not just a subtype of t2, but one such that its values are
22332233
/// trivially convertible to values of the other?
22342234
static bool canOverride(CanType t1, CanType t2,
2235-
bool allowUnsafeParameterOverride,
2235+
OverrideMatchMode matchMode,
22362236
bool isParameter,
22372237
bool insideOptional,
22382238
LazyResolver *resolver) {
@@ -2246,7 +2246,7 @@ static bool canOverride(CanType t1, CanType t2,
22462246
if (!tuple1 || tuple1->getNumElements() != tuple2->getNumElements()) {
22472247
if (tuple2->getNumElements() == 1)
22482248
return canOverride(t1, tuple2.getElementType(0),
2249-
allowUnsafeParameterOverride,
2249+
matchMode,
22502250
isParameter,
22512251
/*insideOptional=*/false,
22522252
resolver);
@@ -2256,7 +2256,7 @@ static bool canOverride(CanType t1, CanType t2,
22562256
for (auto i : indices(tuple1.getElementTypes())) {
22572257
if (!canOverride(tuple1.getElementType(i),
22582258
tuple2.getElementType(i),
2259-
allowUnsafeParameterOverride,
2259+
matchMode,
22602260
isParameter,
22612261
/*insideOptional=*/false,
22622262
resolver))
@@ -2283,12 +2283,12 @@ static bool canOverride(CanType t1, CanType t2,
22832283

22842284
// Inputs are contravariant, results are covariant.
22852285
return (canOverride(fn2.getInput(), fn1.getInput(),
2286-
allowUnsafeParameterOverride,
2286+
matchMode,
22872287
/*isParameter=*/true,
22882288
/*insideOptional=*/false,
22892289
resolver) &&
22902290
canOverride(fn1.getResult(), fn2.getResult(),
2291-
allowUnsafeParameterOverride,
2291+
matchMode,
22922292
/*isParameter=*/false,
22932293
/*insideOptional=*/false,
22942294
resolver));
@@ -2301,22 +2301,23 @@ static bool canOverride(CanType t1, CanType t2,
23012301
// Optional-to-optional.
23022302
if (auto obj1 = t1.getAnyOptionalObjectType()) {
23032303
// Allow T? and T! to freely override one another.
2304-
return canOverride(obj1, obj2, allowUnsafeParameterOverride,
2304+
return canOverride(obj1, obj2, matchMode,
23052305
/*isParameter=*/false,
23062306
/*insideOptional=*/true,
23072307
resolver);
23082308
}
23092309

23102310
// Value-to-optional.
2311-
return canOverride(t1, obj2, allowUnsafeParameterOverride,
2311+
return canOverride(t1, obj2, matchMode,
23122312
/*isParameter=*/false,
23132313
/*insideOptional=*/true,
23142314
resolver);
23152315
}
23162316
}
23172317

23182318
// Allow T to override T! in certain cases.
2319-
if (allowUnsafeParameterOverride && isParameter && !insideOptional) {
2319+
if (matchMode == OverrideMatchMode::AllowNonOptionalForIUOParam &&
2320+
isParameter && !insideOptional) {
23202321
if (auto obj1 = t1->getImplicitlyUnwrappedOptionalObjectType()) {
23212322
t1 = obj1->getCanonicalType();
23222323
if (t1 == t2) return true;
@@ -2327,10 +2328,10 @@ static bool canOverride(CanType t1, CanType t2,
23272328
return t2->isExactSuperclassOf(t1, resolver);
23282329
}
23292330

2330-
bool TypeBase::canOverride(Type other, bool allowUnsafeParameterOverride,
2331+
bool TypeBase::canOverride(Type other, OverrideMatchMode matchMode,
23312332
LazyResolver *resolver) {
23322333
return ::canOverride(getCanonicalType(), other->getCanonicalType(),
2333-
allowUnsafeParameterOverride,
2334+
matchMode,
23342335
/*isParameter=*/false,
23352336
/*insideOptional=*/false,
23362337
resolver);

lib/Sema/TypeCheckDecl.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4847,7 +4847,10 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
48474847
}
48484848

48494849
// Failing that, check for subtyping.
4850-
if (declTy->canOverride(parentDeclTy, parentDecl->isObjC(), &TC)) {
4850+
auto matchMode = OverrideMatchMode::Strict;
4851+
if (parentDecl->isObjC())
4852+
matchMode = OverrideMatchMode::AllowNonOptionalForIUOParam;
4853+
if (declTy->canOverride(parentDeclTy, matchMode, &TC)) {
48514854
// If the Objective-C selectors match, always call it exact.
48524855
matches.push_back(
48534856
std::make_tuple(parentDecl, objCMatch, parentDeclTy));
@@ -4996,7 +4999,9 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
49964999
auto parentPropertyTy = adjustSuperclassMemberDeclType(TC, matchDecl,
49975000
superclass);
49985001

4999-
if (!propertyTy->canOverride(parentPropertyTy, false, &TC)) {
5002+
if (!propertyTy->canOverride(parentPropertyTy,
5003+
OverrideMatchMode::Strict,
5004+
&TC)) {
50005005
TC.diagnose(property, diag::override_property_type_mismatch,
50015006
property->getName(), propertyTy, parentPropertyTy);
50025007
TC.diagnose(matchDecl, diag::property_override_here);

0 commit comments

Comments
 (0)