about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbjorn3 <bjorn3@users.noreply.github.com>2020-07-23 18:07:38 +0200
committerbjorn3 <bjorn3@users.noreply.github.com>2020-07-23 18:08:15 +0200
commit1b8df386aa72bc3dacb803f7d4deb4eadd63b56f (patch)
tree9e9b3c6d2c6369cd6e77a85d69aafe27c7fec742 /src
parent95511cb3eebec837a5c3efa3c87c1fc70dc0c1ba (diff)
downloadrust-1b8df386aa72bc3dacb803f7d4deb4eadd63b56f.tar.gz
rust-1b8df386aa72bc3dacb803f7d4deb4eadd63b56f.zip
Fix -Zpolymorphize
Diffstat (limited to 'src')
-rw-r--r--src/abi/mod.rs74
-rw-r--r--src/base.rs9
-rw-r--r--src/common.rs2
-rw-r--r--src/constant.rs2
-rw-r--r--src/main_shim.rs7
-rw-r--r--src/vtable.rs4
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<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);
             }
         }
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),
             ))
         })
     });