Skip to content

Commit f13f3bd

Browse files
authored
Merge pull request #41332 from slavapestov/rqm-typealias-cycle-fix
Sema: Fix request cycle involving protocol typealiases in preparation for RequirementMachine support
2 parents 4d99516 + 6c714f4 commit f13f3bd

File tree

7 files changed

+28
-21
lines changed

7 files changed

+28
-21
lines changed

include/swift/AST/TypeCheckRequests.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -874,6 +874,7 @@ class StructuralTypeRequest :
874874
public:
875875
// Caching.
876876
bool isCached() const { return true; }
877+
void diagnoseCycle(DiagnosticEngine &diags) const;
877878
};
878879

879880
/// Request the fragile function kind for the context.

lib/AST/Type.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1468,10 +1468,9 @@ CanType TypeBase::computeCanonicalType() {
14681468
// If we haven't set a depth for this generic parameter, try to do so.
14691469
// FIXME: This is a dreadful hack.
14701470
if (gpDecl->getDepth() == GenericTypeParamDecl::InvalidDepth) {
1471-
if (auto decl =
1472-
gpDecl->getDeclContext()->getInnermostDeclarationDeclContext())
1473-
if (auto valueDecl = decl->getAsGenericContext())
1474-
(void)valueDecl->getGenericSignature();
1471+
auto *dc = gpDecl->getDeclContext();
1472+
auto *gpList = dc->getAsDecl()->getAsGenericContext()->getGenericParams();
1473+
gpList->setDepth(dc->getGenericContextDepth());
14751474
}
14761475

14771476
assert(gpDecl->getDepth() != GenericTypeParamDecl::InvalidDepth &&

lib/AST/TypeCheckRequests.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -824,6 +824,17 @@ void UnderlyingTypeRequest::diagnoseCycle(DiagnosticEngine &diags) const {
824824
aliasDecl->getName());
825825
}
826826

827+
//----------------------------------------------------------------------------//
828+
// StructuralTypeRequest computation.
829+
//----------------------------------------------------------------------------//
830+
831+
void StructuralTypeRequest::diagnoseCycle(DiagnosticEngine &diags) const {
832+
auto aliasDecl = std::get<0>(getStorage());
833+
diags.diagnose(aliasDecl, diag::recursive_decl_reference,
834+
aliasDecl->getDescriptiveKind(),
835+
aliasDecl->getName());
836+
}
837+
827838
//----------------------------------------------------------------------------//
828839
// EnumRawValuesRequest computation.
829840
//----------------------------------------------------------------------------//

lib/Sema/TypeCheckType.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -827,9 +827,6 @@ Type TypeResolution::applyUnboundGenericArguments(
827827
genericArgs.size() >= decl->getGenericParams()->size() - 1)) &&
828828
"invalid arguments, use applyGenericArguments for diagnostic emitting");
829829

830-
auto genericSig = decl->getGenericSignature();
831-
assert(!genericSig.isNull());
832-
833830
TypeSubstitutionMap subs;
834831

