expand WF obligations when checking method calls

This commit is contained in:
Michael Goulet 2025-07-30 20:57:00 +00:00
parent e5e79f8bd4
commit 170ccbf434
3 changed files with 30 additions and 35 deletions

View file

@ -356,14 +356,14 @@ fn compare_method_predicate_entailment<'tcx>(
}
if !(impl_sig, trait_sig).references_error() {
ocx.register_obligation(traits::Obligation::new(
infcx.tcx,
cause,
param_env,
ty::ClauseKind::WellFormed(
Ty::new_fn_ptr(tcx, ty::Binder::dummy(unnormalized_impl_sig)).into(),
),
));
for ty in unnormalized_impl_sig.inputs_and_output {
ocx.register_obligation(traits::Obligation::new(
infcx.tcx,
cause.clone(),
param_env,
ty::ClauseKind::WellFormed(ty.into()),
));
}
}
// Check that all obligations are satisfied by the implementation's

View file

@ -142,7 +142,6 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
let (method_sig, method_predicates) =
self.normalize(self.span, (method_sig, method_predicates));
let method_sig = ty::Binder::dummy(method_sig);
// Make sure nobody calls `drop()` explicitly.
self.check_for_illegal_method_calls(pick);
@ -154,20 +153,11 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
// We won't add these if we encountered an illegal sized bound, so that we can use
// a custom error in that case.
if illegal_sized_bound.is_none() {
self.add_obligations(
Ty::new_fn_ptr(self.tcx, method_sig),
all_args,
method_predicates,
pick.item.def_id,
);
self.add_obligations(method_sig, all_args, method_predicates, pick.item.def_id);
}
// Create the final `MethodCallee`.
let callee = MethodCallee {
def_id: pick.item.def_id,
args: all_args,
sig: method_sig.skip_binder(),
};
let callee = MethodCallee { def_id: pick.item.def_id, args: all_args, sig: method_sig };
ConfirmResult { callee, illegal_sized_bound }
}
@ -601,14 +591,14 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
fn add_obligations(
&mut self,
fty: Ty<'tcx>,
sig: ty::FnSig<'tcx>,
all_args: GenericArgsRef<'tcx>,
method_predicates: ty::InstantiatedPredicates<'tcx>,
def_id: DefId,
) {
debug!(
"add_obligations: fty={:?} all_args={:?} method_predicates={:?} def_id={:?}",
fty, all_args, method_predicates, def_id
"add_obligations: sig={:?} all_args={:?} method_predicates={:?} def_id={:?}",
sig, all_args, method_predicates, def_id
);
// FIXME: could replace with the following, but we already calculated `method_predicates`,
@ -637,7 +627,13 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
// the function type must also be well-formed (this is not
// implied by the args being well-formed because of inherent
// impls and late-bound regions - see issue #28609).
self.register_wf_obligation(fty.into(), self.span, ObligationCauseCode::WellFormed(None));
for ty in sig.inputs_and_output {
self.register_wf_obligation(
ty.into(),
self.span,
ObligationCauseCode::WellFormed(None),
);
}
}
///////////////////////////////////////////////////////////////////////////

View file

@ -428,19 +428,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
));
// Also add an obligation for the method type being well-formed.
let method_ty = Ty::new_fn_ptr(tcx, ty::Binder::dummy(fn_sig));
debug!(
"lookup_method_in_trait: matched method method_ty={:?} obligation={:?}",
method_ty, obligation
"lookup_method_in_trait: matched method fn_sig={:?} obligation={:?}",
fn_sig, obligation
);
obligations.push(traits::Obligation::new(
tcx,
obligation.cause,
self.param_env,
ty::Binder::dummy(ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(
method_ty.into(),
))),
));
for ty in fn_sig.inputs_and_output {
obligations.push(traits::Obligation::new(
tcx,
obligation.cause.clone(),
self.param_env,
ty::Binder::dummy(ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(ty.into()))),
));
}
let callee = MethodCallee { def_id, args, sig: fn_sig };
debug!("callee = {:?}", callee);