Previously, if bad would call good through a shim, but generation of good_shim fails (for example, because the shim would require an unsupported cast like *mut T -> &[T]), then bad would still be rewritten to call the nonexistent good_shim function. With this branch, we instead mark good as failed so that good_shim is no longer needed (shims are only needed for calling non-failed functions) and retry the entire rewriting pass. Marking a function as failed may require shims to be generated for its callees, but eventually this process will converge once all the functions where shims can't be generated have been marked as failed.
Previously, if
bad
would callgood
through a shim, but generation ofgood_shim
fails (for example, because the shim would require an unsupported cast like*mut T -> &[T]
), thenbad
would still be rewritten to call the nonexistentgood_shim
function. With this branch, we instead markgood
as failed so thatgood_shim
is no longer needed (shims are only needed for calling non-failed functions) and retry the entire rewriting pass. Marking a function as failed may require shims to be generated for its callees, but eventually this process will converge once all the functions where shims can't be generated have been marked as failed.