Repository navigation
Implement Fn traits for safe functions of any ABI - #160186
Jules-Bertholet wants to merge 1 commit into
Conversation
|
cc @rust-lang/miri |
|
r? @jackh726 rustbot has assigned @jackh726. Use Why was this reviewer chosen?The reviewer was selected based on:
|
|
Don't you need to generate shims or Happy Things will happen? |
|
I don't think so? The basic tests I added work fine, and Miri doesn't complain. But I don't really know that part of the codebase, am relying on Cunningham's Law |
|
I suggest you check with |
|
Nothing broke… |
|
🤷 Maybe it is fine... |
|
Although the practical ABI for |
|
Probably should make sure the function that calls the |
|
Yeah I'd expect the rust-call / argument (un)tupling to go wrong here as that needs the Rust ABI. Does this actually solve a problem? If not I'd rather update the docs. |
32a4f77 to
2403142
Compare
|
Modified the tests to use a function that I confirmed with Godbolt has a completely different |
With new ABIs like |
|
I guess what happens is that we synthesize a But someone should dig into where that happens. |
|
|
||
| pub fn is_fn_trait_compatible(self) -> bool { | ||
| !self.c_variadic() && self.safety().is_safe() && self.abi() == ExternAbi::Rust | ||
| !self.c_variadic() && self.safety().is_safe() && self.abi().is_fn_trait_compatible() |
There was a problem hiding this comment.
| !self.c_variadic() && self.safety().is_safe() && self.abi().is_fn_trait_compatible() | |
| self.safety().is_safe() && self.abi().is_fn_trait_compatible() |
We could try to remove the !self.c_variadic() condition. But there's not much point, as any actual use of variadics is necessarily unsafe. It would also be a bunch of work, as the trait solver currently assumes no type has more than one impl of each Fn trait.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment has been minimized.
This comment has been minimized.
81bebb9 to
d9d97c4
Compare
|
I like the direction. It is actually a breaking change, since trait Trait {}
impl<F: Fn()> Trait for F {}
impl Trait for extern "C" fn() {} |
|
@bors try |
This comment has been minimized.
This comment has been minimized.
Implement `Fn` traits for safe functions of any ABI
|
@craterbot check |
|
👌 Experiment ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more |
This comment was marked as resolved.
This comment was marked as resolved.
| | ExternAbi::Vectorcall { .. } | ||
| | ExternAbi::SysV64 { .. } | ||
| | ExternAbi::Win64 { .. } => true, | ||
| ExternAbi::RustCall |
There was a problem hiding this comment.
We might need a comment explaining that RustCall implements the Fn traits, but not this way
| ExternAbi::RustCall | |
| // RustCall is callable, but it is used as part of implementing the Fn traits for closures, | |
| // so it can't implement the Fn traits via this specific mechanism. | |
| ExternAbi::RustCall |
There was a problem hiding this comment.
There is actually no reason why we couldn't make rust-call true here. There just also isn't any reason why we should
There was a problem hiding this comment.
This seems like something worth saying explicitly?
| ExternAbi::RustCall | |
| // RustCall is callable, but it is also used as part of implementing the Fn traits for closures. | |
| // We could make it implement the Fn traits directly, but we have no reason to right now. | |
| ExternAbi::RustCall |
There was a problem hiding this comment.
We have a comment at the top of the function saying that we make all internal ABIs false. I think that is enough, "rust-call" is no different from the other two internal ABIs.
Trait selection happens here: included for context, legacy solver impactsFor AsyncFn/Fn in the next solver: https://github.com/rust-lang/rust/blob/c1bf6e13fa5ff2c753a49fd5ef37371c6fed729f/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs#L283 For Fn in the legacy solver: https://github.com/rust-lang/rust/blob/c1bf6e13fa5ff2c753a49fd5ef37371c6fed729f/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs#L582 For AsyncFn in the legacy solver: https://github.com/rust-lang/rust/blob/c1bf6e13fa5ff2c753a49fd5ef37371c6fed729f/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs#L521But the actual shim is created here: rust/compiler/rustc_mir_transform/src/shim.rs Lines 41 to 55 in c1bf6e1 rust/compiler/rustc_mir_transform/src/shim.rs Lines 770 to 1001 in c1bf6e1 |
I don't know what there is to test here? |
|
TIL that rustc_intrinsic function items implement the Fn traits, even if they can't be converted to fn pointers. I guess there's nothing special to test here, then. |
|
Crater rollup in #164148 @craterbot abort |
|
🗑️ Experiment ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more |
|
Does this need an update to the Rust Reference, which currently says:
https://doc.rust-lang.org/stable/reference/types/function-item.html#r-type.fn-item.traits Or do we do those kinds of updates later? |
|
Reference PR: rust-lang/reference#2383 |
This comment has been minimized.
This comment has been minimized.
This brings the behavior of the language in line with the documentation in `library/core/src/primitive_docs.rs`.
cd9fa00 to
4621dfe
Compare
|
This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed. Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers. |
View all comments
This brings the behavior of the language in line with its documentation:
rust/library/core/src/primitive_docs.rs
Lines 1930 to 1931 in 1a833e1
ABIs that are not callable, or that are internal implementation details, are excluded.
Reference PR: rust-lang/reference#2383
@rustbot label T-lang needs-fcp A-ABI A-extern-fn I-lang-nominated