1
Fork 0

Assert that we don't capture escaping bound vars in Fn trait selection

This commit is contained in:
Michael Goulet 2022-11-24 18:45:02 +00:00
parent 5dfb4b0afa
commit 8927135274
3 changed files with 20 additions and 13 deletions

View file

@ -693,16 +693,19 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let gen_sig = substs.as_generator().poly_sig(); let gen_sig = substs.as_generator().poly_sig();
// (1) Feels icky to skip the binder here, but OTOH we know // NOTE: The self-type is a generator type and hence is
// that the self-type is an generator type and hence is
// in fact unparameterized (or at least does not reference any // in fact unparameterized (or at least does not reference any
// regions bound in the obligation). Still probably some // regions bound in the obligation).
// refactoring could make this nicer. let self_ty = obligation
.predicate
.self_ty()
.no_bound_vars()
.expect("unboxed closure type should not capture bound vars from the predicate");
let trait_ref = super::util::generator_trait_ref_and_outputs( let trait_ref = super::util::generator_trait_ref_and_outputs(
self.tcx(), self.tcx(),
obligation.predicate.def_id(), obligation.predicate.def_id(),
obligation.predicate.skip_binder().self_ty(), // (1) self_ty,
gen_sig, gen_sig,
) )
.map_bound(|(trait_ref, ..)| trait_ref); .map_bound(|(trait_ref, ..)| trait_ref);

View file

@ -2271,15 +2271,19 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
debug!(?closure_sig); debug!(?closure_sig);
// (1) Feels icky to skip the binder here, but OTOH we know // NOTE: The self-type is an unboxed closure type and hence is
// that the self-type is an unboxed closure type and hence is
// in fact unparameterized (or at least does not reference any // in fact unparameterized (or at least does not reference any
// regions bound in the obligation). Still probably some // regions bound in the obligation).
// refactoring could make this nicer. let self_ty = obligation
.predicate
.self_ty()
.no_bound_vars()
.expect("unboxed closure type should not capture bound vars from the predicate");
closure_trait_ref_and_return_type( closure_trait_ref_and_return_type(
self.tcx(), self.tcx(),
obligation.predicate.def_id(), obligation.predicate.def_id(),
obligation.predicate.skip_binder().self_ty(), // (1) self_ty,
closure_sig, closure_sig,
util::TupleArgumentsFlag::No, util::TupleArgumentsFlag::No,
) )

View file

@ -298,11 +298,11 @@ pub fn closure_trait_ref_and_return_type<'tcx>(
sig: ty::PolyFnSig<'tcx>, sig: ty::PolyFnSig<'tcx>,
tuple_arguments: TupleArgumentsFlag, tuple_arguments: TupleArgumentsFlag,
) -> ty::Binder<'tcx, (ty::TraitRef<'tcx>, Ty<'tcx>)> { ) -> ty::Binder<'tcx, (ty::TraitRef<'tcx>, Ty<'tcx>)> {
assert!(!self_ty.has_escaping_bound_vars());
let arguments_tuple = match tuple_arguments { let arguments_tuple = match tuple_arguments {
TupleArgumentsFlag::No => sig.skip_binder().inputs()[0], TupleArgumentsFlag::No => sig.skip_binder().inputs()[0],
TupleArgumentsFlag::Yes => tcx.intern_tup(sig.skip_binder().inputs()), TupleArgumentsFlag::Yes => tcx.intern_tup(sig.skip_binder().inputs()),
}; };
debug_assert!(!self_ty.has_escaping_bound_vars());
let trait_ref = tcx.mk_trait_ref(fn_trait_def_id, [self_ty, arguments_tuple]); let trait_ref = tcx.mk_trait_ref(fn_trait_def_id, [self_ty, arguments_tuple]);
sig.map_bound(|sig| (trait_ref, sig.output())) sig.map_bound(|sig| (trait_ref, sig.output()))
} }
@ -313,7 +313,7 @@ pub fn generator_trait_ref_and_outputs<'tcx>(
self_ty: Ty<'tcx>, self_ty: Ty<'tcx>,
sig: ty::PolyGenSig<'tcx>, sig: ty::PolyGenSig<'tcx>,
) -> ty::Binder<'tcx, (ty::TraitRef<'tcx>, Ty<'tcx>, Ty<'tcx>)> { ) -> ty::Binder<'tcx, (ty::TraitRef<'tcx>, Ty<'tcx>, Ty<'tcx>)> {
debug_assert!(!self_ty.has_escaping_bound_vars()); assert!(!self_ty.has_escaping_bound_vars());
let trait_ref = tcx.mk_trait_ref(fn_trait_def_id, [self_ty, sig.skip_binder().resume_ty]); let trait_ref = tcx.mk_trait_ref(fn_trait_def_id, [self_ty, sig.skip_binder().resume_ty]);
sig.map_bound(|sig| (trait_ref, sig.yield_ty, sig.return_ty)) sig.map_bound(|sig| (trait_ref, sig.yield_ty, sig.return_ty))
} }
@ -324,7 +324,7 @@ pub fn future_trait_ref_and_outputs<'tcx>(
self_ty: Ty<'tcx>, self_ty: Ty<'tcx>,
sig: ty::PolyGenSig<'tcx>, sig: ty::PolyGenSig<'tcx>,
) -> ty::Binder<'tcx, (ty::TraitRef<'tcx>, Ty<'tcx>)> { ) -> ty::Binder<'tcx, (ty::TraitRef<'tcx>, Ty<'tcx>)> {
debug_assert!(!self_ty.has_escaping_bound_vars()); assert!(!self_ty.has_escaping_bound_vars());
let trait_ref = tcx.mk_trait_ref(fn_trait_def_id, [self_ty]); let trait_ref = tcx.mk_trait_ref(fn_trait_def_id, [self_ty]);
sig.map_bound(|sig| (trait_ref, sig.return_ty)) sig.map_bound(|sig| (trait_ref, sig.return_ty))
} }