Skip to content

Commit e1f68b2

Browse files
committed
Allow existential opening for parameters of optional type.
1 parent e30c8a5 commit e1f68b2

File tree

2 files changed

+16
-4
lines changed

2 files changed

+16
-4
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1402,8 +1402,10 @@ shouldOpenExistentialCallArgument(
14021402
if (param->isVariadic() && !param->getVarargBaseTy()->hasTypeSequence())
14031403
return None;
14041404

1405-
// Look through an inout type on the formal type of the parameter.
1406-
auto formalParamTy = param->getInterfaceType()->getInOutObjectType();
1405+
// Look through an inout and optional types on the formal type of the
1406+
// parameter.
1407+
auto formalParamTy = param->getInterfaceType()->getInOutObjectType()
1408+
->lookThroughSingleOptionalType();
14071409

14081410
// If the argument is of an existential metatype, look through the
14091411
// metatype on the parameter.
@@ -1412,8 +1414,8 @@ shouldOpenExistentialCallArgument(
14121414
paramTy = paramTy->getMetatypeInstanceType();
14131415
}
14141416

1415-
// Look through an inout type on the parameter.
1416-
paramTy = paramTy->getInOutObjectType();
1417+
// Look through an inout and optional types on the parameter.
1418+
paramTy = paramTy->getInOutObjectType()->lookThroughSingleOptionalType();
14171419

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

test/Constraints/opened_existentials.swift

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

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

0 commit comments

Comments
 (0)