Skip to content

Commit a5615d3

Browse files
committed
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.
1 parent ad27045 commit a5615d3

File tree

8 files changed

+31
-30
lines changed

8 files changed

+31
-30
lines changed

compiler/rustc_codegen_llvm/src/back/lto.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -793,7 +793,9 @@ pub(crate) unsafe fn optimize_thin_module(
793793
{
794794
let _timer =
795795
cgcx.prof.generic_activity_with_arg("LLVM_thin_lto_rename", thin_module.name());
796-
unsafe { llvm::LLVMRustPrepareThinLTORename(thin_module.shared.data.0, llmod, target) };
796+
unsafe {
797+
llvm::LLVMRustPrepareThinLTORename(thin_module.shared.data.0, llmod, target.raw())
798+
};
797799
save_temp_bitcode(cgcx, &module, "thin-lto-after-rename");
798800
}
799801

@@ -823,7 +825,7 @@ pub(crate) unsafe fn optimize_thin_module(
823825
let _timer =
824826
cgcx.prof.generic_activity_with_arg("LLVM_thin_lto_import", thin_module.name());
825827
if unsafe {
826-
!llvm::LLVMRustPrepareThinLTOImport(thin_module.shared.data.0, llmod, target)
828+
!llvm::LLVMRustPrepareThinLTOImport(thin_module.shared.data.0, llmod, target.raw())
827829
} {
828830
return Err(write::llvm_err(dcx, LlvmError::PrepareThinLtoModule));
829831
}

compiler/rustc_codegen_llvm/src/back/owned_target_machine.rs

+5-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
use std::ffi::{CStr, c_char};
22
use std::marker::PhantomData;
3-
use std::ops::Deref;
43
use std::ptr::NonNull;
54

65
use rustc_data_structures::small_c_str::SmallCStr;
@@ -80,12 +79,12 @@ impl OwnedTargetMachine {
8079
.map(|tm_unique| Self { tm_unique, phantom: PhantomData })
8180
.ok_or_else(|| LlvmError::CreateTargetMachine { triple: SmallCStr::from(triple) })
8281
}
83-
}
84-
85-
impl Deref for OwnedTargetMachine {
86-
type Target = llvm::TargetMachine;
8782

88-
fn deref(&self) -> &Self::Target {
83+
/// Returns inner `llvm::TargetMachine` type.
84+
///
85+
/// This could be a `Deref` implementation, but `llvm::TargetMachine` is an extern type and
86+
/// `Deref::Target: ?Sized`.
87+
pub fn raw(&self) -> &llvm::TargetMachine {
8988
// SAFETY: constructing ensures we have a valid pointer created by
9089
// llvm::LLVMRustCreateTargetMachine.
9190
unsafe { self.tm_unique.as_ref() }

compiler/rustc_codegen_llvm/src/back/write.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -637,7 +637,7 @@ pub(crate) unsafe fn llvm_optimize(
637637
let result = unsafe {
638638
llvm::LLVMRustOptimize(
639639
module.module_llvm.llmod(),
640-
&*module.module_llvm.tm,
640+
&*module.module_llvm.tm.raw(),
641641
to_pass_builder_opt_level(opt_level),
642642
opt_stage,
643643
cgcx.opts.cg.linker_plugin_lto.enabled(),
@@ -875,7 +875,7 @@ pub(crate) unsafe fn codegen(
875875
};
876876
write_output_file(
877877
dcx,
878-
tm,
878+
tm.raw(),
879879
config.no_builtins,
880880
llmod,
881881
&path,
@@ -909,7 +909,7 @@ pub(crate) unsafe fn codegen(
909909

910910
write_output_file(
911911
dcx,
912-
tm,
912+
tm.raw(),
913913
config.no_builtins,
914914
llmod,
915915
&obj_out,

compiler/rustc_codegen_llvm/src/builder.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -405,7 +405,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
405405

406406
// Emit KCFI operand bundle
407407
let kcfi_bundle = self.kcfi_operand_bundle(fn_attrs, fn_abi, instance, llfn);
408-
if let Some(kcfi_bundle) = kcfi_bundle.as_deref() {
408+
if let Some(kcfi_bundle) = kcfi_bundle.as_ref().map(|b| b.raw()) {
409409
bundles.push(kcfi_bundle);
410410
}
411411

@@ -1433,7 +1433,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
14331433

14341434
// Emit KCFI operand bundle
14351435
let kcfi_bundle = self.kcfi_operand_bundle(fn_attrs, fn_abi, instance, llfn);
1436-
if let Some(kcfi_bundle) = kcfi_bundle.as_deref() {
1436+
if let Some(kcfi_bundle) = kcfi_bundle.as_ref().map(|b| b.raw()) {
14371437
bundles.push(kcfi_bundle);
14381438
}
14391439

@@ -1782,7 +1782,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
17821782

17831783
// Emit KCFI operand bundle
17841784
let kcfi_bundle = self.kcfi_operand_bundle(fn_attrs, fn_abi, instance, llfn);
1785-
if let Some(kcfi_bundle) = kcfi_bundle.as_deref() {
1785+
if let Some(kcfi_bundle) = kcfi_bundle.as_ref().map(|b| b.raw()) {
17861786
bundles.push(kcfi_bundle);
17871787
}
17881788

compiler/rustc_codegen_llvm/src/common.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ impl<'ll> Funclet<'ll> {
7777
}
7878

7979
pub(crate) fn bundle(&self) -> &llvm::OperandBundle<'ll> {
80-
&self.operand
80+
self.operand.raw()
8181
}
8282
}
8383

compiler/rustc_codegen_llvm/src/context.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ pub(crate) unsafe fn create_module<'ll>(
205205
{
206206
let tm = crate::back::write::create_informational_target_machine(tcx.sess, false);
207207
unsafe {
208-
llvm::LLVMRustSetDataLayoutFromTargetMachine(llmod, &tm);
208+
llvm::LLVMRustSetDataLayoutFromTargetMachine(llmod, tm.raw());
209209
}
210210

211211
let llvm_data_layout = unsafe { llvm::LLVMGetDataLayoutStr(llmod) };

compiler/rustc_codegen_llvm/src/llvm/mod.rs

+10-11
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
#![allow(non_snake_case)]
22

33
use std::ffi::{CStr, CString};
4-
use std::ops::Deref;
54
use std::ptr;
65
use std::str::FromStr;
76
use std::string::FromUtf8Error;
@@ -355,6 +354,16 @@ impl<'a> OperandBundleOwned<'a> {
355354
};
356355
OperandBundleOwned { raw: ptr::NonNull::new(raw).unwrap() }
357356
}
357+
358+
/// Returns inner `OperandBundle` type.
359+
///
360+
/// This could be a `Deref` implementation, but `OperandBundle` contains an extern type and
361+
/// `Deref::Target: ?Sized`.
362+
pub(crate) fn raw(&self) -> &OperandBundle<'a> {
363+
// SAFETY: The returned reference is opaque and can only used for FFI.
364+
// It is valid for as long as `&self` is.
365+
unsafe { self.raw.as_ref() }
366+
}
358367
}
359368

360369
impl Drop for OperandBundleOwned<'_> {
@@ -365,16 +374,6 @@ impl Drop for OperandBundleOwned<'_> {
365374
}
366375
}
367376

368-
impl<'a> Deref for OperandBundleOwned<'a> {
369-
type Target = OperandBundle<'a>;
370-
371-
fn deref(&self) -> &Self::Target {
372-
// SAFETY: The returned reference is opaque and can only used for FFI.
373-
// It is valid for as long as `&self` is.
374-
unsafe { self.raw.as_ref() }
375-
}
376-
}
377-
378377
pub(crate) fn add_module_flag_u32(
379378
module: &Module,
380379
merge_behavior: ModuleFlagMergeBehavior,

compiler/rustc_codegen_llvm/src/llvm_util.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,8 @@ pub(crate) fn target_features_cfg(sess: &Session, allow_unstable: bool) -> Vec<S
331331
if let Some(feat) = to_llvm_features(sess, feature) {
332332
for llvm_feature in feat {
333333
let cstr = SmallCStr::new(llvm_feature);
334-
if !unsafe { llvm::LLVMRustHasFeature(&target_machine, cstr.as_ptr()) } {
334+
if !unsafe { llvm::LLVMRustHasFeature(target_machine.raw(), cstr.as_ptr()) }
335+
{
335336
return false;
336337
}
337338
}
@@ -453,8 +454,8 @@ pub(crate) fn print(req: &PrintRequest, out: &mut String, sess: &Session) {
453454
require_inited();
454455
let tm = create_informational_target_machine(sess, false);
455456
match req.kind {
456-
PrintKind::TargetCPUs => print_target_cpus(sess, &tm, out),
457-
PrintKind::TargetFeatures => print_target_features(sess, &tm, out),
457+
PrintKind::TargetCPUs => print_target_cpus(sess, tm.raw(), out),
458+
PrintKind::TargetFeatures => print_target_features(sess, tm.raw(), out),
458459
_ => bug!("rustc_codegen_llvm can't handle print request: {:?}", req),
459460
}
460461
}

0 commit comments

Comments
 (0)