Skip to content

Commit

Permalink
Miri function identity hack: account for possible inlining
Browse files Browse the repository at this point in the history
  • Loading branch information
RalfJung committed Apr 11, 2024
1 parent f13f37f commit 5a8ca9a
Showing 1 changed file with 12 additions and 6 deletions.
18 changes: 12 additions & 6 deletions compiler/rustc_middle/src/mir/interpret/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ use std::num::NonZero;
use std::sync::atomic::{AtomicU32, Ordering};

use rustc_ast::LitKind;
use rustc_attr::InlineAttr;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::sync::{HashMapExt, Lock};
use rustc_data_structures::tiny_list::TinyList;
Expand Down Expand Up @@ -555,16 +556,21 @@ impl<'tcx> TyCtxt<'tcx> {
pub fn reserve_and_set_fn_alloc(self, instance: Instance<'tcx>) -> AllocId {
// Functions cannot be identified by pointers, as asm-equal functions can get deduplicated
// by the linker (we set the "unnamed_addr" attribute for LLVM) and functions can be
// duplicated across crates.
// We thus generate a new `AllocId` for every mention of a function. This means that
// `main as fn() == main as fn()` is false, while `let x = main as fn(); x == x` is true.
// However, formatting code relies on function identity (see #58320), so we only do
// this for generic functions. Lifetime parameters are ignored.
// duplicated across crates. We thus generate a new `AllocId` for every mention of a
// function. This means that `main as fn() == main as fn()` is false, while `let x = main as
// fn(); x == x` is true. However, formatting code relies on function identity (see #58320)
// -- that's likely broken, but for now we have to support it to make Miri work. So we
// identify whether codegen will actually emit duplicate functions. It does that when they
// have non-lifetime generics, or when they can be inlined.
let is_generic = instance
.args
.into_iter()
.any(|kind| !matches!(kind.unpack(), GenericArgKind::Lifetime(_)));
if is_generic {
let can_be_inlined = match self.codegen_fn_attrs(instance.def_id()).inline {
InlineAttr::Never => false,
_ => true,
};
if is_generic || can_be_inlined {
// Get a fresh ID.
let mut alloc_map = self.alloc_map.lock();
let id = alloc_map.reserve();
Expand Down

0 comments on commit 5a8ca9a

Please sign in to comment.