Skip to content

Commit 76d1ba7

Browse files
committed
Only open existentials for generic arguments on the called declaration
1 parent 52dba17 commit 76d1ba7

File tree

2 files changed

+18
-2
lines changed

2 files changed

+18
-2
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1397,10 +1397,19 @@ shouldOpenExistentialCallArgument(
13971397
if (!genericParam)
13981398
return None;
13991399

1400-
// Ensure that the formal parameter is only used in covariant positions,
1401-
// because it won't match anywhere else.
1400+
// Only allow opening the innermost generic parameters.
1401+
auto genericContext = callee->getAsGenericContext();
1402+
if (!genericContext || !genericContext->isGeneric())
1403+
return None;
1404+
14021405
auto genericSig = callee->getInnermostDeclContext()
14031406
->getGenericSignatureOfContext().getCanonicalSignature();
1407+
if (genericParam->getDepth() <
1408+
genericSig.getGenericParams().back()->getDepth())
1409+
return None;
1410+
1411+
// Ensure that the formal parameter is only used in covariant positions,
1412+
// because it won't match anywhere else.
14041413
auto referenceInfo = findGenericParameterReferences(
14051414
callee, genericSig, genericParam,
14061415
/*treatNonResultCovarianceAsInvariant=*/false,

test/Constraints/opened_existentials.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,13 +126,20 @@ func arrayOfOne<T: P>(_ value: T) -> [T] {
126126
}
127127

128128
struct X<T: P> {
129+
// expected-note@-1{{required by generic struct 'X' where 'T' = 'P'}}
130+
func f(_: T) { }
129131
}
130132

131133
// expected-note@+1{{required by global function 'createX' where 'T' = 'P'}}
132134
func createX<T: P>(_ value: T) -> X<T> {
133135
X<T>()
134136
}
135137

138+
func doNotOpenOuter(p: any P) {
139+
_ = X().f(p) // expected-error{{protocol 'P' as a type cannot conform to the protocol itself}}
140+
// expected-note@-1{{only concrete types such as structs, enums and classes can conform to protocols}}
141+
}
142+
136143
@available(SwiftStdlib 5.1, *)
137144
func testReturningOpaqueTypes(p: any P) {
138145
let q = p.getQ()

0 commit comments

Comments
 (0)