question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

extern macro!(ABI) fn

See original GitHub issue

Proposal

Summary and problem statement

Today, there are cases where the ABI in extern ABI should be selected based on static properties, such as the target architecture.

I propose we fix this by making extern macro!(ABI) fn work. This way, people will not have to write duplicate definitions under #[cfg(...)] attributes to get the same effect.

Motivation, use-cases, and solution sketches

Today in Rust, there are cases where the same function definition can work for distinct ABI’s depending on target. But you cannot merge them into one definition; you have to use separate function items with distinct #[cfg(...)] attributes.

For example, this comment describes a scenario where this leads to code duplication (at the level of signature and body) between an extern "thiscall" fn on i686-windows and an extern "fastcall" fn on x86_64-windows.

If we made the ABI in extern ABI a macro expansion position, then the above would be easy to resolve: someone who has literally the same definition for both cases would write an appropriate macro to expand the right way. (I have sketched an idea like extern cfg_match!(target_arch, "x86" => "thiscall", "x86_64" => "fastcall") fn foo() {}, but this initiative is not about what specific macro to use; it is about enabling macros to be used at all.

Links and related work

Inspired by suggestion from @DrMeepster

backlog bonanza discussion

Initial people involved

  • Owner, if known: pnkfelix
  • Liaison

What happens now?

This issue is part of the lang-team initiative process. Once this issue is filed, a Zulip topic will be opened for discussion, and the lang-team will review open proposals in its weekly triage meetings. You should receive feedback within a week or two.

This issue is not meant to be used for technical discussion. There is a Zulip stream for that. Use this issue to leave procedural comments, such as volunteering to review, indicating that you second the proposal (or third, etc), or raising a concern that you would like to be addressed.

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Reactions:1
  • Comments:15 (11 by maintainers)

github_iconTop GitHub Comments

1reaction
nikomatsakiscommented, Mar 22, 2022

We discussed this in today’s @rust-lang/lang meeting. The consensus of the meeting was actually the reverse of the opinion described here – we felt we did NOT want to add this feature. Therefore, I am going to withdraw my second and adjust the labels.

@rustbot label -final-comment-period -to-announce

Many of us felt initially that we generally want to allow macros everywhere we can, but @cramertj raised a key objection that, in this instance, it was a bit unclear that this macro ought to expand to an ABI string in particular. Given that the ABI part of an extern fn is optional, one could imagine the f!() in extern f!() might expand to a function or to other modifiers (e.g., unsafe). We might also add other sorts of modifiers that go before the fn that would make for extra confusion here.

That fact, combined with general agreement that we should make the 32-bit windows ABIs (e.g., thiscall and friends) “fallback” to the standard ABI in 64-bit case (matching the behavior of MSVC, as I understand it), made this particular placement of macros seem like it could cause more confusion than it would bring benefit.

Another point against this proposal was that it would be quite easy to write a procedural macro that “rewrites” the ABI of functions, so that e.g.

#[rewrite_win_abi]
extern "stdcall" fn foo() { }

could look at the target and adjust the ABI accordingly.

1reaction
pnkfelixcommented, Mar 19, 2022

also, @DrMeepster, I didn’t mean to step on any toes. As I said, I was inspired by your comment to take action here, but I did not know that you had already started drafting a formal RFC.

The language and compiler team have both been working on identifying lighterweight methodologies that have smaller stages with explicit intermediate goals. @nikomatsakis and I both agreed that this would be a language team issue, but not one that requires a ton of effort.

In particular I am thinking we can use the language team initiative process and get started on a prototype implementation, while the RFC process moves forward in parallel.

Read more comments on GitHub >

github_iconTop Results From Across the Web

External blocks - The Rust Reference
This allows macros to consume the syntax and make use of the unsafe ... extern "Rust" -- The default ABI when you write...
Read more >
WilliamVenner/fn_abi: A proc attribute macro that sets ... - GitHub
A proc attribute macro that sets the ABI/calling convention for the attributed function ... #[macro_use] extern crate fn_abi; #[abi("fastcall")] extern fn ...
Read more >
External blocks - The Rust Reference
External blocks form the basis for Rust's foreign function interface. ... extern "Rust" -- The default ABI when you write a normal fn...
Read more >
Calling a library function with rust-abi - Stack Overflow
I know Rust has non-stable ABI, but I use both of these crates in one ... link = "static")] extern "Rust" { fn...
Read more >
Foreign Function Interface
extern crate libc; use libc::size_t; #[link(name = "snappy")] extern { fn ... signatures in a foreign library, in this case with the platform's...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found