Skip to content

Commit f52c729

Browse files
committed
ty: normalize fn sigs before subst
This commit normalizes function signatures for instances before substituting, a workaround for polymorphization considering parameters unused when they show up in the signature, but not the body (due to being normalized). Unfortunately, this causes test output to change with the parallel compiler only. Signed-off-by: David Wood <[email protected]>
1 parent 2989fea commit f52c729

File tree

2 files changed

+51
-17
lines changed

2 files changed

+51
-17
lines changed

src/librustc_middle/ty/layout.rs

+26-17
Original file line numberDiff line numberDiff line change
@@ -2302,10 +2302,19 @@ impl<'tcx> ty::Instance<'tcx> {
23022302
// FIXME(davidtwco,eddyb): A `ParamEnv` should be passed through to this function.
23032303
let ty = self.ty(tcx, ty::ParamEnv::reveal_all());
23042304
match ty.kind {
2305-
ty::FnDef(..) |
2306-
// Shims currently have type FnPtr. Not sure this should remain.
2307-
ty::FnPtr(_) => {
2308-
let mut sig = ty.fn_sig(tcx);
2305+
ty::FnDef(..) => {
2306+
// HACK(davidtwco,eddyb): This is a workaround for polymorphization considering
2307+
// parameters unused if they show up in the signature, but not in the `mir::Body`
2308+
// (i.e. due to being inside a projection that got normalized, see
2309+
// `src/test/ui/polymorphization/normalized_sig_types.rs`), and codegen not keeping
2310+
// track of a polymorphization `ParamEnv` to allow normalizing later.
2311+
let mut sig = match ty.kind {
2312+
ty::FnDef(def_id, substs) => tcx
2313+
.normalize_erasing_regions(tcx.param_env(def_id), tcx.fn_sig(def_id))
2314+
.subst(tcx, substs),
2315+
_ => unreachable!(),
2316+
};
2317+
23092318
if let ty::InstanceDef::VtableShim(..) = self.def {
23102319
// Modify `fn(self, ...)` to `fn(self: *mut Self, ...)`.
23112320
sig = sig.map_bound(|mut sig| {
@@ -2321,13 +2330,15 @@ impl<'tcx> ty::Instance<'tcx> {
23212330
let sig = substs.as_closure().sig();
23222331

23232332
let env_ty = tcx.closure_env_ty(def_id, substs).unwrap();
2324-
sig.map_bound(|sig| tcx.mk_fn_sig(
2325-
iter::once(env_ty.skip_binder()).chain(sig.inputs().iter().cloned()),
2326-
sig.output(),
2327-
sig.c_variadic,
2328-
sig.unsafety,
2329-
sig.abi
2330-
))
2333+
sig.map_bound(|sig| {
2334+
tcx.mk_fn_sig(
2335+
iter::once(env_ty.skip_binder()).chain(sig.inputs().iter().cloned()),
2336+
sig.output(),
2337+
sig.c_variadic,
2338+
sig.unsafety,
2339+
sig.abi,
2340+
)
2341+
})
23312342
}
23322343
ty::Generator(_, substs, _) => {
23332344
let sig = substs.as_generator().poly_sig();
@@ -2343,22 +2354,20 @@ impl<'tcx> ty::Instance<'tcx> {
23432354
sig.map_bound(|sig| {
23442355
let state_did = tcx.require_lang_item(GeneratorStateLangItem, None);
23452356
let state_adt_ref = tcx.adt_def(state_did);
2346-
let state_substs = tcx.intern_substs(&[
2347-
sig.yield_ty.into(),
2348-
sig.return_ty.into(),
2349-
]);
2357+
let state_substs =
2358+
tcx.intern_substs(&[sig.yield_ty.into(), sig.return_ty.into()]);
23502359
let ret_ty = tcx.mk_adt(state_adt_ref, state_substs);
23512360

23522361
tcx.mk_fn_sig(
23532362
[env_ty, sig.resume_ty].iter(),
23542363
&ret_ty,
23552364
false,
23562365
hir::Unsafety::Normal,
2357-
rustc_target::spec::abi::Abi::Rust
2366+
rustc_target::spec::abi::Abi::Rust,
23582367
)
23592368
})
23602369
}
2361-
_ => bug!("unexpected type {:?} in Instance::fn_sig", ty)
2370+
_ => bug!("unexpected type {:?} in Instance::fn_sig", ty),
23622371
}
23632372
}
23642373
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// build-pass
2+
3+
pub trait ParallelIterator: Sized {
4+
fn drive<C: Consumer<()>>(_: C) {
5+
C::into_folder();
6+
}
7+
}
8+
9+
pub trait Consumer<T>: Sized {
10+
type Result;
11+
fn into_folder() -> Self::Result;
12+
}
13+
14+
impl ParallelIterator for () {}
15+
16+
impl<F: Fn(), T> Consumer<T> for F {
17+
type Result = ();
18+
fn into_folder() -> Self::Result {
19+
unimplemented!()
20+
}
21+
}
22+
23+
fn main() {
24+
<()>::drive(|| ());
25+
}

0 commit comments

Comments
 (0)