For COW support in SIL it's required to "finalize" array literals.
_finalizeUninitializedArray is a compiler known stdlib function which is called after all elements of an array literal are stored.
This runtime function marks the array literal as finished.
%uninitialized_result_tuple = apply %_allocateUninitializedArray(%count)
%mutable_array = tuple_extract %uninitialized_result_tuple, 0
%elem_base_address = tuple_extract %uninitialized_result_tuple, 1
...
store %elem_0 to %elem_addr_0
store %elem_1 to %elem_addr_1
...
%final_array = apply %_finalizeUninitializedArray(%mutable_array)
In this commit _finalizeUninitializedArray is still a no-op because the COW support is not used in the Array implementation yet.
This method was only ever called with non-generic witnesses,
because it assumed the substitutions stored in the witness
would always be derived from the conforming type.
There were two cases where this wasn't the case though:
1) If the witness is itself generic
2) The witness was defined in a protocol extension and the
conforming type is a non-final class
In all cases, the SubstitutionMap stored in a Witness always
uses the 'synthetic environment'. In some cases, the
'synthetic environment' is the generic environment of the
witness. But in 1) and 2) it was different. While 1) never
occurred because we never used this method to look up
witnesses for generic requirements, 2) could happen.
The condition we want to test for emitting a downcast is isRequired(),
not isInheritable(). The latter is only true for convenience
initializers.
The other fix is that we actually have to emit a class_method
dispatch here to support class hierarchies conforming to literal
protocols.