From 59fdfaff7850dd92d2b150d198cd88eea2d43d6b Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Tue, 18 Jul 2023 18:07:54 +0000 Subject: [PATCH 1/2] refactor ABI formatting Here are two paths of behavior this changes: 1. whenever we see an `extern "Rust"` on a function, we don't strip it from the function (which fixes #5701) 2. if `force_explicit_abi` is disabled, we preserve what the user has written. Previously, rustfmt would change `extern "C"` to `extern `, which is not something a code formatter should do. --- src/items.rs | 2 -- src/types.rs | 1 - src/utils.rs | 25 ++++++++----------------- tests/target/extern-rust.rs | 1 + tests/target/extern_not_explicit.rs | 6 +++--- 5 files changed, 12 insertions(+), 23 deletions(-) create mode 100644 tests/target/extern-rust.rs diff --git a/src/items.rs b/src/items.rs index a72646ef897..1f4a14211b5 100644 --- a/src/items.rs +++ b/src/items.rs @@ -248,7 +248,6 @@ impl<'a> Item<'a> { abi: format_extern( ast::Extern::from_abi(fm.abi, DUMMY_SP), config.force_explicit_abi(), - true, ), vis: None, body: fm @@ -336,7 +335,6 @@ impl<'a> FnSig<'a> { result.push_str(&format_extern( self.ext, context.config.force_explicit_abi(), - false, )); result } diff --git a/src/types.rs b/src/types.rs index 8be474d5bca..f2e229d7477 100644 --- a/src/types.rs +++ b/src/types.rs @@ -892,7 +892,6 @@ fn rewrite_bare_fn( result.push_str(&format_extern( bare_fn.ext, context.config.force_explicit_abi(), - false, )); result.push_str("fn"); diff --git a/src/utils.rs b/src/utils.rs index d1cb197cb51..940dffc6da6 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -131,23 +131,14 @@ pub(crate) fn format_mutability(mutability: ast::Mutability) -> &'static str { } #[inline] -pub(crate) fn format_extern( - ext: ast::Extern, - explicit_abi: bool, - is_mod: bool, -) -> Cow<'static, str> { - let abi = match ext { - ast::Extern::None => "Rust".to_owned(), - ast::Extern::Implicit(_) => "C".to_owned(), - ast::Extern::Explicit(abi, _) => abi.symbol_unescaped.to_string(), - }; - - if abi == "Rust" && !is_mod { - Cow::from("") - } else if abi == "C" && !explicit_abi { - Cow::from("extern ") - } else { - Cow::from(format!(r#"extern "{abi}" "#)) +pub(crate) fn format_extern(ext: ast::Extern, explicit_abi: bool) -> Cow<'static, str> { + match ext { + ast::Extern::None => Cow::from(""), + ast::Extern::Implicit(_) if explicit_abi => Cow::from("extern \"C\" "), + ast::Extern::Implicit(_) => Cow::from("extern "), + ast::Extern::Explicit(abi, _) => { + Cow::from(format!(r#"extern "{}" "#, abi.symbol_unescaped)) + } } } diff --git a/tests/target/extern-rust.rs b/tests/target/extern-rust.rs new file mode 100644 index 00000000000..32824c91203 --- /dev/null +++ b/tests/target/extern-rust.rs @@ -0,0 +1 @@ +extern "Rust" fn uwu() {} diff --git a/tests/target/extern_not_explicit.rs b/tests/target/extern_not_explicit.rs index b55b64d05b3..1f800cf1460 100644 --- a/tests/target/extern_not_explicit.rs +++ b/tests/target/extern_not_explicit.rs @@ -1,12 +1,12 @@ // rustfmt-force_explicit_abi: false -extern { +extern "C" { fn some_fn() -> (); } -extern fn sup() {} +extern "C" fn sup() {} -type funky_func = extern fn( +type funky_func = extern "C" fn( unsafe extern "rust-call" fn( *const JSJitInfo, *mut JSContext, From 267e8c21fdde9d22cbfc5101489cd58d87a48a34 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Wed, 19 Jul 2023 16:12:07 +0000 Subject: [PATCH 2/2] maintain `force_explicit_abi = false` behavior --- src/utils.rs | 4 ++++ tests/target/extern_not_explicit.rs | 6 +++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/utils.rs b/src/utils.rs index 940dffc6da6..ae7c50b4ca2 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -136,6 +136,10 @@ pub(crate) fn format_extern(ext: ast::Extern, explicit_abi: bool) -> Cow<'static ast::Extern::None => Cow::from(""), ast::Extern::Implicit(_) if explicit_abi => Cow::from("extern \"C\" "), ast::Extern::Implicit(_) => Cow::from("extern "), + // turn `extern "C"` into `extern` when `explicit_abi` is set to false + ast::Extern::Explicit(abi, _) if abi.symbol_unescaped == sym::C && !explicit_abi => { + Cow::from("extern ") + } ast::Extern::Explicit(abi, _) => { Cow::from(format!(r#"extern "{}" "#, abi.symbol_unescaped)) } diff --git a/tests/target/extern_not_explicit.rs b/tests/target/extern_not_explicit.rs index 1f800cf1460..b55b64d05b3 100644 --- a/tests/target/extern_not_explicit.rs +++ b/tests/target/extern_not_explicit.rs @@ -1,12 +1,12 @@ // rustfmt-force_explicit_abi: false -extern "C" { +extern { fn some_fn() -> (); } -extern "C" fn sup() {} +extern fn sup() {} -type funky_func = extern "C" fn( +type funky_func = extern fn( unsafe extern "rust-call" fn( *const JSJitInfo, *mut JSContext,