Commits

Slava Pestov committed 60f437abe12
IRGen: Change witness_method calling convention to take a witness table This is another incremental step toward protocol resilience. To support resiliently adding requirements with default implementations, we need to emit the witness thunk for each default requirement once, and share it between conformances. However, the body of the witness thunk can call witness methods from the conformance of <Self : P>. Formerly, witness thunks were only emitted with a concrete Self type, so any calls were resolved statically. Now that Self can be abstract in a witness thunk signature, we have to pass in the witness table and do the necessary gymnastics on both sides of the call. At the call site, the witness table is either abstract, concrete, or undefined, as follows: - If the unsubstituted Self type is concrete in the witness method signature, no witness table is necessary; this is the case of a concrete (non-default) witness thunk. - If the unsubstituted Self type is abstract and the substituted Self type is concrete, the witness table is accessed via direct reference. - If the unsubstituted Self type is abstract and the substituted Self type is also abstract, the witness table comes from type metadata that was passed in to the function where the call is taking place. Inside the body of the witness method thunk, we only bind the witness table if Self is an abstract type; this rules out the first case above, where the witness table is not needed and cannot be provided by the caller. The result of a SIL witness_method instruction now lowers as an explosion containing two values, the function pointer itself and the witness table. Similarly, partial application thunks now grab the witness table and package it up in the context. Special care is taken to support function_ref + apply and function_ref + partial_apply of @convention(witness_method) callees; here, we can hit the case where we don't know the original conformance because the callee is concrete, in which case we just pass in a null pointer as the witness table. Witness thunks with an abstract Self currently only work for protocols without any associated type requirements; to support those, we need to be able to fulfill associated type metadata from the witness table for the <Self : P> conformance. This will be addressed as part of @rjmccall's calling convention work. Also I didn't make any attempt to support this for @objc protocols that do not have a witness table. In this case, the extra parameter is not necessary since we can perform dynamic dispatch on the 'self' value to call requirements; however, @objc protocols will not support default implementations, at least not in the near-term.