Skip to content

Implement Fn traits for safe functions of any ABI - #160186

Merged
rust-bors[bot] merged 1 commit into
rust-lang:mainfrom
Jules-Bertholet:fn-traits-any-abi
Nov 1, 2026
Merged

rust-bors[bot] merged 1 commit into
rust-lang:mainfrom
Jules-Bertholet:fn-traits-any-abi

Conversation

@Jules-Bertholet

@Jules-Bertholet Jules-Bertholet commented Jul 29, 2026 •

Copy link
Copy Markdown
Contributor

View all comments

This brings the behavior of the language in line with its documentation:

/// In addition, all *safe* function pointers implement [`Fn`], [`FnMut`], and [`FnOnce`], because
/// these traits are specially known to the compiler.

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

@rustbot

rustbot commented Jul 29, 2026

Copy link
Copy Markdown
Collaborator

miri is developed in its own repository. If the Miri part of this change can be broken out, consider making this change to rust-lang/miri instead. However, if Miri needs adjusting for rustc changes, just ignore this message.

cc @rust-lang/miri

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. WG-trait-system-refactor The Rustc Trait System Refactor Initiative (-Znext-solver) labels Jul 29, 2026
@rustbot

rustbot commented Jul 29, 2026

Copy link
Copy Markdown
Collaborator

r? @jackh726

rustbot has assigned @jackh726.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: compiler
  • compiler expanded to 74 candidates
  • Random selection from 16 candidates

@rustbot rustbot added A-ABI Area: Concerning the application binary interface (ABI) A-extern-fn Area: `extern` functions needs-fcp This change is insta-stable, or significant enough to need a team FCP to proceed. T-lang Relevant to the language team labels Jul 29, 2026
@ChayimFriedman2

Copy link
Copy Markdown
Contributor

Don't you need to generate shims or Happy Things will happen?

@Jules-Bertholet

Copy link
Copy Markdown
Contributor Author

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

@ChayimFriedman2

Copy link
Copy Markdown
Contributor

I suggest you check with &dyn Fn(), things are more likely to break there.

@Jules-Bertholet

Copy link
Copy Markdown
Contributor Author

Nothing broke…

@ChayimFriedman2

Copy link
Copy Markdown
Contributor

🤷 Maybe it is fine...

@ChayimFriedman2

Copy link
Copy Markdown
Contributor

Although the practical ABI for &isize and isize is identical for C and Rust, so it will compile fine and I don't know if Miri can detect a mismatch - maybe try something like [usize; 2], that appears to have a different ABI between Rust and C?

@ds84182

ds84182 commented Jul 30, 2026

Copy link
Copy Markdown

Probably should make sure the function that calls the &dyn Fn is not inlined.

@RalfJung

Copy link
Copy Markdown
Member

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.

@Jules-Bertholet

Jules-Bertholet commented Jul 30, 2026 •

Copy link
Copy Markdown
Contributor Author

Modified the tests to use a function that I confirmed with Godbolt has a completely different "Rust" vs. "C" ABI. And everything still works

@Jules-Bertholet

Copy link
Copy Markdown
Contributor Author

Does this actually solve a problem?

With new ABIs like "tail", extern is not just for FFI anymore.

@RalfJung

Copy link
Copy Markdown
Member

I guess what happens is that we synthesize a call/call_once body for the traits when implementing them for a fn item, which discards the self argument, and which in this case also serves as an ABI adapter?

But someone should dig into where that happens.

Comment thread compiler/rustc_abi/src/extern_abi.rs Resolved

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()

@Jules-Bertholet Jules-Bertholet Jul 30, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
!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.

View changes since the review

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. I am pretty happy with this PR right now and I would have been pretty annoyed if it tried to bundle that change.

@Jules-Bertholet

This comment was marked as outdated.

@rustbot rustbot assigned chenyukang and unassigned jackh726 Aug 15, 2026
@chenyukang

This comment was marked as outdated.

@rust-rfcbot rust-rfcbot removed the proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. label Oct 21, 2026
@rust-rfcbot

Copy link
Copy Markdown
Collaborator

🔔 This is now entering its final comment period, as per the review above. 🔔

@traviscross traviscross removed I-lang-nominated Nominated for discussion during a lang team meeting. P-lang-drag-1 Lang team prioritization drag level 1. https://rust-lang.zulipchat.com/#narrow/channel/410516-t-lang labels Oct 21, 2026
@scottmcm

Copy link
Copy Markdown
Member

The title made me ponder potential future things like extern "naked" fn, but that would fit in the "not callable" exception, so this seems straight-forwardly-good.

@rfcbot reviewed

@tgross35

Copy link
Copy Markdown
Member

The title made me ponder potential future things like extern "naked" fn, but that would fit in the "not callable" exception, so this seems straight-forwardly-good.

