@@ -27,7 +27,7 @@ pub use self::pointer::{Pointer, PointerArithmetic};
27
27
use std:: fmt;
28
28
use crate :: mir;
29
29
use crate :: hir:: def_id:: DefId ;
30
- use crate :: ty:: { self , TyCtxt , Instance } ;
30
+ use crate :: ty:: { self , TyCtxt , Instance , subst :: UnpackedKind } ;
31
31
use crate :: ty:: layout:: { self , Size } ;
32
32
use std:: io;
33
33
use crate :: rustc_serialize:: { Encoder , Decodable , Encodable } ;
@@ -318,14 +318,29 @@ impl<'tcx> AllocMap<'tcx> {
318
318
id
319
319
}
320
320
321
- /// Functions cannot be identified by pointers, as asm-equal functions can get deduplicated
322
- /// by the linker and functions can be duplicated across crates.
323
- /// We thus generate a new `AllocId` for every mention of a function. This means that
324
- /// `main as fn() == main as fn()` is false, while `let x = main as fn(); x == x` is true.
325
321
pub fn create_fn_alloc ( & mut self , instance : Instance < ' tcx > ) -> AllocId {
326
- let id = self . reserve ( ) ;
327
- self . id_to_kind . insert ( id, AllocKind :: Function ( instance) ) ;
328
- id
322
+ // Functions cannot be identified by pointers, as asm-equal functions can get deduplicated
323
+ // by the linker (we set the "unnamed_addr" attribute for LLVM) and functions can be
324
+ // duplicated across crates.
325
+ // We thus generate a new `AllocId` for every mention of a function. This means that
326
+ // `main as fn() == main as fn()` is false, while `let x = main as fn(); x == x` is true.
327
+ // However, formatting code relies on function identity (see #58320), so we only do
328
+ // this for generic functions. Lifetime parameters are ignored.
329
+ let is_generic = instance. substs . into_iter ( ) . any ( |kind| {
330
+ match kind. unpack ( ) {
331
+ UnpackedKind :: Lifetime ( _) => false ,
332
+ _ => true ,
333
+ }
334
+ } ) ;
335
+ if is_generic {
336
+ // Get a fresh ID
337
+ let id = self . reserve ( ) ;
338
+ self . id_to_kind . insert ( id, AllocKind :: Function ( instance) ) ;
339
+ id
340
+ } else {
341
+ // Deduplicate
342
+ self . intern ( AllocKind :: Function ( instance) )
343
+ }
329
344
}
330
345
331
346
/// Returns `None` in case the `AllocId` is dangling. An `EvalContext` can still have a
0 commit comments