Skip to content
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

extern is replaced with extern "C" for wasm extern functions #2908

Closed
gnzlbg opened this issue Aug 10, 2018 · 9 comments · Fixed by #4293
Closed

extern is replaced with extern "C" for wasm extern functions #2908

gnzlbg opened this issue Aug 10, 2018 · 9 comments · Fixed by #4293
Labels
bug Panic, non-idempotency, invalid code, etc.
Milestone

Comments

@gnzlbg
Copy link
Contributor

gnzlbg commented Aug 10, 2018

I am getting this diff with rustfmt in stdsimd, is this intended (@nrc , @topecongiro ) / correct (cc @alexcrichton) ?

 #[wasm_bindgen(module = "child_process", version = "*")]
-extern {
+extern "C" {
     #[wasm_bindgen(js_name = execSync)]
     fn exec_sync(cmd: &str) -> Buffer;
 }
@alexcrichton
Copy link
Member

This was briefly discussed at rustwasm/wasm-bindgen#422, and while wonky it was seen as "we don't have much choice!"

@gnzlbg
Copy link
Contributor Author

gnzlbg commented Aug 10, 2018

The simd128 PR in stdsimd contains these changes and the build is green, so 👍

@gnzlbg gnzlbg closed this as completed Aug 10, 2018
@gnzlbg gnzlbg reopened this Sep 12, 2019
@gnzlbg
Copy link
Contributor Author

gnzlbg commented Sep 12, 2019

I ran into this again now that rustfmt is able to format most of the libc crate and I'm not sure if I follow the rationale given in that issue:

extern { } is a synonym for extern "C" { }.

However, #[wasm_bindgen] extern { } is not the same as extern { }. It is actually more similar to wasm_bindgen! { extern { } }, which rustfmt should probably not format to wasm_bindgen! { extern "C" { } } because that would possibly break the macro expansion.

@topecongiro I think this is just an instance of rustfmt trying to format code inside a macro, and ending up breaking the macro. A procedural macro is still a macro.

@topecongiro topecongiro added the bug Panic, non-idempotency, invalid code, etc. label Jun 7, 2020
@topecongiro topecongiro added this to the 2.0.0 milestone Jun 7, 2020
@calebcartwright
Copy link
Member

@topecongiro - what are we thinking in terms of resolving this one? do we want to allow an implicit abi on foreign item mods even when force_explicit_abi is true (which is the default) for mods that have the wasm_bindgen attribute? If so, should rustfmt do this by default/always or would we want an additional config option to let users control whether or not rustfmt inserts an explicit "C" abi;

I've yet to do anything with wasm, but my sense from these threads is that the insertion of the explicit abi is undesirable and a bit puzzling so I'm guessing users don't actually want or need to be able to have the explicit abi inserted.

@topecongiro
Copy link
Contributor

I've been thinking about it lately that when using the default configuration, rustfmt should not modify code that could lead to semantic changes. It is hard to do this correctly because of the proc macro, but we should try whenever possible.

With that mind, regarding this issue, I'd like to change the default value of force_explicit_abi to false and include a note in the documentation about the potential issue when setting it to true.

@calebcartwright
Copy link
Member

I'd like to change the default value of force_explicit_abi to false

The style guide prescribes being explicit which I presume is why rustfmt defaults to true. Do we need to update the style guide as well?

https://github.com/rust-dev-tools/fmt-rfcs/blob/f4fb7b84eacb8161905157b761dd8002b0eed044/guide/items.md#extern-items

When writing extern items (such as extern "C" fn), always be explicit about the ABI. For example, write extern "C" fn foo ..., not extern fn foo ..., or extern "C" { ... }.

@topecongiro
Copy link
Contributor

Yes, that's right. Maybe tone it down a bit and change always be explicit about the ABI. to prefer to be explicit about the API?

@calebcartwright
Copy link
Member

calebcartwright commented Jun 27, 2020

Maybe tone it down a bit and change always be explicit about the ABI. to prefer to be explicit about the API?

Even if we softened the language a bit, I still feel like we'd end up in a scenario where rustfmt's default wouldn't follow the prescribed style guide approach for ABIs. I also have some concerns that changing the default to not be explicit across the board to address the wasm use case may negatively impact the other cases where the conversion to explicit ABI is preferred (rust-lang/style-team#52) 🤔

I see a few options:

  1. As of rustfmt 1.4.13, rustfmt supports formatting arbitrary ABIs, so a different explicit ABI like "wasm-bindgen" could be used as mentioned in Should extern "C" { ... } be disallowed? rustwasm/wasm-bindgen#422 (comment)
  2. Update rustfmt's default and the corresponding style guide language as discussed above, but also mention that rustfmt won't do so without overriding the default configuration
  3. Enhance the extern formatting logic in rustfmt to not convert from implicit to explicit when doing so could fail to be semantics preserving

I'm going to try to set aside some time in the next few days to work on this (assuming on one beats me to it), and would be happy to open PRs for options 2 and 3 for consideration. However, let me know if you definitely want to just press on with option 2 @topecongiro

@topecongiro
Copy link
Contributor

@calebcartwright I agree that in most scenarios, it is desirable to normalize to explicit abi. As I said, I would like to be careful about adding/removing non-whitespace tokens. In this particular case, however, as you mentioned in option 1, users can work around this issue by adding an arbitrary abi by themselves; so just implementing the option 3 may be enough. Thank you for your insight.

I'm going to try to set aside some time in the next few days to work on this (assuming on one beats me to it), and would be happy to open PRs for options 2 and 3 for consideration.

Amazing ❤️ Note that the semantic change of the code is not limited to wasm-bindgen but can happen in any kind of proc macros. So I think it is safer not to add an explicit abi to the block if it has attributes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Panic, non-idempotency, invalid code, etc.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants