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,
|
substs,
|
||||||
ty::ClosureKind::FnOnce,
|
ty::ClosureKind::FnOnce,
|
||||||
)
|
)
|
||||||
|
.expect("failed to normalize and resolve closure during codegen")
|
||||||
.polymorphize(fx.tcx);
|
.polymorphize(fx.tcx);
|
||||||
let func_ref = fx.get_function_ref(instance);
|
let func_ref = fx.get_function_ref(instance);
|
||||||
let func_addr = fx.bcx.ins().func_addr(fx.pointer_type, func_ref);
|
let func_addr = fx.bcx.ins().func_addr(fx.pointer_type, func_ref);
|
||||||
|
@ -213,6 +213,7 @@ pub fn codegen_rvalue_operand(
|
|||||||
substs,
|
substs,
|
||||||
ty::ClosureKind::FnOnce,
|
ty::ClosureKind::FnOnce,
|
||||||
)
|
)
|
||||||
|
.expect("failed to normalize and resolve closure during codegen")
|
||||||
.polymorphize(bx.cx().tcx());
|
.polymorphize(bx.cx().tcx());
|
||||||
OperandValue::Immediate(bx.cx().get_fn_addr(instance))
|
OperandValue::Immediate(bx.cx().get_fn_addr(instance))
|
||||||
}
|
}
|
||||||
|
@ -100,7 +100,8 @@ pub fn cast(
|
|||||||
def_id,
|
def_id,
|
||||||
substs,
|
substs,
|
||||||
ty::ClosureKind::FnOnce,
|
ty::ClosureKind::FnOnce,
|
||||||
);
|
)
|
||||||
|
.ok_or_else(|| err_inval!(TooGeneric))?;
|
||||||
let fn_ptr = self.create_fn_alloc_ptr(FnVal::Instance(instance));
|
let fn_ptr = self.create_fn_alloc_ptr(FnVal::Instance(instance));
|
||||||
self.write_pointer(fn_ptr, dest)?;
|
self.write_pointer(fn_ptr, dest)?;
|
||||||
}
|
}
|
||||||
|
@ -496,12 +496,12 @@ pub fn resolve_closure(
|
|||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
substs: ty::SubstsRef<'tcx>,
|
substs: ty::SubstsRef<'tcx>,
|
||||||
requested_kind: ty::ClosureKind,
|
requested_kind: ty::ClosureKind,
|
||||||
) -> Instance<'tcx> {
|
) -> Option<Instance<'tcx>> {
|
||||||
let actual_kind = substs.as_closure().kind();
|
let actual_kind = substs.as_closure().kind();
|
||||||
|
|
||||||
match needs_fn_once_adapter_shim(actual_kind, requested_kind) {
|
match needs_fn_once_adapter_shim(actual_kind, requested_kind) {
|
||||||
Ok(true) => Instance::fn_once_adapter_instance(tcx, def_id, substs),
|
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>,
|
tcx: TyCtxt<'tcx>,
|
||||||
closure_did: DefId,
|
closure_did: DefId,
|
||||||
substs: ty::SubstsRef<'tcx>,
|
substs: ty::SubstsRef<'tcx>,
|
||||||
) -> Instance<'tcx> {
|
) -> Option<Instance<'tcx>> {
|
||||||
debug!("fn_once_adapter_shim({:?}, {:?})", closure_did, substs);
|
debug!("fn_once_adapter_shim({:?}, {:?})", closure_did, substs);
|
||||||
let fn_once = tcx.require_lang_item(LangItem::FnOnce, None);
|
let fn_once = tcx.require_lang_item(LangItem::FnOnce, None);
|
||||||
let call_once = tcx
|
let call_once = tcx
|
||||||
@ -531,12 +531,13 @@ pub fn fn_once_adapter_instance(
|
|||||||
let self_ty = tcx.mk_closure(closure_did, substs);
|
let self_ty = tcx.mk_closure(closure_did, substs);
|
||||||
|
|
||||||
let sig = substs.as_closure().sig();
|
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);
|
assert_eq!(sig.inputs().len(), 1);
|
||||||
let substs = tcx.mk_substs_trait(self_ty, &[sig.inputs()[0].into()]);
|
let substs = tcx.mk_substs_trait(self_ty, &[sig.inputs()[0].into()]);
|
||||||
|
|
||||||
debug!("fn_once_adapter_shim: self_ty={:?} sig={:?}", self_ty, sig);
|
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
|
/// 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)
|
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
|
/// Monomorphizes a type from the AST by first applying the
|
||||||
/// in-scope substitutions and then normalizing any associated
|
/// in-scope substitutions and then normalizing any associated
|
||||||
/// types.
|
/// types.
|
||||||
|
@ -730,7 +730,8 @@ fn visit_rvalue(&mut self, rvalue: &mir::Rvalue<'tcx>, location: Location) {
|
|||||||
def_id,
|
def_id,
|
||||||
substs,
|
substs,
|
||||||
ty::ClosureKind::FnOnce,
|
ty::ClosureKind::FnOnce,
|
||||||
);
|
)
|
||||||
|
.expect("failed to normalize and resolve closure during codegen");
|
||||||
if should_codegen_locally(self.tcx, &instance) {
|
if should_codegen_locally(self.tcx, &instance) {
|
||||||
self.output.push(create_fn_mono_item(self.tcx, instance, span));
|
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) => {
|
traits::ImplSource::Closure(closure_data) => {
|
||||||
let trait_closure_kind = tcx.fn_trait_kind_from_lang_item(trait_id).unwrap();
|
let trait_closure_kind = tcx.fn_trait_kind_from_lang_item(trait_id).unwrap();
|
||||||
Some(Instance::resolve_closure(
|
Instance::resolve_closure(
|
||||||
tcx,
|
tcx,
|
||||||
closure_data.closure_def_id,
|
closure_data.closure_def_id,
|
||||||
closure_data.substs,
|
closure_data.substs,
|
||||||
trait_closure_kind,
|
trait_closure_kind,
|
||||||
))
|
)
|
||||||
}
|
}
|
||||||
traits::ImplSource::FnPointer(ref data) => match data.fn_ty.kind() {
|
traits::ImplSource::FnPointer(ref data) => match data.fn_ty.kind() {
|
||||||
ty::FnDef(..) | ty::FnPtr(..) => Some(Instance {
|
ty::FnDef(..) | ty::FnPtr(..) => Some(Instance {
|
||||||
|
Loading…
Reference in New Issue
Block a user