Skip to content

Commit f6b3eb0

Browse files
committed
Function pointers are only equal to themselves, not to other function pointers to the same function
1 parent 3074fcb commit f6b3eb0

File tree

1 file changed

+8
-5
lines changed
  • src/librustc/mir/interpret

1 file changed

+8
-5
lines changed

src/librustc/mir/interpret/mod.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,7 @@ pub struct AllocMap<'tcx> {
305305
/// Lets you know what an AllocId refers to
306306
id_to_type: FxHashMap<AllocId, AllocType<'tcx>>,
307307

308-
/// Used to ensure that functions and statics only get one associated AllocId
308+
/// Used to ensure that statics only get one associated AllocId
309309
type_interner: FxHashMap<AllocType<'tcx>, AllocId>,
310310

311311
/// The AllocId to assign to the next requested id.
@@ -347,11 +347,14 @@ impl<'tcx> AllocMap<'tcx> {
347347
id
348348
}
349349

350-
// FIXME: Check if functions have identity. If not, we should not intern these,
351-
// but instead create a new id per use.
352-
// Alternatively we could just make comparing function pointers an error.
350+
/// Functions cannot be identified by pointers, as asm-equal functions can get deduplicated
351+
/// by the linker and functions can be duplicated across crates.
352+
/// We thus generate a new `AllocId` for every mention of a function. This means that
353+
/// `main as fn() == main as fn()` is false, while `let x = main as fn(); x == x` is true.
353354
pub fn create_fn_alloc(&mut self, instance: Instance<'tcx>) -> AllocId {
354-
self.intern(AllocType::Function(instance))
355+
let id = self.reserve();
356+
self.id_to_type.insert(id, AllocType::Function(instance));
357+
id
355358
}
356359

357360
pub fn get(&self, id: AllocId) -> Option<AllocType<'tcx>> {

0 commit comments

Comments
 (0)