Skip to content

Commit f3a4558

Browse files
committed
[SE-0404] Rebase fixes and better handling of generic superclasses with inferred params
1 parent 7b68919 commit f3a4558

File tree

3 files changed

+40
-40
lines changed

3 files changed

+40
-40
lines changed

lib/AST/DeclContext.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,12 @@ DeclContext *DeclContext::getParentForLookup() const {
269269
// outer types.
270270
return getModuleScopeContext();
271271
}
272+
if (isa<ProtocolDecl>(this) && getParent()->isGenericContext()) {
273+
// Protocols in generic contexts must not look in to their parents,
274+
// as the parents may contain types with inferred implicit
275+
// generic parameters not present in the protocol's generic signature.
276+
return getModuleScopeContext();
277+
}
272278
if (isa<NominalTypeDecl>(this)) {
273279
// If we are inside a nominal type that is inside a protocol,
274280
// skip the protocol.

lib/Sema/TypeCheckDeclPrimary.cpp

Lines changed: 20 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2674,30 +2674,30 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
26742674
NTD->diagnose(diag::tuple_extension_nested_type, NTD);
26752675
return;
26762676
}
2677-
}
26782677

2679-
// We don't support protocols nested in generic contexts.
2680-
// This includes protocols nested in other protocols.
2681-
if (isa<ProtocolDecl>(NTD) && NTD->getParent()->isGenericContext()) {
2682-
if (auto *OuterPD = NTD->getParent()->getSelfProtocolDecl())
2683-
NTD->diagnose(diag::unsupported_nested_protocol_in_protocol, NTD,
2684-
OuterPD);
2685-
else
2686-
NTD->diagnose(diag::unsupported_nested_protocol_in_generic, NTD);
2678+
// We don't support protocols nested in generic contexts.
2679+
// This includes protocols nested in other protocols.
2680+
if (isa<ProtocolDecl>(NTD) && DC->isGenericContext()) {
2681+
if (auto *OuterPD = DC->getSelfProtocolDecl())
2682+
NTD->diagnose(diag::unsupported_nested_protocol_in_protocol, NTD,
2683+
OuterPD);
2684+
else
2685+
NTD->diagnose(diag::unsupported_nested_protocol_in_generic, NTD);
26872686

2688-
NTD->setInvalid();
2689-
return;
2690-
}
2687+
NTD->setInvalid();
2688+
return;
2689+
}
26912690

