Closed spernsteiner closed 1 year ago
This code uses the same cast-generation logic as mir_op
, so whatever's supported there will also be supported here. For *mut T -> &[T]
in particular, that cast is not supported, so shim generation will fail (as in #950).
Can I take a little bit more of a look at this after it's rebased?
Implements generation of unsafe shims when calling rewritten code from non-rewritten code. Given this input:
The tool now produces output like this:
Here, the tool has rewritten
good
to change its argument type from*const i32
to&i32
, but analysis failed onbad
, so the tool can't apply corresponding rewrites in the body ofbad
. Previously, this would cause a type error:bad
would continue passing*const i32
togood
, butgood
now expects&i32
. Now, the tool generates a helper functiongood_shim
, which wrapsgood
but keeps the original signature from before rewriting, and rewritesbad
to callgood_shim
instead ofgood
, resulting in a well-typed program. Renaming the callee inbad
doesn't require any analysis results, so it works even though analysis failed onbad
.Implementation strategy: for each failed (non-rewritten) function, we walk over the HIR and look for
ExprKind::Path
s andExprKind::MethodCall
s that resolve to rewritten functions. For each one, we generate a rewrite that appends_shim
to the end of the function name and record theDefId
of the callee. Then, for each callee we encountered, we generate a rewrite that inserts the shim function definition after the definition of the callee. The shim function has to cast arguments and return values between the original unsafe types and the safe types produced by rewriting; for this, we reuse the cast-generation machinery fromrewrite::expr::mir_op
andrewrite::expr::convert
.This is a counterpart to #936: that one handles calls from rewritten code into non-rewritten code, and this one handles the reverse.
This PR also marks failed
fn
s asFIXED
and thus doesn't propagate analysis failures to callers.