Recover when failing to normalize closure signature.
This commit is contained in:
parent
2e45cd4b69
commit
0161ecd13f
@ -686,6 +686,7 @@ fn is_fat_ptr<'tcx>(fx: &FunctionCx<'_, '_, 'tcx>, ty: Ty<'tcx>) -> bool {
|
||||
substs,
|
||||
ty::ClosureKind::FnOnce,
|
||||
)
|
||||
.expect("failed to normalize and resolve closure during codegen")
|
||||
.polymorphize(fx.tcx);
|
||||
let func_ref = fx.get_function_ref(instance);
|
||||
let func_addr = fx.bcx.ins().func_addr(fx.pointer_type, func_ref);
|
||||
|
@ -213,6 +213,7 @@ pub fn codegen_rvalue_operand(
|
||||
substs,
|
||||
ty::ClosureKind::FnOnce,
|
||||
)
|
||||
.expect("failed to normalize and resolve closure during codegen")
|
||||
.polymorphize(bx.cx().tcx());
|
||||
OperandValue::Immediate(bx.cx().get_fn_addr(instance))
|
||||
}
|
||||
|
@ -100,7 +100,8 @@ pub fn cast(
|
||||
def_id,
|
||||
substs,
|
||||
ty::ClosureKind::FnOnce,
|
||||
);
|
||||
)
|
||||
.ok_or_else(|| err_inval!(TooGeneric))?;
|
||||
let fn_ptr = self.create_fn_alloc_ptr(FnVal::Instance(instance));
|
||||
self.write_pointer(fn_ptr, dest)?;
|
||||
}
|
||||
|
@ -496,12 +496,12 @@ pub fn resolve_closure(
|
||||
def_id: DefId,
|
||||
substs: ty::SubstsRef<'tcx>,
|
||||
requested_kind: ty::ClosureKind,
|
||||
) -> Instance<'tcx> {
|
||||
) -> Option<Instance<'tcx>> {
|
||||
let actual_kind = substs.as_closure().kind();
|
||||
|
||||
match needs_fn_once_adapter_shim(actual_kind, requested_kind) {
|
||||
Ok(true) => Instance::fn_once_adapter_instance(tcx, def_id, substs),
|
||||
_ => Instance::new(def_id, substs),
|
||||
_ => Some(Instance::new(def_id, substs)),
|
||||
}
|
||||
}
|
||||
|
||||
@ -515,7 +515,7 @@ pub fn fn_once_adapter_instance(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
closure_did: DefId,
|
||||
substs: ty::SubstsRef<'tcx>,
|
||||
) -> Instance<'tcx> {
|
||||
) -> Option<Instance<'tcx>> {
|
||||
debug!("fn_once_adapter_shim({:?}, {:?})", closure_did, substs);
|
||||
let fn_once = tcx.require_lang_item(LangItem::FnOnce, None);
|
||||
let call_once = tcx
|
||||
@ -531,12 +531,13 @@ pub fn fn_once_adapter_instance(
|
||||
let self_ty = tcx.mk_closure(closure_did, substs);
|
||||
|
||||
let sig = substs.as_closure().sig();
|
||||
let sig = tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), sig);
|
||||
let sig =
|
||||
tcx.try_normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), sig).ok()?;
|
||||
assert_eq!(sig.inputs().len(), 1);
|
||||
let substs = tcx.mk_substs_trait(self_ty, &[sig.inputs()[0].into()]);
|
||||
|
||||
debug!("fn_once_adapter_shim: self_ty={:?} sig={:?}", self_ty, sig);
|
||||
Instance { def, substs }
|
||||
Some(Instance { def, substs })
|
||||
}
|
||||
|
||||
/// Depending on the kind of `InstanceDef`, the MIR body associated with an
|
||||
|
@ -112,6 +112,26 @@ pub fn normalize_erasing_late_bound_regions<T>(
|
||||
self.normalize_erasing_regions(param_env, value)
|
||||
}
|
||||
|
||||
/// If you have a `Binder<'tcx, T>`, you can do this to strip out the
|
||||
/// late-bound regions and then normalize the result, yielding up
|
||||
/// a `T` (with regions erased). This is appropriate when the
|
||||
/// binder is being instantiated at the call site.
|
||||
///
|
||||
/// N.B., currently, higher-ranked type bounds inhibit
|
||||
/// normalization. Therefore, each time we erase them in
|
||||
/// codegen, we need to normalize the contents.
|
||||
pub fn try_normalize_erasing_late_bound_regions<T>(
|
||||
self,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
value: ty::Binder<'tcx, T>,
|
||||
) -> Result<T, NormalizationError<'tcx>>
|
||||
where
|
||||
T: TypeFoldable<'tcx>,
|
||||
{
|
||||
let value = self.erase_late_bound_regions(value);
|
||||
self.try_normalize_erasing_regions(param_env, value)
|
||||
}
|
||||
|
||||
/// Monomorphizes a type from the AST by first applying the
|
||||
/// in-scope substitutions and then normalizing any associated
|
||||
/// types.
|
||||
|
@ -730,7 +730,8 @@ fn visit_rvalue(&mut self, rvalue: &mir::Rvalue<'tcx>, location: Location) {
|
||||
def_id,
|
||||
substs,
|
||||
ty::ClosureKind::FnOnce,
|
||||
);
|
||||
)
|
||||
.expect("failed to normalize and resolve closure during codegen");
|
||||
if should_codegen_locally(self.tcx, &instance) {
|
||||
self.output.push(create_fn_mono_item(self.tcx, instance, span));
|
||||
}
|
||||
|
@ -332,12 +332,12 @@ fn resolve_associated_item<'tcx>(
|
||||
}),
|
||||
traits::ImplSource::Closure(closure_data) => {
|
||||
let trait_closure_kind = tcx.fn_trait_kind_from_lang_item(trait_id).unwrap();
|
||||
Some(Instance::resolve_closure(
|
||||
Instance::resolve_closure(
|
||||
tcx,
|
||||
closure_data.closure_def_id,
|
||||
closure_data.substs,
|
||||
trait_closure_kind,
|
||||
))
|
||||
)
|
||||
}
|
||||
traits::ImplSource::FnPointer(ref data) => match data.fn_ty.kind() {
|
||||
ty::FnDef(..) | ty::FnPtr(..) => Some(Instance {
|
||||
|
Loading…
Reference in New Issue
Block a user