|
96 | 96 | #[macro_use] |
97 | 97 | extern crate rustc_middle; |
98 | 98 |
|
| 99 | +use rustc_hir::def::DefKind; |
99 | 100 | use rustc_hir::def_id::{CrateNum, LOCAL_CRATE}; |
100 | 101 | use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; |
| 102 | +use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs; |
101 | 103 | use rustc_middle::mir::mono::{InstantiationMode, MonoItem}; |
102 | 104 | use rustc_middle::ty::query::Providers; |
103 | 105 | use rustc_middle::ty::subst::SubstsRef; |
@@ -175,7 +177,11 @@ fn compute_symbol_name<'tcx>( |
175 | 177 | } |
176 | 178 |
|
177 | 179 | // FIXME(eddyb) Precompute a custom symbol name based on attributes. |
178 | | - let attrs = tcx.codegen_fn_attrs(def_id); |
| 180 | + let attrs = if tcx.has_codegen_attrs(tcx.def_kind(def_id)) { |
| 181 | + tcx.codegen_fn_attrs(def_id) |
| 182 | + } else { |
| 183 | + CodegenFnAttrs::EMPTY |
| 184 | + }; |
179 | 185 |
|
180 | 186 | // Foreign items by default use no mangling for their symbol name. There's a |
181 | 187 | // few exceptions to this rule though: |
@@ -213,20 +219,25 @@ fn compute_symbol_name<'tcx>( |
213 | 219 | return tcx.item_name(def_id).to_string(); |
214 | 220 | } |
215 | 221 |
|
216 | | - let avoid_cross_crate_conflicts = |
217 | | - // If this is an instance of a generic function, we also hash in |
218 | | - // the ID of the instantiating crate. This avoids symbol conflicts |
219 | | - // in case the same instances is emitted in two crates of the same |
220 | | - // project. |
221 | | - is_generic(substs) || |
| 222 | + // If we're dealing with an instance of a function that's inlined from |
| 223 | + // another crate but we're marking it as globally shared to our |
| 224 | + // compilation (aka we're not making an internal copy in each of our |
| 225 | + // codegen units) then this symbol may become an exported (but hidden |
| 226 | + // visibility) symbol. This means that multiple crates may do the same |
| 227 | + // and we want to be sure to avoid any symbol conflicts here. |
| 228 | + let is_globally_shared_function = matches!( |
| 229 | + tcx.def_kind(instance.def_id()), |
| 230 | + DefKind::Fn | DefKind::AssocFn | DefKind::Closure | DefKind::Generator | DefKind::Ctor(..) |
| 231 | + ) && matches!( |
| 232 | + MonoItem::Fn(instance).instantiation_mode(tcx), |
| 233 | + InstantiationMode::GloballyShared { may_conflict: true } |
| 234 | + ); |
222 | 235 |
|
223 | | - // If we're dealing with an instance of a function that's inlined from |
224 | | - // another crate but we're marking it as globally shared to our |
225 | | - // compilation (aka we're not making an internal copy in each of our |
226 | | - // codegen units) then this symbol may become an exported (but hidden |
227 | | - // visibility) symbol. This means that multiple crates may do the same |
228 | | - // and we want to be sure to avoid any symbol conflicts here. |
229 | | - matches!(MonoItem::Fn(instance).instantiation_mode(tcx), InstantiationMode::GloballyShared { may_conflict: true }); |
| 236 | + // If this is an instance of a generic function, we also hash in |
| 237 | + // the ID of the instantiating crate. This avoids symbol conflicts |
| 238 | + // in case the same instances is emitted in two crates of the same |
| 239 | + // project. |
| 240 | + let avoid_cross_crate_conflicts = is_generic(substs) || is_globally_shared_function; |
230 | 241 |
|
231 | 242 | let instantiating_crate = |
232 | 243 | if avoid_cross_crate_conflicts { Some(compute_instantiating_crate()) } else { None }; |
|
0 commit comments