835832
// Get the interface type for the declaration. We will be substituting
@@ -855,6 +852,7 @@ Type TypeResolution::applyUnboundGenericArguments(
855852
if (!resultType->hasTypeParameter())
856853
return resultType;
857854

855+
auto genericSig = decl->getGenericSignature();
858856
auto parentSig = decl->getDeclContext()->getGenericSignatureOfContext();
859857
for (auto gp : parentSig.getGenericParams())
860858
subs[gp->getCanonicalType()->castTo<GenericTypeParamType>()] =
@@ -864,18 +862,18 @@ Type TypeResolution::applyUnboundGenericArguments(
864862
}
865863

866864
skipRequirementsCheck |= parentTy->hasTypeVariable();
867-
} else if (auto genericSig =
865+
} else if (auto parentSig =
868866
decl->getDeclContext()->getGenericSignatureOfContext()) {
869-
for (auto gp : genericSig.getGenericParams()) {
867+
for (auto gp : parentSig.getGenericParams()) {
870868
subs[gp->getCanonicalType()->castTo<GenericTypeParamType>()] = gp;
871869
}
872870
}
873871

874872
// Realize the types of the generic arguments and add them to the
875873
// substitution map.
876-
auto innerParams = genericSig.getInnermostGenericParams();
877-
for (unsigned i = 0; i < innerParams.size(); ++i) {
878-
auto origTy = innerParams[i];
874+
auto innerParams = decl->getGenericParams()->getParams();
875+
for (unsigned i : indices(innerParams)) {
876+
auto origTy = innerParams[i]->getDeclaredInterfaceType();
879877
auto origGP = origTy->getCanonicalType()->castTo<GenericTypeParamType>();
880878

881879
if (!origGP->isTypeSequence()) {
@@ -894,7 +892,8 @@ Type TypeResolution::applyUnboundGenericArguments(
894892
// types we can bind to this type sequence parameter.
895893
unsigned tail;
896894
for (tail = 1; tail <= innerParams.size(); ++tail) {
897-
auto tailTy = innerParams[innerParams.size() - tail];
895+
auto tailTy = innerParams[innerParams.size() - tail]
896+
->getDeclaredInterfaceType();
898897
auto tailGP = tailTy->getCanonicalType()->castTo<GenericTypeParamType>();
899898
if (tailGP->isTypeSequence()) {
900899
assert(tailGP->isEqual(origGP) &&
@@ -943,6 +942,7 @@ Type TypeResolution::applyUnboundGenericArguments(
943942
if (noteLoc.isInvalid())
944943
noteLoc = loc;
945944

945+
auto genericSig = decl->getGenericSignature();
946946
auto result = TypeChecker::checkGenericArguments(
947947
module, loc, noteLoc,
948948
UnboundGenericType::get(decl, parentTy, getASTContext()),

test/Generics/generic_types.swift

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -230,9 +230,7 @@ class Top {}
230230
class Bottom<T : Bottom<Top>> {}
231231
// expected-error@-1 {{'Bottom' requires that 'Top' inherit from 'Bottom<Top>'}}
232232
// expected-note@-2 {{requirement specified as 'T' : 'Bottom<Top>' [with T = Top]}}
233-
// expected-error@-3 4{{generic class 'Bottom' has self-referential generic requirements}}
234-
// expected-note@-4 {{while resolving type 'Bottom<Top>'}}
235-
// expected-note@-5 {{through reference here}}
233+
// expected-error@-3 3{{generic class 'Bottom' has self-referential generic requirements}}
236234

237235
// Invalid inheritance clause
238236

test/decl/protocol/req/recursion.swift

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,7 @@ public protocol P {
4545
}
4646

4747
public struct S<A: P> where A.T == S<A> {
48-
// expected-error@-1 4{{generic struct 'S' has self-referential generic requirements}}
49-
// expected-note@-2 {{while resolving type 'S<A>'}}
48+
// expected-error@-1 3{{generic struct 'S' has self-referential generic requirements}}
5049
func f(a: A.T) {
5150
g(a: id(t: a)) // `a` has error type which is diagnosed as circular reference
5251
_ = A.T.self
@@ -71,8 +70,7 @@ protocol PI {
7170
}
7271

7372
struct SI<A: PI> : I where A : I, A.T == SI<A> {
74-
// expected-error@-1 4{{generic struct 'SI' has self-referential generic requirements}}
75-
// expected-note@-2 {{while resolving type 'SI<A>'}}
73+
// expected-error@-1 3{{generic struct 'SI' has self-referential generic requirements}}
7674
func ggg<T : I>(t: T.Type) -> T {
7775
return T()
7876
}

validation-test/compiler_crashers_2_fixed/sr-10612.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: not %target-swift-frontend -typecheck %s
1+
// RUN: %target-swift-frontend -typecheck %s
22

33
protocol P1: class {
44
associatedtype P1P1: P1

0 commit comments

Comments
 (0)