Fix -Zpolymorphize

This commit is contained in:
bjorn3 2020-07-23 18:07:38 +02:00
parent 95511cb3ee
commit 1b8df386aa
6 changed files with 52 additions and 46 deletions

View File

@ -13,14 +13,26 @@ use crate::prelude::*;
pub(crate) use self::returning::{can_return_to_ssa_var, codegen_return};
// Copied from https://github.com/rust-lang/rust/blob/b2c1a606feb1fbdb0ac0acba76f881ef172ed474/src/librustc_middle/ty/layout.rs#L2287
// Copied from https://github.com/rust-lang/rust/blob/f52c72948aa1dd718cc1f168d21c91c584c0a662/src/librustc_middle/ty/layout.rs#L2301
pub(crate) fn fn_sig_for_fn_abi<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> ty::PolyFnSig<'tcx> {
let ty = instance.ty(tcx, ParamEnv::reveal_all());
use rustc_middle::ty::subst::Subst;
// FIXME(davidtwco,eddyb): A `ParamEnv` should be passed through to this function.
let ty = instance.ty(tcx, ty::ParamEnv::reveal_all());
match ty.kind {
ty::FnDef(..) |
// Shims currently have type FnPtr. Not sure this should remain.
ty::FnPtr(_) => {
let mut sig = ty.fn_sig(tcx);
ty::FnDef(..) => {
// HACK(davidtwco,eddyb): This is a workaround for polymorphization considering
// parameters unused if they show up in the signature, but not in the `mir::Body`
// (i.e. due to being inside a projection that got normalized, see
// `src/test/ui/polymorphization/normalized_sig_types.rs`), and codegen not keeping
// track of a polymorphization `ParamEnv` to allow normalizing later.
let mut sig = match ty.kind {
ty::FnDef(def_id, substs) => tcx
.normalize_erasing_regions(tcx.param_env(def_id), tcx.fn_sig(def_id))
.subst(tcx, substs),
_ => unreachable!(),
};
if let ty::InstanceDef::VtableShim(..) = instance.def {
// Modify `fn(self, ...)` to `fn(self: *mut Self, ...)`.
sig = sig.map_bound(|mut sig| {
@ -36,13 +48,15 @@ pub(crate) fn fn_sig_for_fn_abi<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx
let sig = substs.as_closure().sig();
let env_ty = tcx.closure_env_ty(def_id, substs).unwrap();
sig.map_bound(|sig| tcx.mk_fn_sig(
std::iter::once(env_ty.skip_binder()).chain(sig.inputs().iter().cloned()),
sig.output(),
sig.c_variadic,
sig.unsafety,
sig.abi
))
sig.map_bound(|sig| {
tcx.mk_fn_sig(
std::iter::once(env_ty.skip_binder()).chain(sig.inputs().iter().cloned()),
sig.output(),
sig.c_variadic,
sig.unsafety,
sig.abi,
)
})
}
ty::Generator(_, substs, _) => {
let sig = substs.as_generator().poly_sig();
@ -50,18 +64,16 @@ pub(crate) fn fn_sig_for_fn_abi<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx
let env_region = ty::ReLateBound(ty::INNERMOST, ty::BrEnv);
let env_ty = tcx.mk_mut_ref(tcx.mk_region(env_region), ty);
let pin_did = tcx.lang_items().pin_type().unwrap();
let pin_did = tcx.require_lang_item(rustc_hir::LangItem::PinTypeLangItem, None);
let pin_adt_ref = tcx.adt_def(pin_did);
let pin_substs = tcx.intern_substs(&[env_ty.into()]);
let env_ty = tcx.mk_adt(pin_adt_ref, pin_substs);
sig.map_bound(|sig| {
let state_did = tcx.lang_items().gen_state().unwrap();
let state_did = tcx.require_lang_item(rustc_hir::LangItem::GeneratorStateLangItem, None);
let state_adt_ref = tcx.adt_def(state_did);
let state_substs = tcx.intern_substs(&[
sig.yield_ty.into(),
sig.return_ty.into(),
]);
let state_substs =
tcx.intern_substs(&[sig.yield_ty.into(), sig.return_ty.into()]);
let ret_ty = tcx.mk_adt(state_adt_ref, state_substs);
tcx.mk_fn_sig(
@ -69,11 +81,11 @@ pub(crate) fn fn_sig_for_fn_abi<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx
&ret_ty,
false,
rustc_hir::Unsafety::Normal,
rustc_target::spec::abi::Abi::Rust
rustc_target::spec::abi::Abi::Rust,
)
})
}
_ => bug!("unexpected type {:?} in Instance::fn_sig", ty)
_ => bug!("unexpected type {:?} in Instance::fn_sig", ty),
}
}
@ -464,7 +476,8 @@ pub(crate) fn codegen_terminator_call<'tcx>(
let instance = if let ty::FnDef(def_id, substs) = fn_ty.kind {
let instance = ty::Instance::resolve(fx.tcx, ty::ParamEnv::reveal_all(), def_id, substs)
.unwrap()
.unwrap();
.unwrap()
.polymorphize(fx.tcx);
if fx.tcx.symbol_name(instance).name.starts_with("llvm.") {
crate::intrinsics::codegen_llvm_intrinsic_call(
@ -655,7 +668,7 @@ pub(crate) fn codegen_drop<'tcx>(
drop_place: CPlace<'tcx>,
) {
let ty = drop_place.layout().ty;
let drop_fn = Instance::resolve_drop_in_place(fx.tcx, ty);
let drop_fn = Instance::resolve_drop_in_place(fx.tcx, ty).polymorphize(fx.tcx);
if let ty::InstanceDef::DropGlue(_, None) = drop_fn.def {
// we don't actually need to drop anything
@ -685,16 +698,7 @@ pub(crate) fn codegen_drop<'tcx>(
fx.bcx.ins().call_indirect(sig, drop_fn, &[ptr]);
}
_ => {
let instance = match drop_fn_ty.kind {
ty::FnDef(def_id, substs) => {
Instance::resolve(fx.tcx, ParamEnv::reveal_all(), def_id, substs)
.unwrap()
.unwrap()
}
_ => unreachable!("{:?}", drop_fn_ty),
};
assert!(!matches!(instance.def, InstanceDef::Virtual(_, _)));
assert!(!matches!(drop_fn.def, InstanceDef::Virtual(_, _)));
let arg_place = CPlace::new_stack_slot(
fx,
@ -712,13 +716,13 @@ pub(crate) fn codegen_drop<'tcx>(
let mut call_args: Vec<Value> = arg_value.into_iter().collect::<Vec<_>>();
if instance.def.requires_caller_location(fx.tcx) {
if drop_fn.def.requires_caller_location(fx.tcx) {
// Pass the caller location for `#[track_caller]`.
let caller_location = fx.get_caller_location(span);
call_args.extend(adjust_arg_for_abi(fx, caller_location).into_iter());
}
let func_ref = fx.get_function_ref(instance);
let func_ref = fx.get_function_ref(drop_fn);
fx.bcx.ins().call(func_ref, &call_args);
}
}

View File

@ -267,7 +267,7 @@ fn codegen_fn_content(fx: &mut FunctionCx<'_, '_, impl Backend>) {
fx.tcx.sess.span_fatal(bb_data.terminator().source_info.span, &s)
});
let instance = Instance::mono(fx.tcx, def_id);
let instance = Instance::mono(fx.tcx, def_id).polymorphize(fx.tcx);
let symbol_name = fx.tcx.symbol_name(instance).name;
fx.lib_call(&*symbol_name, vec![fx.pointer_type, fx.pointer_type, fx.pointer_type], vec![], &args);
@ -469,7 +469,8 @@ fn trans_stmt<'tcx>(
ty::FnDef(def_id, substs) => {
let func_ref = fx.get_function_ref(
Instance::resolve_for_fn_ptr(fx.tcx, ParamEnv::reveal_all(), def_id, substs)
.unwrap(),
.unwrap()
.polymorphize(fx.tcx),
);
let func_addr = fx.bcx.ins().func_addr(fx.pointer_type, func_ref);
lval.write_cvalue(fx, CValue::by_val(func_addr, to_layout));
@ -580,7 +581,7 @@ fn trans_stmt<'tcx>(
def_id,
substs,
ty::ClosureKind::FnOnce,
);
).polymorphize(fx.tcx);
let func_ref = fx.get_function_ref(instance);
let func_addr = fx.bcx.ins().func_addr(fx.pointer_type, func_ref);
lval.write_cvalue(fx, CValue::by_val(func_addr, lval.layout()));
@ -641,7 +642,7 @@ fn trans_stmt<'tcx>(
.fatal(&format!("allocation of `{}` {}", box_layout.ty, s));
}
};
let instance = ty::Instance::mono(fx.tcx, def_id);
let instance = ty::Instance::mono(fx.tcx, def_id).polymorphize(fx.tcx);
let func_ref = fx.get_function_ref(instance);
let call = fx.bcx.ins().call(func_ref, &[llsize, llalign]);
let ptr = fx.bcx.inst_results(call)[0];

View File

@ -287,7 +287,7 @@ impl<'tcx, B: Backend> LayoutOf for FunctionCx<'_, 'tcx, B> {
type TyAndLayout = TyAndLayout<'tcx>;
fn layout_of(&self, ty: Ty<'tcx>) -> TyAndLayout<'tcx> {
assert!(!ty.needs_subst());
assert!(!ty.still_further_specializable());
self.tcx
.layout_of(ParamEnv::reveal_all().and(&ty))
.unwrap_or_else(|e| {

View File

@ -228,7 +228,7 @@ fn data_id_for_static(
def_id: DefId,
linkage: Linkage,
) -> DataId {
let instance = Instance::mono(tcx, def_id);
let instance = Instance::mono(tcx, def_id).polymorphize(tcx);
let symbol_name = tcx.symbol_name(instance).name;
let ty = instance.ty(tcx, ParamEnv::reveal_all());
let is_mutable = if tcx.is_mutable_static(def_id) {

View File

@ -21,7 +21,7 @@ pub(crate) fn maybe_create_entry_wrapper(
None => return,
};
let instance = Instance::mono(tcx, main_def_id);
let instance = Instance::mono(tcx, main_def_id).polymorphize(tcx);
if module.get_name(&*tcx.symbol_name(instance).name).is_none() {
return;
}
@ -58,7 +58,7 @@ pub(crate) fn maybe_create_entry_wrapper(
.declare_function("main", Linkage::Export, &cmain_sig)
.unwrap();
let instance = Instance::mono(tcx, rust_main_def_id);
let instance = Instance::mono(tcx, rust_main_def_id).polymorphize(tcx);
let (main_name, main_sig) =
get_function_name_and_sig(tcx, m.isa().triple(), instance, false);
@ -90,7 +90,8 @@ pub(crate) fn maybe_create_entry_wrapper(
tcx.intern_substs(&[main_ret_ty.into()]),
)
.unwrap()
.unwrap();
.unwrap()
.polymorphize(tcx);
let start_func_id = import_function(tcx, m, start_instance);
let main_val = bcx

View File

@ -93,7 +93,7 @@ fn build_vtable<'tcx>(
let usize_size = fx.layout_of(fx.tcx.types.usize).size.bytes() as usize;
let drop_in_place_fn =
import_function(tcx, fx.module, Instance::resolve_drop_in_place(tcx, layout.ty));
import_function(tcx, fx.module, Instance::resolve_drop_in_place(tcx, layout.ty).polymorphize(fx.tcx));
let mut components: Vec<_> = vec![Some(drop_in_place_fn), None, None];
@ -109,7 +109,7 @@ fn build_vtable<'tcx>(
Some(import_function(
tcx,
fx.module,
Instance::resolve_for_vtable(tcx, ParamEnv::reveal_all(), def_id, substs).unwrap(),
Instance::resolve_for_vtable(tcx, ParamEnv::reveal_all(), def_id, substs).unwrap().polymorphize(fx.tcx),
))
})
});