Skip to content

Commit 0161ecd

Browse files
committed
Recover when failing to normalize closure signature.
1 parent 2e45cd4 commit 0161ecd

File tree

7 files changed

+34
-9
lines changed

7 files changed

+34
-9
lines changed

compiler/rustc_codegen_cranelift/src/base.rs

+1
Original file line numberDiff line numberDiff line change
@@ -686,6 +686,7 @@ fn codegen_stmt<'tcx>(
686686
substs,
687687
ty::ClosureKind::FnOnce,
688688
)
689+
.expect("failed to normalize and resolve closure during codegen")
689690
.polymorphize(fx.tcx);
690691
let func_ref = fx.get_function_ref(instance);
691692
let func_addr = fx.bcx.ins().func_addr(fx.pointer_type, func_ref);

compiler/rustc_codegen_ssa/src/mir/rvalue.rs

+1
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
213213
substs,
214214
ty::ClosureKind::FnOnce,
215215
)
216+
.expect("failed to normalize and resolve closure during codegen")
216217
.polymorphize(bx.cx().tcx());
217218
OperandValue::Immediate(bx.cx().get_fn_addr(instance))
218219
}

compiler/rustc_const_eval/src/interpret/cast.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
100100
def_id,
101101
substs,
102102
ty::ClosureKind::FnOnce,
103-
);
103+
)
104+
.ok_or_else(|| err_inval!(TooGeneric))?;
104105
let fn_ptr = self.create_fn_alloc_ptr(FnVal::Instance(instance));
105106
self.write_pointer(fn_ptr, dest)?;
106107
}

compiler/rustc_middle/src/ty/instance.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -496,12 +496,12 @@ impl<'tcx> Instance<'tcx> {
496496
def_id: DefId,
497497
substs: ty::SubstsRef<'tcx>,
498498
requested_kind: ty::ClosureKind,
499-
) -> Instance<'tcx> {
499+
) -> Option<Instance<'tcx>> {
500500
let actual_kind = substs.as_closure().kind();
501501

502502
match needs_fn_once_adapter_shim(actual_kind, requested_kind) {
503503
Ok(true) => Instance::fn_once_adapter_instance(tcx, def_id, substs),
504-
_ => Instance::new(def_id, substs),
504+
_ => Some(Instance::new(def_id, substs)),
505505
}
506506
}
507507

@@ -515,7 +515,7 @@ impl<'tcx> Instance<'tcx> {
515515
tcx: TyCtxt<'tcx>,
516516
closure_did: DefId,
517517
substs: ty::SubstsRef<'tcx>,
518-
) -> Instance<'tcx> {
518+
) -> Option<Instance<'tcx>> {
519519
debug!("fn_once_adapter_shim({:?}, {:?})", closure_did, substs);
520520
let fn_once = tcx.require_lang_item(LangItem::FnOnce, None);
521521
let call_once = tcx
@@ -531,12 +531,13 @@ impl<'tcx> Instance<'tcx> {
531531
let self_ty = tcx.mk_closure(closure_did, substs);
532532

533533
let sig = substs.as_closure().sig();
534-
let sig = tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), sig);
534+
let sig =
535+
tcx.try_normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), sig).ok()?;
535536
assert_eq!(sig.inputs().len(), 1);
536537
let substs = tcx.mk_substs_trait(self_ty, &[sig.inputs()[0].into()]);
537538

538539
debug!("fn_once_adapter_shim: self_ty={:?} sig={:?}", self_ty, sig);
539-
Instance { def, substs }
540+
Some(Instance { def, substs })
540541
}
541542

542543
/// Depending on the kind of `InstanceDef`, the MIR body associated with an

compiler/rustc_middle/src/ty/normalize_erasing_regions.rs

+20
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,26 @@ impl<'tcx> TyCtxt<'tcx> {
112112
self.normalize_erasing_regions(param_env, value)
113113
}
114114

115+
/// If you have a `Binder<'tcx, T>`, you can do this to strip out the
116+
/// late-bound regions and then normalize the result, yielding up
117+
/// a `T` (with regions erased). This is appropriate when the
118+
/// binder is being instantiated at the call site.
119+
///
120+
/// N.B., currently, higher-ranked type bounds inhibit
121+
/// normalization. Therefore, each time we erase them in
122+
/// codegen, we need to normalize the contents.
123+
pub fn try_normalize_erasing_late_bound_regions<T>(
124+
self,
125+
param_env: ty::ParamEnv<'tcx>,
126+
value: ty::Binder<'tcx, T>,
127+
) -> Result<T, NormalizationError<'tcx>>
128+
where
129+
T: TypeFoldable<'tcx>,
130+
{
131+
let value = self.erase_late_bound_regions(value);
132+
self.try_normalize_erasing_regions(param_env, value)
133+
}
134+
115135
/// Monomorphizes a type from the AST by first applying the
116136
/// in-scope substitutions and then normalizing any associated
117137
/// types.

compiler/rustc_monomorphize/src/collector.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -730,7 +730,8 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
730730
def_id,
731731
substs,
732732
ty::ClosureKind::FnOnce,
733-
);
733+
)
734+
.expect("failed to normalize and resolve closure during codegen");
734735
if should_codegen_locally(self.tcx, &instance) {
735736
self.output.push(create_fn_mono_item(self.tcx, instance, span));
736737
}

compiler/rustc_ty_utils/src/instance.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -332,12 +332,12 @@ fn resolve_associated_item<'tcx>(
332332
}),
333333
traits::ImplSource::Closure(closure_data) => {
334334
let trait_closure_kind = tcx.fn_trait_kind_from_lang_item(trait_id).unwrap();
335-
Some(Instance::resolve_closure(
335+
Instance::resolve_closure(
336336
tcx,
337337
closure_data.closure_def_id,
338338
closure_data.substs,
339339
trait_closure_kind,
340-
))
340+
)
341341
}
342342
traits::ImplSource::FnPointer(ref data) => match data.fn_ty.kind() {
343343
ty::FnDef(..) | ty::FnPtr(..) => Some(Instance {

0 commit comments

Comments
 (0)