|
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