2692-
// We don't support nested types in protocols.
2693-
if (auto proto = dyn_cast<ProtocolDecl>(parentDecl)) {
2694-
if (DC->getExtendedProtocolDecl()) {
2695-
NTD->diagnose(diag::unsupported_type_nested_in_protocol_extension, NTD,
2696-
proto);
2697-
} else {
2698-
NTD->diagnose(diag::unsupported_type_nested_in_protocol, NTD, proto);
2691+
// We don't support nested types in protocols.
2692+
if (auto proto = dyn_cast<ProtocolDecl>(parentDecl)) {
2693+
if (DC->getExtendedProtocolDecl()) {
2694+
NTD->diagnose(diag::unsupported_type_nested_in_protocol_extension, NTD,
2695+
proto);
2696+
} else {
2697+
NTD->diagnose(diag::unsupported_type_nested_in_protocol, NTD, proto);
2698+
}
2699+
NTD->setInvalid();
26992700
}
2700-
NTD->setInvalid();
27012701
}
27022702

27032703
// We don't support nested types in generic functions yet.
@@ -3189,15 +3189,6 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
31893189
if (!PD->getPrimaryAssociatedTypeNames().empty())
31903190
(void) PD->getPrimaryAssociatedTypes();
31913191

3192-
// We cannot compute the requirement signature of a protocol
3193-
// in a generic context, because superclass constraints
3194-
// may include implicitly inferred generic arguments that are
3195-
// not part of the protocol's generic signature.
3196-
if (PD->getParent()->isGenericContext()) {
3197-
assert(PD->isInvalid());
3198-
return;
3199-
}
3200-
32013192
// Explicitly compute the requirement signature to detect errors.
32023193
// Do this before visiting members, to avoid a request cycle if
32033194
// a member references another declaration whose generic signature

test/decl/nested/protocol.swift

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -163,15 +163,15 @@ struct OuterGeneric<D> {
163163
protocol InnerProtocol { // expected-error{{protocol 'InnerProtocol' cannot be nested in a generic context}}
164164
associatedtype Rooster
165165
func flip(_ r: Rooster)
166-
func flop(_ t: D)
166+
func flop(_ t: D) // expected-error {{cannot find type 'D' in scope}}
167167
}
168168
}
169169

170170
class OuterGenericClass<T> {
171171
protocol InnerProtocol { // expected-error{{protocol 'InnerProtocol' cannot be nested in a generic context}}
172172
associatedtype Rooster
173173
func flip(_ r: Rooster)
174-
func flop(_ t: T)
174+
func flop(_ t: T) // expected-error {{cannot find type 'T' in scope}}
175175
}
176176
}
177177

@@ -180,7 +180,7 @@ protocol OuterProtocol {
180180
protocol InnerProtocol { // expected-error{{protocol 'InnerProtocol' cannot be nested in protocol 'OuterProtocol'}}
181181
associatedtype Rooster
182182
func flip(_ r: Rooster)
183-
func flop(_ h: Hen)
183+
func flop(_ h: Hen) // expected-error {{cannot find type 'Hen' in scope}}
184184
}
185185
}
186186

@@ -195,37 +195,40 @@ struct ConformsToOuterProtocol : OuterProtocol {
195195

196196
extension OuterProtocol {
197197
func f() {
198-
protocol Invalid_0 {} // expected-error{{protocol 'Invalid_0' cannot be nested in a generic context}}
198+
protocol Invalid_0 {} // expected-error{{type 'Invalid_0' cannot be nested in generic function 'f()'}}
199199

200200
struct SomeType { // expected-error{{type 'SomeType' cannot be nested in generic function 'f()'}}
201201
protocol Invalid_1 {} // expected-error{{protocol 'Invalid_1' cannot be nested in a generic context}}
202202
}
203203
}
204204
func g<T>(_: T) {
205-
protocol Invalid_2 {} // expected-error{{protocol 'Invalid_2' cannot be nested in a generic context}}
205+
protocol Invalid_2 {} // expected-error{{type 'Invalid_2' cannot be nested in generic function 'g'}}
206206
}
207207
}
208208

209209
// 'InnerProtocol' does not inherit the generic parameters of
210210
// 'OtherGenericClass', so the occurrence of 'OtherGenericClass'
211211
// in 'InnerProtocol' is not "in context" with implicitly
212212
// inferred generic arguments <T, U>.
213-
class OtherGenericClass<T, U> {
213+
class OtherGenericClass<T, U> { // expected-note {{generic type 'OtherGenericClass' declared here}}
214214
protocol InnerProtocol : OtherGenericClass { }
215-
// expected-error@-1{{protocol 'InnerProtocol' cannot be nested in a generic context}}
215+
// expected-error@-1 {{protocol 'InnerProtocol' cannot be nested in a generic context}}
216+
// expected-error@-2 {{reference to generic type 'OtherGenericClass' requires arguments in <...>}}
216217
}
217218

218219
protocol InferredGenericTest {
219220
associatedtype A
220221
}
221222
extension OtherGenericClass {
222-
protocol P: InferredGenericTest where Self.A == T {} // expected-error {{protocol 'P' cannot be nested in a generic context}}
223+
protocol P: InferredGenericTest where Self.A == T {}
224+
// expected-error@-1 {{protocol 'P' cannot be nested in a generic context}}
225+
// expected-error@-2 {{cannot find type 'T' in scope}}
223226
}
224227

225228
// A nested protocol does not satisfy an associated type requirement.
226229

227230
protocol HasAssoc {
228-
associatedtype A // expected-note {{protocol requires nested type 'A'; do you want to add it?}}
231+
associatedtype A // expected-note {{protocol requires nested type 'A'; add nested type 'A' for conformance}}
229232
}
230233
struct ConformsToHasAssoc: HasAssoc { // expected-error {{type 'ConformsToHasAssoc' does not conform to protocol 'HasAssoc'}}
231234
protocol A {}
@@ -257,12 +260,12 @@ func testLookup<T: OuterForUFI.Inner>(_ x: T) {
257260
// Protocols cannot be nested inside of generic functions.
258261

259262
func invalidProtocolInGeneric<T>(_: T) {
260-
protocol Test {} // expected-error{{protocol 'Test' cannot be nested in a generic context}}
263+
protocol Test {} // expected-error{{type 'Test' cannot be nested in generic function 'invalidProtocolInGeneric'}}
261264
}
262265

263266
struct NestedInGenericMethod<T> {
264267
func someMethod() {
265-
protocol AnotherTest {} // expected-error{{protocol 'AnotherTest' cannot be nested in a generic context}}
268+
protocol AnotherTest {} // expected-error{{type 'AnotherTest' cannot be nested in generic function 'someMethod()'}}
266269
}
267270
}
268271

0 commit comments

Comments
 (0)