1
Fork 0

Check FnPtr/FnDef built-in fn traits correctly with effects

This commit is contained in:
Michael Goulet 2023-12-16 19:21:43 +00:00
parent 2a7634047a
commit 69f360d00c
7 changed files with 84 additions and 24 deletions

View file

@ -2327,8 +2327,9 @@ fn confirm_fn_pointer_candidate<'cx, 'tcx>(
obligation: &ProjectionTyObligation<'tcx>,
nested: Vec<PredicateObligation<'tcx>>,
) -> Progress<'tcx> {
let tcx = selcx.tcx();
let fn_type = selcx.infcx.shallow_resolve(obligation.predicate.self_ty());
let sig = fn_type.fn_sig(selcx.tcx());
let sig = fn_type.fn_sig(tcx);
let Normalized { value: sig, obligations } = normalize_with_depth(
selcx,
obligation.param_env,
@ -2337,9 +2338,24 @@ fn confirm_fn_pointer_candidate<'cx, 'tcx>(
sig,
);
confirm_callable_candidate(selcx, obligation, sig, util::TupleArgumentsFlag::Yes)
.with_addl_obligations(nested)
.with_addl_obligations(obligations)
let host_effect_param = match *fn_type.kind() {
ty::FnDef(def_id, args) => tcx
.generics_of(def_id)
.host_effect_index
.map_or(tcx.consts.true_, |idx| args.const_at(idx)),
ty::FnPtr(_) => tcx.consts.true_,
_ => unreachable!("only expected FnPtr or FnDef in `confirm_fn_pointer_candidate`"),
};
confirm_callable_candidate(
selcx,
obligation,
sig,
util::TupleArgumentsFlag::Yes,
host_effect_param,
)
.with_addl_obligations(nested)
.with_addl_obligations(obligations)
}
fn confirm_closure_candidate<'cx, 'tcx>(
@ -2362,9 +2378,16 @@ fn confirm_closure_candidate<'cx, 'tcx>(
debug!(?obligation, ?closure_sig, ?obligations, "confirm_closure_candidate");
confirm_callable_candidate(selcx, obligation, closure_sig, util::TupleArgumentsFlag::No)
.with_addl_obligations(nested)
.with_addl_obligations(obligations)
confirm_callable_candidate(
selcx,
obligation,
closure_sig,
util::TupleArgumentsFlag::No,
// FIXME(effects): This doesn't handle const closures correctly!
selcx.tcx().consts.true_,
)
.with_addl_obligations(nested)
.with_addl_obligations(obligations)
}
fn confirm_callable_candidate<'cx, 'tcx>(
@ -2372,6 +2395,7 @@ fn confirm_callable_candidate<'cx, 'tcx>(
obligation: &ProjectionTyObligation<'tcx>,
fn_sig: ty::PolyFnSig<'tcx>,
flag: util::TupleArgumentsFlag,
fn_host_effect: ty::Const<'tcx>,
) -> Progress<'tcx> {
let tcx = selcx.tcx();
@ -2386,6 +2410,7 @@ fn confirm_callable_candidate<'cx, 'tcx>(
obligation.predicate.self_ty(),
fn_sig,
flag,
fn_host_effect,
)
.map_bound(|(trait_ref, ret_type)| ty::ProjectionPredicate {
projection_ty: ty::AliasTy::new(tcx, fn_once_output_def_id, trait_ref.args),