1
Fork 0

Instantiate binder before registering nested obligations for auto/built-in traits

This commit is contained in:
Michael Goulet 2025-03-24 17:09:48 +00:00
parent f8c27dfe1a
commit 93b3be3300
2 changed files with 16 additions and 32 deletions

View file

@ -266,9 +266,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
} else { } else {
bug!("unexpected builtin trait {:?}", trait_def) bug!("unexpected builtin trait {:?}", trait_def)
}; };
let BuiltinImplConditions::Where(nested) = conditions else { let BuiltinImplConditions::Where(types) = conditions else {
bug!("obligation {:?} had matched a builtin impl but now doesn't", obligation); bug!("obligation {:?} had matched a builtin impl but now doesn't", obligation);
}; };
let types = self.infcx.enter_forall_and_leak_universe(types);
let cause = obligation.derived_cause(ObligationCauseCode::BuiltinDerived); let cause = obligation.derived_cause(ObligationCauseCode::BuiltinDerived);
self.collect_predicates_for_types( self.collect_predicates_for_types(
@ -276,7 +277,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
cause, cause,
obligation.recursion_depth + 1, obligation.recursion_depth + 1,
trait_def, trait_def,
nested, types,
) )
} else { } else {
PredicateObligations::new() PredicateObligations::new()
@ -444,37 +445,25 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
&mut self, &mut self,
obligation: &PolyTraitObligation<'tcx>, obligation: &PolyTraitObligation<'tcx>,
) -> Result<PredicateObligations<'tcx>, SelectionError<'tcx>> { ) -> Result<PredicateObligations<'tcx>, SelectionError<'tcx>> {
debug!(?obligation, "confirm_auto_impl_candidate");
let self_ty = obligation.predicate.self_ty().map_bound(|ty| self.infcx.shallow_resolve(ty));
let types = self.constituent_types_for_ty(self_ty)?;
Ok(self.vtable_auto_impl(obligation, obligation.predicate.def_id(), types))
}
/// See `confirm_auto_impl_candidate`.
fn vtable_auto_impl(
&mut self,
obligation: &PolyTraitObligation<'tcx>,
trait_def_id: DefId,
nested: ty::Binder<'tcx, Vec<Ty<'tcx>>>,
) -> PredicateObligations<'tcx> {
debug!(?nested, "vtable_auto_impl");
ensure_sufficient_stack(|| { ensure_sufficient_stack(|| {
let cause = obligation.derived_cause(ObligationCauseCode::BuiltinDerived);
assert_eq!(obligation.predicate.polarity(), ty::PredicatePolarity::Positive); assert_eq!(obligation.predicate.polarity(), ty::PredicatePolarity::Positive);
let self_ty =
obligation.predicate.self_ty().map_bound(|ty| self.infcx.shallow_resolve(ty));
let types = self.constituent_types_for_ty(self_ty)?;
let types = self.infcx.enter_forall_and_leak_universe(types);
let cause = obligation.derived_cause(ObligationCauseCode::BuiltinDerived);
let obligations = self.collect_predicates_for_types( let obligations = self.collect_predicates_for_types(
obligation.param_env, obligation.param_env,
cause, cause,
obligation.recursion_depth + 1, obligation.recursion_depth + 1,
trait_def_id, obligation.predicate.def_id(),
nested, types,
); );
debug!(?obligations, "vtable_auto_impl"); Ok(obligations)
obligations
}) })
} }

View file

@ -2370,7 +2370,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
cause: ObligationCause<'tcx>, cause: ObligationCause<'tcx>,
recursion_depth: usize, recursion_depth: usize,
trait_def_id: DefId, trait_def_id: DefId,
types: ty::Binder<'tcx, Vec<Ty<'tcx>>>, types: Vec<Ty<'tcx>>,
) -> PredicateObligations<'tcx> { ) -> PredicateObligations<'tcx> {
// Because the types were potentially derived from // Because the types were potentially derived from
// higher-ranked obligations they may reference late-bound // higher-ranked obligations they may reference late-bound
@ -2387,13 +2387,8 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
// 3. Re-bind the regions back to `for<'a> &'a i32 : Copy` // 3. Re-bind the regions back to `for<'a> &'a i32 : Copy`
types types
.as_ref() .into_iter()
.skip_binder() // binder moved -\ .flat_map(|placeholder_ty| {
.iter()
.flat_map(|ty| {
let ty: ty::Binder<'tcx, Ty<'tcx>> = types.rebind(*ty); // <----/
let placeholder_ty = self.infcx.enter_forall_and_leak_universe(ty);
let Normalized { value: normalized_ty, mut obligations } = let Normalized { value: normalized_ty, mut obligations } =
ensure_sufficient_stack(|| { ensure_sufficient_stack(|| {
normalize_with_depth( normalize_with_depth(