Skip to content

Commit 244a5f7

Browse files
committed
Sema: Fix crash with recursive subscript validation via associated type inference
Looks like subscript validation wasn't checking or setting ValueDecl::isBeingValidated(). This caused a stack overflow with associated type inference. The way to trigger this during normal use is to invoke the fixit for adding missing protocol requirements -- they're written in terms of the protocol's associated type, which the user might not have defined yet. Fixes <rdar://problem/26680599>.
1 parent 700be61 commit 244a5f7

File tree

2 files changed

+31
-3
lines changed

2 files changed

+31
-3
lines changed

lib/Sema/TypeCheckDecl.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4093,9 +4093,11 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
40934093
return;
40944094
}
40954095

4096-
if (SD->hasInterfaceType())
4096+
if (SD->hasInterfaceType() || SD->isBeingValidated())
40974097
return;
40984098

4099+
SD->setIsBeingValidated();
4100+
40994101
auto dc = SD->getDeclContext();
41004102
assert(dc->isTypeContext() &&
41014103
"Decl parsing must prevent subscripts outside of types!");
@@ -4139,6 +4141,8 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
41394141
TC.configureInterfaceType(SD, SD->getGenericSignature());
41404142
}
41414143

4144+
SD->setIsBeingValidated(false);
4145+
41424146
TC.checkDeclAttributesEarly(SD);
41434147
TC.computeAccessibility(SD);
41444148

test/decl/protocol/req/associated_type_inference.swift

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,11 @@ struct XProp0b : PropertyP0 { // expected-error{{type 'XProp0b' does not conform
129129
// Inference from subscripts
130130
protocol SubscriptP0 {
131131
associatedtype Index
132-
associatedtype Element : PSimple // expected-note{{unable to infer associated type 'Element' for protocol 'SubscriptP0'}}
132+
// expected-note@-1 2 {{protocol requires nested type 'Index'; do you want to add it?}}
133+
134+
associatedtype Element : PSimple
135+
// expected-note@-1 {{unable to infer associated type 'Element' for protocol 'SubscriptP0'}}
136+
// expected-note@-2 2 {{protocol requires nested type 'Element'; do you want to add it?}}
133137

134138
subscript (i: Index) -> Element { get }
135139
}
@@ -138,14 +142,27 @@ struct XSubP0a : SubscriptP0 {
138142
subscript (i: Int) -> Int { get { return i } }
139143
}
140144

141-
struct XSubP0b : SubscriptP0 { // expected-error{{type 'XSubP0b' does not conform to protocol 'SubscriptP0'}}
145+
struct XSubP0b : SubscriptP0 {
146+
// expected-error@-1{{type 'XSubP0b' does not conform to protocol 'SubscriptP0'}}
142147
subscript (i: Int) -> Float { get { return Float(i) } } // expected-note{{inferred type 'Float' (by matching requirement 'subscript') is invalid: does not conform to 'PSimple'}}
143148
}
144149

150+
struct XSubP0c : SubscriptP0 {
151+
// expected-error@-1 {{type 'XSubP0c' does not conform to protocol 'SubscriptP0'}}
152+
subscript (i: Index) -> Element { get { } }
153+
}
154+
155+
struct XSubP0d : SubscriptP0 {
156+
// expected-error@-1 {{type 'XSubP0d' does not conform to protocol 'SubscriptP0'}}
157+
subscript (i: XSubP0d.Index) -> XSubP0d.Element { get { } }
158+
}
159+
145160
// Inference from properties and subscripts
146161
protocol CollectionLikeP0 {
147162
associatedtype Index
163+
// expected-note@-1 {{protocol requires nested type 'Index'; do you want to add it?}}
148164
associatedtype Element
165+
// expected-note@-1 {{protocol requires nested type 'Element'; do you want to add it?}}
149166

150167
var startIndex: Index { get }
151168
var endIndex: Index { get }
@@ -164,6 +181,13 @@ struct XCollectionLikeP0a<T> : CollectionLikeP0 {
164181
subscript (r: Range<Int>) -> SomeSlice<T> { get { return SomeSlice() } }
165182
}
166183

184+
struct XCollectionLikeP0b : CollectionLikeP0 {
185+
// expected-error@-1 {{type 'XCollectionLikeP0b' does not conform to protocol 'CollectionLikeP0'}}
186+
var startIndex: XCollectionLikeP0b.Index
187+
// expected-error@-1 {{'startIndex' used within its own type}}
188+
var startElement: XCollectionLikeP0b.Element
189+
}
190+
167191
// rdar://problem/21304164
168192
public protocol Thenable {
169193
associatedtype T // expected-note{{protocol requires nested type 'T'}}

0 commit comments

Comments
 (0)