codegen_llvm: avoid Deref impls w/ extern type

`rustc_codegen_llvm` relied on `Deref` impls where `Deref::Target` was
or contained an extern type - in my experimental implementation of
rust-lang/rfcs#3729, this isn't possible as the `Target` associated
type's `?Sized` bound cannot be relaxed backwards compatibly (unless we
come up with some way of doing this).

In later pull requests with the rust-lang/rfcs#3729 implementation,
breakage like this could only occur for nightly users relying on the
`extern_types` feature.

Upstreaming this to avoid needing to keep carrying this patch locally,
and I think it'll necessarily need to change eventually.
This commit is contained in:
David Wood
2025-02-04 12:20:09 +00:00
parent ad27045c31
commit a5615d3c62
8 changed files with 31 additions and 30 deletions

View File

@@ -793,7 +793,9 @@ pub(crate) unsafe fn optimize_thin_module(
{
let _timer =
cgcx.prof.generic_activity_with_arg("LLVM_thin_lto_rename", thin_module.name());
unsafe { llvm::LLVMRustPrepareThinLTORename(thin_module.shared.data.0, llmod, target) };
unsafe {
llvm::LLVMRustPrepareThinLTORename(thin_module.shared.data.0, llmod, target.raw())
};
save_temp_bitcode(cgcx, &module, "thin-lto-after-rename");
}
@@ -823,7 +825,7 @@ pub(crate) unsafe fn optimize_thin_module(
let _timer =
cgcx.prof.generic_activity_with_arg("LLVM_thin_lto_import", thin_module.name());
if unsafe {
!llvm::LLVMRustPrepareThinLTOImport(thin_module.shared.data.0, llmod, target)
!llvm::LLVMRustPrepareThinLTOImport(thin_module.shared.data.0, llmod, target.raw())
} {
return Err(write::llvm_err(dcx, LlvmError::PrepareThinLtoModule));
}

View File

@@ -1,6 +1,5 @@
use std::ffi::{CStr, c_char};
use std::marker::PhantomData;
use std::ops::Deref;
use std::ptr::NonNull;
use rustc_data_structures::small_c_str::SmallCStr;
@@ -80,12 +79,12 @@ impl OwnedTargetMachine {
.map(|tm_unique| Self { tm_unique, phantom: PhantomData })
.ok_or_else(|| LlvmError::CreateTargetMachine { triple: SmallCStr::from(triple) })
}
}
impl Deref for OwnedTargetMachine {
type Target = llvm::TargetMachine;
fn deref(&self) -> &Self::Target {
/// Returns inner `llvm::TargetMachine` type.
///
/// This could be a `Deref` implementation, but `llvm::TargetMachine` is an extern type and
/// `Deref::Target: ?Sized`.
pub fn raw(&self) -> &llvm::TargetMachine {
// SAFETY: constructing ensures we have a valid pointer created by
// llvm::LLVMRustCreateTargetMachine.
unsafe { self.tm_unique.as_ref() }

View File

@@ -637,7 +637,7 @@ pub(crate) unsafe fn llvm_optimize(
let result = unsafe {
llvm::LLVMRustOptimize(
module.module_llvm.llmod(),
&*module.module_llvm.tm,
&*module.module_llvm.tm.raw(),
to_pass_builder_opt_level(opt_level),
opt_stage,
cgcx.opts.cg.linker_plugin_lto.enabled(),
@@ -875,7 +875,7 @@ pub(crate) unsafe fn codegen(
};
write_output_file(
dcx,
tm,
tm.raw(),
config.no_builtins,
llmod,
&path,
@@ -909,7 +909,7 @@ pub(crate) unsafe fn codegen(
write_output_file(
dcx,
tm,
tm.raw(),
config.no_builtins,
llmod,
&obj_out,