(unsafe extern "custom"? That's coming in 1.100 #158504)

@rust-rfcbot rust-rfcbot added finished-final-comment-period The final comment period is finished for this PR / Issue. to-announce Announce this issue on triage meeting and removed final-comment-period In the final comment period and will be merged soon unless new substantive objections are raised. labels Oct 31, 2026
@rust-rfcbot

Copy link
Copy Markdown
Collaborator

The final comment period, with a disposition to merge, as per the review above, is now complete.

As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed.

@workingjubilee workingjubilee left a comment •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have this weird "I feel like we want more tests" feeling, but we can always benefit from some fuzzing, so that's not different from anything else in the compiler. This seems good. It does strengthen the promise you make inside unsafe extern with safe from "yeah, safe, anyone deliberately calling this is okay" to "No, really, you can call this as an anonymized closure three crates over, hope you were right that it's fine to call this context-free!" but that's consistent with unsafe elsewhere: that code has got some mighty fine print.

View changes since this review

@workingjubilee

Copy link
Copy Markdown
Member

I haven't seen any activity from the randomly-assigned reviewer on this PR, and it has received quite a bit of scrutiny, including now my own.

r? @workingjubilee
@bors r=workingjubilee

@rust-bors

rust-bors Bot commented Oct 31, 2026

Copy link
Copy Markdown
Contributor

📋 This PR cannot be approved because it currently has the following label: needs-reference-pr.

@rustbot rustbot assigned workingjubilee and unassigned TaKO8Ki Oct 31, 2026
@Jules-Bertholet

Copy link
Copy Markdown
Contributor Author

Has reference PR: rust-lang/reference#2383

@workingjubilee workingjubilee removed the needs-reference-pr This language change needs an approved Reference PR to proceed. label Oct 31, 2026
@workingjubilee

workingjubilee commented Nov 1, 2026 •

Copy link
Copy Markdown
Member

This has unanimous approval by lang, FCP has closed, and the reference PR was presumably reviewed (as it was certainly viewable) during discussion of this feature. In the interest of avoiding a "Who's on first?" skit, I'm gonna r+ this again but if I should've waited until the ref PR was formally merged or something please let me know.

@bors r+

@rust-bors

rust-bors Bot commented Nov 1, 2026

Copy link
Copy Markdown
Contributor

📌 Commit 4621dfe has been approved by workingjubilee

It is now in the queue for this repository.

@rust-bors rust-bors Bot added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Nov 1, 2026
rust-bors Bot pushed a commit that referenced this pull request Nov 1, 2026
Rollup of 10 pull requests

Successful merges:

 - #160186 (Implement `Fn` traits for safe functions of any ABI)
 - #160370 (rustdoc: notable trait badge and popover enhancements)
 - #165077 (Fix alloctests for panic=abort)
 - #163623 (Make docblock `<code>` elements inline so they behave better)
 - #163833 (Fix RISC-V inline ASM `clobber_abi` when extra target features are enabled)
 - #165067 (cg_llvm: Use an invariant lifetime brand for LLVM modules )
 - #165227 (Respect `--color=never` when printing `--explain` output to the terminal)
 - #165254 (Cleanup `rustdoc-html` tests)
 - #165258 (impl Eq for AllocRange)
 - #165259 (rustc-dev-guide subtree update)
@rust-bors
rust-bors Bot merged commit dd9fc74 into rust-lang:main Nov 1, 2026
14 checks passed
rust-bors Bot pushed a commit that referenced this pull request Nov 1, 2026
Rollup merge of #160186 - Jules-Bertholet:fn-traits-any-abi, r=workingjubilee

Implement `Fn` traits for safe functions of any ABI

This brings the behavior of the language in line with its documentation:

https://github.com/rust-lang/rust/blob/1a833e16546c2eb012758ddd499964fd8afee29e/library/core/src/primitive_docs.rs#L1930-L1931

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
@rustbot rustbot added this to the 1.101.0 milestone Nov 1, 2026
@Jules-Bertholet
Jules-Bertholet deleted the fn-traits-any-abi branch November 1, 2026 23:48
eduardorittner pushed a commit to eduardorittner/miri that referenced this pull request Nov 2, 2026
Rollup of 10 pull requests

Successful merges:

 - rust-lang/rust#160186 (Implement `Fn` traits for safe functions of any ABI)
 - rust-lang/rust#160370 (rustdoc: notable trait badge and popover enhancements)
 - rust-lang/rust#165077 (Fix alloctests for panic=abort)
 - rust-lang/rust#163623 (Make docblock `<code>` elements inline so they behave better)
 - rust-lang/rust#163833 (Fix RISC-V inline ASM `clobber_abi` when extra target features are enabled)
 - rust-lang/rust#165067 (cg_llvm: Use an invariant lifetime brand for LLVM modules )
 - rust-lang/rust#165227 (Respect `--color=never` when printing `--explain` output to the terminal)
 - rust-lang/rust#165254 (Cleanup `rustdoc-html` tests)
 - rust-lang/rust#165258 (impl Eq for AllocRange)
 - rust-lang/rust#165259 (rustc-dev-guide subtree update)
DaniPopes pushed a commit to DaniPopes/rustc_codegen_cranelift that referenced this pull request Nov 4, 2026
Rollup of 10 pull requests

Successful merges:

 - rust-lang/rust#160186 (Implement `Fn` traits for safe functions of any ABI)
 - rust-lang/rust#160370 (rustdoc: notable trait badge and popover enhancements)
 - rust-lang/rust#165077 (Fix alloctests for panic=abort)
 - rust-lang/rust#163623 (Make docblock `<code>` elements inline so they behave better)
 - rust-lang/rust#163833 (Fix RISC-V inline ASM `clobber_abi` when extra target features are enabled)
 - rust-lang/rust#165067 (cg_llvm: Use an invariant lifetime brand for LLVM modules )
 - rust-lang/rust#165227 (Respect `--color=never` when printing `--explain` output to the terminal)
 - rust-lang/rust#165254 (Cleanup `rustdoc-html` tests)
 - rust-lang/rust#165258 (impl Eq for AllocRange)
 - rust-lang/rust#165259 (rustc-dev-guide subtree update)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-ABI Area: Concerning the application binary interface (ABI) A-extern-fn Area: `extern` functions disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. finished-final-comment-period The final comment period is finished for this PR / Issue. I-lang-radar Items that are on lang's radar and will need eventual work or consideration. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-lang Relevant to the language team to-announce Announce this issue on triage meeting WG-trait-system-refactor The Rustc Trait System Refactor Initiative (-Znext-solver)

Projects

None yet

Development

Successfully merging this pull request may close these issues.