- 
                Notifications
    You must be signed in to change notification settings 
- Fork 13.9k
c-variadic: allow c-variadic inherent and trait methods #146434
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
c-variadic: allow c-variadic inherent and trait methods #146434
Conversation
but a C-variadic method makes a trait dyn-incompatible. That is because methods from dyn traits, when cast to a function pointer, create a shim. That shim can't really forward the c-variadic arguments.
| 
 | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could we have some tests in relevant files for functions which are neither extern "C" nor Rust functions, to demonstrate how the principles here extend (or don't)?
In particular I'd like them to cover an ABI which in principle doesn't support varargs and an ABI which in principle does.
1b99d56    to
    321a76b      
    Compare
  
    | Sure, I added tests for these calling conventions in various contexts: unsafe extern "cdecl" fn cdecl_free(_: ...) {}
unsafe extern "cdecl-unwind" fn cdecl_unwind_free(_: ...) {}
unsafe extern "stdcall" fn stdcall_free(_: ...) {}
unsafe extern "stdcall-unwind" fn stdcall_unwind_free(_: ...) {}
unsafe extern "thiscall" fn thiscall_free(_: ...) {}
unsafe extern "thiscall-unwind" fn thiscall_unwind_free(_: ...) {}@rustbot ready | 
| Shims are also generated when  | 
| Correct, but  | 
| Oh right. Good. | 
| Will try to get to this on Monday. You will probably see many more questions in the shape of "what about  | 
| So we parse  And we didn't encounter any shim-generation in codegen for any sort of inherent methods or trait methods that aren't dynamic? I think I'm feeling positive about this but want to sleep on it and review the codegen shims a bit maybe. | 
| No, I think only this is relevant pub enum ReifyReason {
    /// The `ReifyShim` was created to produce a function pointer. This happens when:
    /// * A vtable entry is directly converted to a function call (e.g. creating a fn ptr from a
    ///   method on a `dyn` object).
    /// * A function with `#[track_caller]` is converted to a function pointer
    /// * If KCFI is enabled, creating a function pointer from a method on a dyn-compatible trait.
    /// This includes the case of converting `::call`-like methods on closure-likes to function
    /// pointers.
    FnPtr,
    /// This `ReifyShim` was created to populate a vtable. Currently, this happens when a
    /// `#[track_caller]` mismatch occurs between the implementation of a method and the method.
    /// This includes the case of `::call`-like methods in closure-likes' vtables.
    Vtable,
}
 | 
|     /// * If KCFI is enabled, creating a function pointer from a method on a dyn-compatible trait.
    /// This includes the case of converting `::call`-like methods on closure-likes to function
    /// pointers.
Thanks for pulling that out, that was one of my big questions. Okay, so that happens when we decay a "closure-like", so a rust/compiler/rustc_middle/src/ty/util.rs Line 604 in 5d1b897 
 I am somewhat worried about that, because I think this might actually be something that "normal" closure decay is at risk of incurring. But closures shouldn't have varargs, of course, since they're  Or maybe I'm wrong? I hope I'm wrong in a direction that still aligns with not caring about these possible interactions, at least. Either way, since it's an interaction between two unstable things, I am willing to defer having a decisive answer to this until later. This should enable more code only, so: @bors r+ rollup | 
| Also I found out after a brief chat that apparently KCFI does get used in the case of varargs! It still shouldn't matter for the other reasons, but, you know, | 
…hods, r=workingjubilee c-variadic: allow c-variadic inherent and trait methods tracking issue: rust-lang#44930 Continuing the work of rust-lang#146342, allow inherent and trait methods to be c-variadic. However, a trait that contains a c-variadic method is no longer dyn-compatible. There is, presumably, some way to make c-variadic methods dyn-compatible. However currently, we don't have confidence that it'll work reliably: when methods from a `dyn` object are cast to a function pointer, a `ReifyShim` is created. If that shim is c-variadic, it would need to forward the C variable argument list. That does appear to work, because the `va_list` is not represented in MIR at all in this case, so the registers from the call site are untouched by the shim and can be read by the actual implementation. That just does not seem like a solid implementation. Also, intuitively, why would c-variadic function, primarily needed for FFI, need to be used with `dyn` objects at all? We can revisit this limitation if a need arises. r? `@workingjubilee`
…kingjubilee c-variadic: allow c-variadic inherent and trait methods tracking issue: #44930 Continuing the work of #146342, allow inherent and trait methods to be c-variadic. However, a trait that contains a c-variadic method is no longer dyn-compatible. There is, presumably, some way to make c-variadic methods dyn-compatible. However currently, we don't have confidence that it'll work reliably: when methods from a `dyn` object are cast to a function pointer, a `ReifyShim` is created. If that shim is c-variadic, it would need to forward the C variable argument list. That does appear to work, because the `va_list` is not represented in MIR at all in this case, so the registers from the call site are untouched by the shim and can be read by the actual implementation. That just does not seem like a solid implementation. Also, intuitively, why would c-variadic function, primarily needed for FFI, need to be used with `dyn` objects at all? We can revisit this limitation if a need arises. r? `@workingjubilee`
| 💔 Test failed - checks-actions | 
| It looks like the  | 
| @bors retry | 
Rollup of 6 pull requests Successful merges: - #146434 (c-variadic: allow c-variadic inherent and trait methods) - #146487 (Improve `core::num` coverage) - #146597 (Add span for struct tail recursion limit error) - #146622 (Add regression test for issue #91831) - #146717 (Clean up universe evaluation during type test evaluation) - #146723 (Include patch in release notes) r? `@ghost` `@rustbot` modify labels: rollup
Rollup merge of #146434 - folkertdev:c-variadic-inherent-methods, r=workingjubilee c-variadic: allow c-variadic inherent and trait methods tracking issue: #44930 Continuing the work of #146342, allow inherent and trait methods to be c-variadic. However, a trait that contains a c-variadic method is no longer dyn-compatible. There is, presumably, some way to make c-variadic methods dyn-compatible. However currently, we don't have confidence that it'll work reliably: when methods from a `dyn` object are cast to a function pointer, a `ReifyShim` is created. If that shim is c-variadic, it would need to forward the C variable argument list. That does appear to work, because the `va_list` is not represented in MIR at all in this case, so the registers from the call site are untouched by the shim and can be read by the actual implementation. That just does not seem like a solid implementation. Also, intuitively, why would c-variadic function, primarily needed for FFI, need to be used with `dyn` objects at all? We can revisit this limitation if a need arises. r? `@workingjubilee`
tracking issue: #44930
Continuing the work of #146342, allow inherent and trait methods to be c-variadic. However, a trait that contains a c-variadic method is no longer dyn-compatible.
There is, presumably, some way to make c-variadic methods dyn-compatible. However currently, we don't have confidence that it'll work reliably: when methods from a
dynobject are cast to a function pointer, aReifyShimis created. If that shim is c-variadic, it would need to forward the C variable argument list.That does appear to work, because the
va_listis not represented in MIR at all in this case, so the registers from the call site are untouched by the shim and can be read by the actual implementation. That just does not seem like a solid implementation.Also, intuitively, why would c-variadic function, primarily needed for FFI, need to be used with
dynobjects at all? We can revisit this limitation if a need arises.r? @workingjubilee