Skip to content

Commit ed93529

Browse files
authored
Merge pull request #61321 from DougGregor/open-existential-for-optional-param
2 parents 777eafc + 761b0aa commit ed93529

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
@@ -1620,8 +1620,10 @@ shouldOpenExistentialCallArgument(
16201620
if (param->isVariadic())
16211621
return None;
16221622

1623-
// Look through an inout type on the formal type of the parameter.
1624-
auto formalParamTy = param->getInterfaceType()->getInOutObjectType();
1623+
// Look through an inout and optional types on the formal type of the
1624+
// parameter.
1625+
auto formalParamTy = param->getInterfaceType()->getInOutObjectType()
1626+
->lookThroughSingleOptionalType();
16251627

16261628
// If the argument is of an existential metatype, look through the
16271629
// metatype on the parameter.
@@ -1630,8 +1632,8 @@ shouldOpenExistentialCallArgument(
16301632
paramTy = paramTy->getMetatypeInstanceType();
16311633
}
16321634

1633-
// Look through an inout type on the parameter.
1634-
paramTy = paramTy->getInOutObjectType();
1635+
// Look through an inout and optional types on the parameter.
1636+
paramTy = paramTy->getInOutObjectType()->lookThroughSingleOptionalType();
16351637

16361638
// The parameter type must be a type variable.
16371639
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)