In this case we would "devirtualize" the protocol requirement call
by building the AST to model a direct reference to the witness.
Previously this was done by recursively calling typeCheckExpression(),
but the only thing this did was recover the correct substitutions
for the call.
Instead, we can just build the right SubstitutionMap directly.
Unfortunately, while we serialize enough information in the AST
to devirtualize calls at the SIL level, we do not for AST Exprs.
This is because SIL devirtualization builds a reference to the
witness thunk signature, which is an intermediate step between
the protocol requirement and the witness. I get around this by
deriving the substitutions from walking in parallel over the
interface type of the witness, together with the inferred type
of the call expression.