Skip to content

Commit d9a1941

Browse files
committed
Do not recurse infinitely when type checking constructor parameters.
Fully-qualified references to associated types in parameter lists of constructors could result in infinite recursion and crash the compiler when the typealias for the associated type is not defined. Use the same approach used in normal function parameter lists of setting IsBeingTypeChecked on the enclosing type to avoid going into an infinite recursion here. Resolves rdar://problem/27680407. (cherry picked from commit 126b9fc)
1 parent 0cca666 commit d9a1941

File tree

2 files changed

+25
-10
lines changed

2 files changed

+25
-10
lines changed

lib/Sema/TypeCheckDecl.cpp

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6425,17 +6425,22 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
64256425
}
64266426
}
64276427

6428-
// Type check the constructor parameters.
6429-
if (CD->isInvalid() || semaFuncParamPatterns(CD)) {
6430-
CD->overwriteType(ErrorType::get(TC.Context));
6431-
CD->setInterfaceType(ErrorType::get(TC.Context));
6432-
CD->setInvalid();
6433-
} else {
6434-
configureConstructorType(CD, SelfTy,
6435-
CD->getParameterList(1)->getType(TC.Context));
6428+
{
6429+
CD->setIsBeingTypeChecked(true);
6430+
SWIFT_DEFER { CD->setIsBeingTypeChecked(false); };
6431+
6432+
// Type check the constructor parameters.
6433+
if (CD->isInvalid() || semaFuncParamPatterns(CD)) {
6434+
CD->overwriteType(ErrorType::get(TC.Context));
6435+
CD->setInterfaceType(ErrorType::get(TC.Context));
6436+
CD->setInvalid();
6437+
} else {
6438+
configureConstructorType(CD, SelfTy,
6439+
CD->getParameterList(1)->getType(TC.Context));
64366440

6437-
if (!CD->isGenericContext())
6438-
TC.configureInterfaceType(CD);
6441+
if (!CD->isGenericContext())
6442+
TC.configureInterfaceType(CD);
6443+
}
64396444
}
64406445

64416446
validateAttributes(TC, CD);

test/Sema/circular_decl_checking.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,13 @@ struct SomeStruct<A> {
6666
typealias A = A // expected-error {{type alias 'A' circularly references itself}}
6767
}
6868

69+
// <rdar://problem/27680407> Infinite recursion when using fully-qualified associatedtype name that has not been defined with typealias
70+
protocol rdar27680407Proto {
71+
associatedtype T // expected-note {{protocol requires nested type 'T'; do you want to add it?}}
72+
73+
init(value: T)
74+
}
75+
76+
struct rdar27680407Struct : rdar27680407Proto { // expected-error {{type 'rdar27680407Struct' does not conform to protocol 'rdar27680407Proto'}}
77+
init(value: rdar27680407Struct.T) {}
78+
}

0 commit comments

Comments
 (0)