Rollup merge of #104841 - compiler-errors:fishy-bound-var, r=jackh726
Assert that we don't capture escaping bound vars in `Fn` trait selection Fixes #104825
This commit is contained in:
commit
34f1de8395
@ -605,8 +605,10 @@ fn confirm_fn_pointer_candidate(
|
|||||||
{
|
{
|
||||||
debug!(?obligation, "confirm_fn_pointer_candidate");
|
debug!(?obligation, "confirm_fn_pointer_candidate");
|
||||||
|
|
||||||
// Okay to skip binder; it is reintroduced below.
|
let self_ty = self
|
||||||
let self_ty = self.infcx.shallow_resolve(obligation.self_ty().skip_binder());
|
.infcx
|
||||||
|
.shallow_resolve(obligation.self_ty().no_bound_vars())
|
||||||
|
.expect("fn pointer should not capture bound vars from predicate");
|
||||||
let sig = self_ty.fn_sig(self.tcx());
|
let sig = self_ty.fn_sig(self.tcx());
|
||||||
let trait_ref = closure_trait_ref_and_return_type(
|
let trait_ref = closure_trait_ref_and_return_type(
|
||||||
self.tcx(),
|
self.tcx(),
|
||||||
@ -621,15 +623,7 @@ fn confirm_fn_pointer_candidate(
|
|||||||
|
|
||||||
// Confirm the `type Output: Sized;` bound that is present on `FnOnce`
|
// Confirm the `type Output: Sized;` bound that is present on `FnOnce`
|
||||||
let cause = obligation.derived_cause(BuiltinDerivedObligation);
|
let cause = obligation.derived_cause(BuiltinDerivedObligation);
|
||||||
// The binder on the Fn obligation is "less" important than the one on
|
let output_ty = self.infcx.replace_bound_vars_with_placeholders(sig.output());
|
||||||
// the signature, as evidenced by how we treat it during projection.
|
|
||||||
// The safe thing to do here is to liberate it, though, which should
|
|
||||||
// have no worse effect than skipping the binder here.
|
|
||||||
let liberated_fn_ty =
|
|
||||||
self.infcx.replace_bound_vars_with_placeholders(obligation.predicate.rebind(self_ty));
|
|
||||||
let output_ty = self
|
|
||||||
.infcx
|
|
||||||
.replace_bound_vars_with_placeholders(liberated_fn_ty.fn_sig(self.tcx()).output());
|
|
||||||
let output_ty = normalize_with_depth_to(
|
let output_ty = normalize_with_depth_to(
|
||||||
self,
|
self,
|
||||||
obligation.param_env,
|
obligation.param_env,
|
||||||
@ -693,16 +687,19 @@ fn confirm_generator_candidate(
|
|||||||
|
|
||||||
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);
|
||||||
|
@ -2271,15 +2271,19 @@ fn closure_trait_ref_unnormalized(
|
|||||||
|
|
||||||
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,
|
||||||
)
|
)
|
||||||
|
@ -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))
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user