From 1b8df386aa72bc3dacb803f7d4deb4eadd63b56f Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Thu, 23 Jul 2020 18:07:38 +0200 Subject: [PATCH] Fix -Zpolymorphize --- src/abi/mod.rs | 74 +++++++++++++++++++++++++----------------------- src/base.rs | 9 +++--- src/common.rs | 2 +- src/constant.rs | 2 +- src/main_shim.rs | 7 +++-- src/vtable.rs | 4 +-- 6 files changed, 52 insertions(+), 46 deletions(-) diff --git a/src/abi/mod.rs b/src/abi/mod.rs index cbbdb1fab0b..fcf05be8653 100644 --- a/src/abi/mod.rs +++ b/src/abi/mod.rs @@ -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 = arg_value.into_iter().collect::>(); - 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); } } diff --git a/src/base.rs b/src/base.rs index 57396004c12..cd8152066fa 100644 --- a/src/base.rs +++ b/src/base.rs @@ -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]; diff --git a/src/common.rs b/src/common.rs index 39a918b60f3..c807bde15c3 100644 --- a/src/common.rs +++ b/src/common.rs @@ -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| { diff --git a/src/constant.rs b/src/constant.rs index 82d50a1e444..e3d96528972 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -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) { diff --git a/src/main_shim.rs b/src/main_shim.rs index 98148355b27..a256446df93 100644 --- a/src/main_shim.rs +++ b/src/main_shim.rs @@ -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 diff --git a/src/vtable.rs b/src/vtable.rs index c0cb70f3ff6..601c37d82c8 100644 --- a/src/vtable.rs +++ b/src/vtable.rs @@ -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), )) }) });