SILGen: Implement function conversions involving opened existentials

Suppose we have a protocol requirement returning Self:

protocol Clonable {
  func clone() -> Self
}

If we have a value 'x' of existential type 'Clonable',
the partial application 'x.clone' has formal type
'() -> Clonable'. However the actual type of the
method substitutes in an "opened" existential type
for 'Self'.

In order to implement the partial application we must
wrap the method in a thunk which 'erases' the opened
existential, so the thunk has type

<T : Clonable> (() -> T) -> () -> Clonable

The thunk is called with a substitution replacing 'T'
with the opened existential type.

Fixes <rdar://problem/21391055>.
This commit is contained in:
Slava Pestov
2016-12-28 11:14:17 -05:00
parent 4d349759ab
commit a72eba1119
5 changed files with 353 additions and 39 deletions

View File

@@ -1535,7 +1535,9 @@ public:
CanSILFunctionType buildThunkType(ManagedValue fn,
CanSILFunctionType expectedType,
CanSILFunctionType &substFnType,
SmallVectorImpl<Substitution> &subs);
GenericEnvironment *&genericEnv,
SubstitutionMap &contextSubMap,
SubstitutionMap &interfaceSubMap);
//===--------------------------------------------------------------------===//
// Declarations