about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/librustc_middle/ty/layout.rs43
-rw-r--r--src/test/ui/polymorphization/normalized_sig_types.rs25
2 files changed, 51 insertions, 17 deletions
diff --git a/src/librustc_middle/ty/layout.rs b/src/librustc_middle/ty/layout.rs
index 610a7cd41be..cb937bf0112 100644
--- a/src/librustc_middle/ty/layout.rs
+++ b/src/librustc_middle/ty/layout.rs
@@ -2302,10 +2302,19 @@ impl<'tcx> ty::Instance<'tcx> {
         // FIXME(davidtwco,eddyb): A `ParamEnv` should be passed through to this function.
         let ty = self.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(..) = self.def {
                     // Modify `fn(self, ...)` to `fn(self: *mut Self, ...)`.
                     sig = sig.map_bound(|mut sig| {
@@ -2321,13 +2330,15 @@ impl<'tcx> ty::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(
-                    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(
+                        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();
@@ -2343,10 +2354,8 @@ impl<'tcx> ty::Instance<'tcx> {
                 sig.map_bound(|sig| {
                     let state_did = tcx.require_lang_item(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(
@@ -2354,11 +2363,11 @@ impl<'tcx> ty::Instance<'tcx> {
                         &ret_ty,
                         false,
                         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),
         }
     }
 }
diff --git a/src/test/ui/polymorphization/normalized_sig_types.rs b/src/test/ui/polymorphization/normalized_sig_types.rs
new file mode 100644
index 00000000000..fa76b7201e8
--- /dev/null
+++ b/src/test/ui/polymorphization/normalized_sig_types.rs
@@ -0,0 +1,25 @@
+// build-pass
+
+pub trait ParallelIterator: Sized {
+    fn drive<C: Consumer<()>>(_: C) {
+        C::into_folder();
+    }
+}
+
+pub trait Consumer<T>: Sized {
+    type Result;
+    fn into_folder() -> Self::Result;
+}
+
+impl ParallelIterator for () {}
+
+impl<F: Fn(), T> Consumer<T> for F {
+    type Result = ();
+    fn into_folder() -> Self::Result {
+        unimplemented!()
+    }
+}
+
+fn main() {
+    <()>::drive(|| ());
+}