about summary refs log tree commit diff
path: root/compiler/rustc_mir_transform/src/coverage/debug.rs
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-05-28 16:49:52 +0000
committerbors <bors@rust-lang.org>2022-05-28 16:49:52 +0000
commit116201eefebcf45074ae232377e7145f5fbb704b (patch)
treea5981e4e7c67e1ab311782da7926c135f5b9645a /compiler/rustc_mir_transform/src/coverage/debug.rs
parent4f39fb1f34d4bd25d9ce96afe7b2d109f073e286 (diff)
parent78a83b0d5fb90d3fa9418592282b55e9f2e496be (diff)
downloadrust-116201eefebcf45074ae232377e7145f5fbb704b.tar.gz
rust-116201eefebcf45074ae232377e7145f5fbb704b.zip
Auto merge of #97461 - eddyb:proc-macro-less-payload, r=bjorn3
proc_macro: don't pass a client-side function pointer through the server.

Before this PR, `proc_macro::bridge::Client<F>` contained both:
* the C ABI entry-point `run`, that the server can call to start the client
* some "payload" `f: F` passed to that entry-point
  * in practice, this was always a (client-side Rust ABI) `fn` pointer to the actual function the proc macro author wrote, i.e. `#[proc_macro] fn foo(input: TokenStream) -> TokenStream`

In other words, the client was passing one of its (Rust) `fn` pointers to the server, which was passing it back to the client, for the client to call (see later below for why that was ever needed).

I was inspired by `@nnethercote's` attempt to remove the `get_handle_counters` field from `Client` (see https://github.com/rust-lang/rust/pull/97004#issuecomment-1139273301), which combined with removing the `f` ("payload") field, could theoretically allow for a `#[repr(transparent)]` `Client` that mostly just newtypes the C ABI entry-point `fn` pointer <sub>(and in the context of e.g. wasm isolation, that's *all* you want, since you can reason about it from outside the wasm VM, as just a 32-bit "function table index", that you can pass to the wasm VM to call that function)</sub>.

<hr/>

So this PR removes that "payload". But it's not a simple refactor: the reason the field existed in the first place is because monomorphizing over a function type doesn't let you call the function without having a value of that type, because function types don't implement anything like `Default`, i.e.:
```rust
extern "C" fn ffi_wrapper<A, R, F: Fn(A) -> R>(arg: A) -> R {
    let f: F = ???; // no way to get a value of `F`
    f(arg)
}
```
That could be solved with something like this, if it was allowed:
```rust
extern "C" fn ffi_wrapper<
    A, R,
    F: Fn(A) -> R,
    const f: F // not allowed because the type is a generic param
>(arg: A) -> R {
    f(arg)
}
```

Instead, this PR contains a workaround in `proc_macro::bridge::selfless_reify` (see its module-level comment for more details) that can provide something similar to the `ffi_wrapper` example above, but limited to `F` being `Copy` and ZST (and requiring an `F` value to prove the caller actually can create values of `F` and it's not uninhabited or some other unsound situation).

<hr/>

Hopefully this time we don't have a performance regression, and this has a chance to land.

cc `@mystor` `@bjorn3`
Diffstat (limited to 'compiler/rustc_mir_transform/src/coverage/debug.rs')
0 files changed, 0 insertions, 0 deletions