Skip to content

Commit 81fad09

Browse files
committed
Sema: Nominal types nested inside protocols are not requirements
1 parent fdaa886 commit 81fad09

File tree

2 files changed

+25
-17
lines changed

2 files changed

+25
-17
lines changed

lib/Sema/TypeCheckProtocol.cpp

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3963,6 +3963,17 @@ void ConformanceChecker::resolveSingleTypeWitness(
39633963
}
39643964
}
39653965

3966+
// Not all protocol members are requirements.
3967+
static bool isRequirement(ValueDecl *requirement) {
3968+
if (auto *FD = dyn_cast<FuncDecl>(requirement))
3969+
if (FD->isAccessor())
3970+
return false;
3971+
if (isa<TypeAliasDecl>(requirement) ||
3972+
isa<NominalTypeDecl>(requirement))
3973+
return false;
3974+
return true;
3975+
}
3976+
39663977
void ConformanceChecker::resolveSingleWitness(ValueDecl *requirement) {
39673978
assert(!isa<AssociatedTypeDecl>(requirement) && "Not a value witness");
39683979
assert(!Conformance->hasWitness(requirement) && "Already resolved");
@@ -3982,12 +3993,7 @@ void ConformanceChecker::resolveSingleWitness(ValueDecl *requirement) {
39823993
return;
39833994
}
39843995

3985-
// If this is a getter/setter for a funcdecl, ignore it.
3986-
if (auto *FD = dyn_cast<FuncDecl>(requirement))
3987-
if (FD->isAccessor())
3988-
return;
3989-
// If this is a typealias, it does not need a witness check.
3990-
if (isa<TypeAliasDecl>(requirement))
3996+
if (!isRequirement(requirement))
39913997
return;
39923998

39933999
// Resolve all associated types before trying to resolve this witness.
@@ -4132,15 +4138,11 @@ void ConformanceChecker::checkConformance() {
41324138
continue;
41334139

41344140
// Associated type requirements handled above.
4135-
if (isa<AssociatedTypeDecl>(requirement))
4141+
if (isa<TypeDecl>(requirement))
41364142
continue;
41374143

41384144
// Type aliases don't have requirements themselves.
4139-
if (isa<TypeAliasDecl>(requirement))
4140-
continue;
4141-
4142-
// Nominal types nested inside protocols are not requirements.
4143-
if (isa<NominalTypeDecl>(requirement))
4145+
if (!isRequirement(requirement))
41444146
continue;
41454147

41464148
/// Local function to finalize the witness.
@@ -5468,14 +5470,20 @@ void TypeChecker::inferDefaultWitnesses(ProtocolDecl *proto) {
54685470
DefaultWitnessChecker checker(*this, proto);
54695471

54705472
for (auto *requirement : proto->getMembers()) {
5471-
if (isa<AssociatedTypeDecl>(requirement))
5473+
if (requirement->isInvalid())
54725474
continue;
54735475

5474-
if (requirement->isInvalid())
5476+
auto *valueDecl = dyn_cast<ValueDecl>(requirement);
5477+
if (!valueDecl)
5478+
continue;
5479+
5480+
if (isa<TypeDecl>(valueDecl))
5481+
continue;
5482+
5483+
if (!isRequirement(valueDecl))
54755484
continue;
54765485

5477-
if (auto *valueDecl = dyn_cast<ValueDecl>(requirement))
5478-
checker.resolveWitnessViaLookup(valueDecl);
5486+
checker.resolveWitnessViaLookup(valueDecl);
54795487
}
54805488
}
54815489

validation-test/compiler_crashers/28394-swift-typechecker-checkconformance.swift renamed to validation-test/compiler_crashers_fixed/28394-swift-typechecker-checkconformance.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@
55
// See https://swift.org/LICENSE.txt for license information
66
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
77

8-
// RUN: not --crash %target-swift-frontend %s -typecheck
8+
// RUN: not %target-swift-frontend %s -typecheck
99
// REQUIRES: asserts
1010
class d:a{let c=A}protocol a{struct A{}class S<T{}typealias e:a typealias d:a

0 commit comments

Comments
 (0)