From 5999f34ff600b64c208e9d7cff6e1e7d1bb1662d Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Thu, 30 Sep 2021 21:58:49 -0400 Subject: Don't assert polymorphization has taken effect in const eval Const eval no longer runs MIR optimizations so unless this is getting run as part of a MIR optimization like const-prop, there can be unused type parameters even if polymorphization is enabled. --- compiler/rustc_const_eval/src/interpret/util.rs | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) (limited to 'compiler/rustc_const_eval/src') diff --git a/compiler/rustc_const_eval/src/interpret/util.rs b/compiler/rustc_const_eval/src/interpret/util.rs index b9866995e9f..9d7905ed9a8 100644 --- a/compiler/rustc_const_eval/src/interpret/util.rs +++ b/compiler/rustc_const_eval/src/interpret/util.rs @@ -44,22 +44,10 @@ where let is_used = unused_params.contains(index).map_or(true, |unused| !unused); // Only recurse when generic parameters in fns, closures and generators // are used and require substitution. - match (is_used, subst.needs_subst()) { - // Just in case there are closures or generators within this subst, - // recurse. - (true, true) => return subst.visit_with(self), - // Confirm that polymorphization replaced the parameter with - // `ty::Param`/`ty::ConstKind::Param`. - (false, true) if cfg!(debug_assertions) => match subst.unpack() { - ty::subst::GenericArgKind::Type(ty) => { - assert!(matches!(ty.kind(), ty::Param(_))) - } - ty::subst::GenericArgKind::Const(ct) => { - assert!(matches!(ct.kind(), ty::ConstKind::Param(_))) - } - ty::subst::GenericArgKind::Lifetime(..) => (), - }, - _ => {} + // Just in case there are closures or generators within this subst, + // recurse. + if is_used && subst.needs_subst() { + return subst.visit_with(self); } } ControlFlow::CONTINUE -- cgit 1.4.1-3-g733a5 From 0161ecd13f31d3521791d419522bab55eabfa717 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Fri, 4 Feb 2022 23:18:28 +0100 Subject: Recover when failing to normalize closure signature. --- compiler/rustc_codegen_cranelift/src/base.rs | 1 + compiler/rustc_codegen_ssa/src/mir/rvalue.rs | 1 + compiler/rustc_const_eval/src/interpret/cast.rs | 3 ++- compiler/rustc_middle/src/ty/instance.rs | 11 ++++++----- .../rustc_middle/src/ty/normalize_erasing_regions.rs | 20 ++++++++++++++++++++ compiler/rustc_monomorphize/src/collector.rs | 3 ++- compiler/rustc_ty_utils/src/instance.rs | 4 ++-- 7 files changed, 34 insertions(+), 9 deletions(-) (limited to 'compiler/rustc_const_eval/src') diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs index fbe830b2b10..fa4ea426385 100644 --- a/compiler/rustc_codegen_cranelift/src/base.rs +++ b/compiler/rustc_codegen_cranelift/src/base.rs @@ -686,6 +686,7 @@ fn codegen_stmt<'tcx>( 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); diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index 81c1897694c..a5806d64d43 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -213,6 +213,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { 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)) } diff --git a/compiler/rustc_const_eval/src/interpret/cast.rs b/compiler/rustc_const_eval/src/interpret/cast.rs index 076415b2d1b..dfdcd4292c9 100644 --- a/compiler/rustc_const_eval/src/interpret/cast.rs +++ b/compiler/rustc_const_eval/src/interpret/cast.rs @@ -100,7 +100,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { 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)?; } diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index e8dd179eac1..0e10fe25c10 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -496,12 +496,12 @@ impl<'tcx> Instance<'tcx> { def_id: DefId, substs: ty::SubstsRef<'tcx>, requested_kind: ty::ClosureKind, - ) -> Instance<'tcx> { + ) -> Option> { 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 @@ impl<'tcx> Instance<'tcx> { tcx: TyCtxt<'tcx>, closure_did: DefId, substs: ty::SubstsRef<'tcx>, - ) -> Instance<'tcx> { + ) -> Option> { 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 @@ impl<'tcx> Instance<'tcx> { 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 diff --git a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs index 66a0a192a87..9d8a8116594 100644 --- a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs +++ b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs @@ -112,6 +112,26 @@ impl<'tcx> TyCtxt<'tcx> { 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( + self, + param_env: ty::ParamEnv<'tcx>, + value: ty::Binder<'tcx, T>, + ) -> Result> + 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. diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 2af22e129a5..d4978c56568 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -730,7 +730,8 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { 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)); } diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index 552db5406df..d08fe6dada1 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -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 { -- cgit 1.4.1-3-g733a5