@@ -126,6 +126,7 @@ use std::num::NonZero;
126
126
use std:: sync:: atomic:: { AtomicU32 , Ordering } ;
127
127
128
128
use rustc_ast:: LitKind ;
129
+ use rustc_attr:: InlineAttr ;
129
130
use rustc_data_structures:: fx:: FxHashMap ;
130
131
use rustc_data_structures:: sync:: { HashMapExt , Lock } ;
131
132
use rustc_data_structures:: tiny_list:: TinyList ;
@@ -555,16 +556,21 @@ impl<'tcx> TyCtxt<'tcx> {
555
556
pub fn reserve_and_set_fn_alloc ( self , instance : Instance < ' tcx > ) -> AllocId {
556
557
// Functions cannot be identified by pointers, as asm-equal functions can get deduplicated
557
558
// by the linker (we set the "unnamed_addr" attribute for LLVM) and functions can be
558
- // duplicated across crates.
559
- // We thus generate a new `AllocId` for every mention of a function. This means that
560
- // `main as fn() == main as fn()` is false, while `let x = main as fn(); x == x` is true.
561
- // However, formatting code relies on function identity (see #58320), so we only do
562
- // this for generic functions. Lifetime parameters are ignored.
559
+ // duplicated across crates. We thus generate a new `AllocId` for every mention of a
560
+ // function. This means that `main as fn() == main as fn()` is false, while `let x = main as
561
+ // fn(); x == x` is true. However, formatting code relies on function identity (see #58320)
562
+ // -- that's likely broken, but for now we have to support it to make Miri work. So we
563
+ // identify whether codegen will actually emit duplicate functions. It does that when they
564
+ // have non-lifetime generics, or when they can be inlined.
563
565
let is_generic = instance
564
566
. args
565
567
. into_iter ( )
566
568
. any ( |kind| !matches ! ( kind. unpack( ) , GenericArgKind :: Lifetime ( _) ) ) ;
567
- if is_generic {
569
+ let can_be_inlined = match self . codegen_fn_attrs ( instance. def_id ( ) ) . inline {
570
+ InlineAttr :: Never => false ,
571
+ _ => true ,
572
+ } ;
573
+ if is_generic || can_be_inlined {
568
574
// Get a fresh ID.
569
575
let mut alloc_map = self . alloc_map . lock ( ) ;
570
576
let id = alloc_map. reserve ( ) ;
0 commit comments