@@ -147,19 +147,28 @@ pub(crate) fn format_extern(
147
147
ext : ast:: Extern ,
148
148
explicit_abi : bool ,
149
149
is_mod : bool ,
150
+ attrs : Option < & [ ast:: Attribute ] > ,
150
151
) -> Cow < ' static , str > {
151
- let abi = match ext {
152
- ast:: Extern :: None => "Rust" . to_owned ( ) ,
153
- ast:: Extern :: Implicit => "C" . to_owned ( ) ,
154
- ast:: Extern :: Explicit ( abi) => abi. symbol_unescaped . to_string ( ) ,
155
- } ;
156
-
157
- if abi == "Rust" && !is_mod {
158
- Cow :: from ( "" )
159
- } else if abi == "C" && !explicit_abi {
160
- Cow :: from ( "extern " )
161
- } else {
162
- Cow :: from ( format ! ( r#"extern "{}" "# , abi) )
152
+ let format_explicit_abi = |abi : & str | Cow :: from ( format ! ( r#"extern "{}" "# , abi) ) ;
153
+ let explicit_conversion_preserves_semantics =
154
+ || !is_mod || ( is_mod && attrs. map_or ( true , |a| a. is_empty ( ) ) ) ;
155
+
156
+ match ext {
157
+ ast:: Extern :: None if !is_mod => Cow :: from ( "" ) ,
158
+ ast:: Extern :: Explicit ( ast:: StrLit {
159
+ symbol_unescaped, ..
160
+ } ) if !is_mod && symbol_unescaped == rustc_span:: sym:: rust => Cow :: from ( "" ) ,
161
+ ast:: Extern :: Implicit if !explicit_abi || !explicit_conversion_preserves_semantics ( ) => {
162
+ Cow :: from ( "extern " )
163
+ }
164
+ ast:: Extern :: Explicit ( ast:: StrLit {
165
+ symbol_unescaped, ..
166
+ } ) if !explicit_abi && symbol_unescaped == rustc_span:: sym:: C => Cow :: from ( "extern " ) ,
167
+ ast:: Extern :: None => format_explicit_abi ( "Rust" ) ,
168
+ ast:: Extern :: Implicit => format_explicit_abi ( "C" ) ,
169
+ ast:: Extern :: Explicit ( ast:: StrLit {
170
+ symbol_unescaped, ..
171
+ } ) => format_explicit_abi ( & symbol_unescaped. to_string ( ) ) ,
163
172
}
164
173
}
165
174
0 commit comments