Skip to content

Commit 761b0aa

Browse files
committed
Allow existential opening for parameters of optional type.
1 parent 5cf1cb3 commit 761b0aa

File tree

3 files changed

+20
-11
lines changed

3 files changed

+20
-11
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1584,8 +1584,10 @@ shouldOpenExistentialCallArgument(
15841584
if (param->isVariadic())
15851585
return None;
15861586

1587-
// Look through an inout type on the formal type of the parameter.
1588-
auto formalParamTy = param->getInterfaceType()->getInOutObjectType();
1587+
// Look through an inout and optional types on the formal type of the
1588+
// parameter.
1589+
auto formalParamTy = param->getInterfaceType()->getInOutObjectType()
1590+
->lookThroughSingleOptionalType();
15891591

15901592
// If the argument is of an existential metatype, look through the
15911593
// metatype on the parameter.
@@ -1594,8 +1596,8 @@ shouldOpenExistentialCallArgument(
15941596
paramTy = paramTy->getMetatypeInstanceType();
15951597
}
15961598

1597-
// Look through an inout type on the parameter.
1598-
paramTy = paramTy->getInOutObjectType();
1599+
// Look through an inout and optional types on the parameter.
1600+
paramTy = paramTy->getInOutObjectType()->lookThroughSingleOptionalType();
15991601

16001602
// The parameter type must be a type variable.
16011603
auto paramTypeVar = paramTy->getAs<TypeVariableType>();

test/Constraints/opened_existentials.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,16 @@ func passesInOut(i: Int) {
161161
takesInOut(&p)
162162
}
163163

164+
func takesOptional<T: P>(_ value: T?) { }
165+
// expected-note@-1{{required by global function 'takesOptional' where 'T' = 'any P'}}
166+
167+
func passesToOptional(p: any P, pOpt: (any P)?) {
168+
takesOptional(p) // okay
169+
takesOptional(pOpt) // expected-error{{type 'any P' cannot conform to 'P'}}
170+
// expected-note@-1{{only concrete types such as structs, enums and classes can conform to protocols}}
171+
}
172+
173+
164174
@available(SwiftStdlib 5.1, *)
165175
func testReturningOpaqueTypes(p: any P) {
166176
let q = p.getQ()

test/Generics/existential_restrictions.swift

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,7 @@ protocol CP : class { }
99
}
1010

1111
func fP<T : P>(_ t: T?) { }
12-
// expected-note@-1 {{required by global function 'fP' where 'T' = 'any P'}}
13-
// expected-note@-2 {{required by global function 'fP' where 'T' = 'any OP & P'}}
1412
func fOP<T : OP>(_ t: T?) { }
15-
// expected-note@-1 {{required by global function 'fOP' where 'T' = 'any OP & P'}}
1613
func fOPE(_ t: OP) { }
1714
func fSP<T : SP>(_ t: T?) { }
1815
func fAO<T : AnyObject>(_ t: T?) { }
@@ -23,7 +20,7 @@ func fAOE(_ t: AnyObject) { }
2320
func fT<T>(_ t: T) { }
2421

2522
func testPassExistential(_ p: P, op: OP, opp: OP & P, cp: CP, sp: SP, any: Any, ao: AnyObject) {
26-
fP(p) // expected-error{{type 'any P' cannot conform to 'P'}} expected-note {{only concrete types such as structs, enums and classes can conform to protocols}}
23+
fP(p)
2724
fAO(p) // expected-error{{global function 'fAO' requires that 'any P' be a class type}}
2825
fAOE(p) // expected-error{{argument type 'any P' expected to be an instance of a class or class-constrained type}}
2926
fT(p)
@@ -37,14 +34,14 @@ func testPassExistential(_ p: P, op: OP, opp: OP & P, cp: CP, sp: SP, any: Any,
3734
fAOE(cp)
3835
fT(cp)
3936

40-
fP(opp) // expected-error{{type 'any OP & P' cannot conform to 'P'}} expected-note {{only concrete types such as structs, enums and classes can conform to protocols}}
41-
fOP(opp) // expected-error{{type 'any OP & P' cannot conform to 'OP'}} expected-note {{only concrete types such as structs, enums and classes can conform to protocols}}
37+
fP(opp)
38+
fOP(opp)
4239
fAO(opp) // expected-error{{global function 'fAO' requires that 'any OP & P' be a class type}}
4340
fAOE(opp)
4441
fT(opp)
4542

4643
fOP(sp)
47-
fSP(sp) // expected-error{{'any SP' cannot be used as a type conforming to protocol 'SP' because 'SP' has static requirements}}
44+
fSP(sp)
4845
fAO(sp)
4946
fAOE(sp)
5047
fT(sp)

0 commit comments

Comments
 (0)