Skip to content

Commit 41a7667

Browse files
authored
Merge pull request #19908 from slavapestov/consolidate-superclass-check
Sema: Remove TypeChecker::isSuperclassOf()
2 parents 63cc5f9 + c9ae303 commit 41a7667

File tree

6 files changed

+22
-34
lines changed

6 files changed

+22
-34
lines changed

lib/AST/Type.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1423,16 +1423,20 @@ Type TypeBase::getSuperclass(bool useArchetypes) {
14231423
}
14241424

14251425
bool TypeBase::isExactSuperclassOf(Type ty) {
1426-
// For there to be a superclass relationship, we must be a superclass, and
1427-
// the potential subtype must be a class or superclass-bounded archetype.
1428-
if (!getClassOrBoundGenericClass() || !ty->mayHaveSuperclass())
1426+
// For there to be a superclass relationship, we must be a class, and
1427+
// the potential subtype must be a class, superclass-bounded archetype,
1428+
// or subclass existential involving an imported class and @objc
1429+
// protocol.
1430+
if (!getClassOrBoundGenericClass() ||
1431+
!(ty->mayHaveSuperclass() ||
1432+
(ty->isObjCExistentialType() &&
1433+
ty->getSuperclass() &&
1434+
ty->getSuperclass()->getAnyNominal()->hasClangNode())))
14291435
return false;
14301436

14311437
do {
14321438
if (ty->isEqual(this))
14331439
return true;
1434-
if (ty->getAnyNominal() && ty->getAnyNominal()->isInvalid())
1435-
return false;
14361440
} while ((ty = ty->getSuperclass()));
14371441
return false;
14381442
}

lib/Sema/TypeCheckConstraints.cpp

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2929,21 +2929,6 @@ bool TypeChecker::isSubtypeOf(Type type1, Type type2, DeclContext *dc) {
29292929
ConstraintKind::Subtype, dc);
29302930
}
29312931

2932-
bool TypeChecker::isSubclassOf(Type type1, Type type2, DeclContext *dc) {
2933-
assert(type2->getClassOrBoundGenericClass());
2934-
2935-
if (!typesSatisfyConstraint(type1,
2936-
Context.getAnyObjectType(),
2937-
/*openArchetypes=*/false,
2938-
ConstraintKind::ConformsTo, dc)) {
2939-
return false;
2940-
}
2941-
2942-
return typesSatisfyConstraint(type1, type2,
2943-
/*openArchetypes=*/false,
2944-
ConstraintKind::Subtype, dc);
2945-
}
2946-
29472932
bool TypeChecker::isConvertibleTo(Type type1, Type type2, DeclContext *dc,
29482933
bool *unwrappedIUO) {
29492934
return typesSatisfyConstraint(type1, type2,

lib/Sema/TypeCheckGeneric.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -931,9 +931,7 @@ RequirementCheckResult TypeChecker::checkGenericArguments(
931931

932932
case RequirementKind::Superclass: {
933933
// Superclass requirements.
934-
// FIXME: Don't use the type checker instance here?
935-
TypeChecker &tc = static_cast<TypeChecker &>(*ctx.getLazyResolver());
936-
if (!tc.isSubclassOf(firstType, secondType, dc)) {
934+
if (!secondType->isExactSuperclassOf(firstType)) {
937935
diagnostic = diag::type_does_not_inherit;
938936
diagnosticNote = diag::type_does_not_inherit_or_conform_requirement;
939937
requirementFailure = true;

lib/Sema/TypeCheckProtocolInference.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1557,7 +1557,7 @@ compareDeclsForInference(TypeChecker &TC, DeclContext *DC,
15571557
if (!t2)
15581558
return true;
15591559

1560-
return TC.isSubclassOf(t1, t2, DC);
1560+
return t2->isExactSuperclassOf(t1);
15611561
};
15621562

15631563
bool protos1AreSubsetOf2 = protos1.empty();

lib/Sema/TypeChecker.h

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -986,15 +986,6 @@ class TypeChecker final : public LazyResolver {
986986
///
987987
/// \returns true if \c t1 is a subtype of \c t2.
988988
bool isSubtypeOf(Type t1, Type t2, DeclContext *dc);
989-
990-
/// \brief Determine whether one type is a subclass of another.
991-
///
992-
/// \param t1 The potential subtype.
993-
/// \param t2 The potential supertype.
994-
/// \param dc The context of the check.
995-
///
996-
/// \returns true if \c t1 is a subtype of \c t2.
997-
bool isSubclassOf(Type t1, Type t2, DeclContext *dc);
998989

999990
/// \brief Determine whether one type is implicitly convertible to another.
1000991
///

test/Generics/superclass_constraint.swift

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// RUN: %target-typecheck-verify-swift
22

3-
// RUN: %target-typecheck-verify-swift -typecheck -debug-generic-signatures %s > %t.dump 2>&1
3+
// RUN: %target-typecheck-verify-swift -typecheck -debug-generic-signatures %s > %t.dump 2>&1
44
// RUN: %FileCheck %s < %t.dump
55

66
class A {
@@ -204,3 +204,13 @@ func g<T : Init & Derived>(_: T.Type) {
204204
_ = T(x: ())
205205
_ = T(y: ())
206206
}
207+
208+
// Binding a class-constrained generic parameter to a subclass existential is
209+
// not sound.
210+
struct G<T : Base> {}
211+
// expected-note@-1 2 {{requirement specified as 'T' : 'Base' [with T = Base & P]}}
212+
213+
_ = G<Base & P>() // expected-error {{'G' requires that 'Base & P' inherit from 'Base'}}
214+
215+
func badClassConstrainedType(_: G<Base & P>) {}
216+
// expected-error@-1 {{'G' requires that 'Base & P' inherit from 'Base'}}

0 commit comments

Comments
 (0)