Resolve instance for SymFn in global/naked asm

This commit is contained in:
Michael Goulet
2025-04-27 21:55:50 +00:00
parent 0eb0b8cb67
commit 3a1ee645ca
4 changed files with 72 additions and 2 deletions
+7 -1
View File
@@ -457,7 +457,13 @@ pub fn codegen_global_asm<'tcx, Cx>(cx: &mut Cx, item_id: ItemId)
rustc_hir::InlineAsmOperand::SymFn { expr } => {
let ty = cx.tcx().typeck(item_id.owner_id).expr_ty(expr);
let instance = match ty.kind() {
&ty::FnDef(def_id, args) => Instance::new(def_id, args),
&ty::FnDef(def_id, args) => Instance::expect_resolve(
cx.tcx(),
ty::TypingEnv::fully_monomorphized(),
def_id,
args,
expr.span,
),
_ => span_bug!(*op_sp, "asm sym is not a function"),
};
@@ -95,7 +95,9 @@ fn inline_to_global_operand<'a, 'tcx, Cx: LayoutOf<'tcx, LayoutOfResult = TyAndL
);
let instance = match mono_type.kind() {
&ty::FnDef(def_id, args) => Instance::new(def_id, args),
&ty::FnDef(def_id, args) => {
Instance::expect_resolve(cx.tcx(), cx.typing_env(), def_id, args, value.span)
}
_ => bug!("asm sym is not a function"),
};
+27
View File
@@ -0,0 +1,27 @@
// Test that we're properly monomorphizing sym args in global asm blocks
// that point to associated items.
//@ edition: 2021
//@ needs-asm-support
//@ only-x86_64-unknown-linux-gnu
//@ build-pass
#![no_main]
use std::arch::global_asm;
fn foo() {
loop {}
}
trait Foo {
fn bar();
}
impl Foo for i32 {
fn bar() {
loop {}
}
}
global_asm!(".global main", "main:", "call {}", sym <i32 as Foo>::bar);
+35
View File
@@ -0,0 +1,35 @@
// Regression test for <https://github.com/rust-lang/rust/issues/140373>.
// Test that we're properly monomorphizing sym args in naked asm blocks
// that point to associated items.
//@ edition: 2021
//@ needs-asm-support
//@ only-x86_64
//@ build-pass
trait T {
extern "C" fn t();
}
enum E<const C: usize> {}
impl<const C: usize> T for E<C> {
extern "C" fn t() {
println!("Const generic: {}", C);
}
}
#[unsafe(naked)]
extern "C" fn foo<U: T>() {
core::arch::naked_asm!(
"push rax",
"call {fn}",
"pop rax",
"ret",
fn = sym <U as T>::t,
);
}
fn main() {
foo::<E<42>>();
}