Make proof tree probing generic
This commit is contained in:
parent
8a8bbc0c17
commit
c2e416c471
3 changed files with 51 additions and 38 deletions
|
@ -471,6 +471,10 @@ impl<'tcx> ty::InferCtxtLike for InferCtxt<'tcx> {
|
|||
{
|
||||
self.resolve_vars_if_possible(value)
|
||||
}
|
||||
|
||||
fn probe<T>(&self, probe: impl FnOnce() -> T) -> T {
|
||||
self.probe(|_| probe())
|
||||
}
|
||||
}
|
||||
|
||||
/// See the `error_reporting` module for more details.
|
||||
|
|
|
@ -1,27 +1,29 @@
|
|||
use crate::solve::assembly::Candidate;
|
||||
|
||||
use super::EvalCtxt;
|
||||
use rustc_infer::infer::InferCtxt;
|
||||
use rustc_infer::traits::BuiltinImplSource;
|
||||
use rustc_middle::traits::query::NoSolution;
|
||||
use rustc_middle::traits::solve::{inspect, CandidateSource, QueryResult};
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_next_trait_solver::solve::{
|
||||
inspect, BuiltinImplSource, CandidateSource, NoSolution, QueryResult,
|
||||
};
|
||||
use rustc_type_ir::{InferCtxtLike, Interner};
|
||||
use std::marker::PhantomData;
|
||||
|
||||
pub(in crate::solve) struct ProbeCtxt<'me, 'a, 'tcx, F, T> {
|
||||
ecx: &'me mut EvalCtxt<'a, InferCtxt<'tcx>>,
|
||||
pub(in crate::solve) struct ProbeCtxt<'me, 'a, Infcx, I, F, T>
|
||||
where
|
||||
Infcx: InferCtxtLike<Interner = I>,
|
||||
I: Interner,
|
||||
{
|
||||
ecx: &'me mut EvalCtxt<'a, Infcx, I>,
|
||||
probe_kind: F,
|
||||
_result: PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<'tcx, F, T> ProbeCtxt<'_, '_, 'tcx, F, T>
|
||||
impl<Infcx, I, F, T> ProbeCtxt<'_, '_, Infcx, I, F, T>
|
||||
where
|
||||
F: FnOnce(&T) -> inspect::ProbeKind<TyCtxt<'tcx>>,
|
||||
F: FnOnce(&T) -> inspect::ProbeKind<I>,
|
||||
Infcx: InferCtxtLike<Interner = I>,
|
||||
I: Interner,
|
||||
{
|
||||
pub(in crate::solve) fn enter(
|
||||
self,
|
||||
f: impl FnOnce(&mut EvalCtxt<'_, InferCtxt<'tcx>>) -> T,
|
||||
) -> T {
|
||||
pub(in crate::solve) fn enter(self, f: impl FnOnce(&mut EvalCtxt<'_, Infcx>) -> T) -> T {
|
||||
let ProbeCtxt { ecx: outer_ecx, probe_kind, _result } = self;
|
||||
|
||||
let infcx = outer_ecx.infcx;
|
||||
|
@ -38,7 +40,7 @@ where
|
|||
tainted: outer_ecx.tainted,
|
||||
inspect: outer_ecx.inspect.take_and_enter_probe(),
|
||||
};
|
||||
let r = nested_ecx.infcx.probe(|_| {
|
||||
let r = nested_ecx.infcx.probe(|| {
|
||||
let r = f(&mut nested_ecx);
|
||||
nested_ecx.inspect.probe_final_state(infcx, max_input_universe);
|
||||
r
|
||||
|
@ -52,30 +54,43 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
pub(in crate::solve) struct TraitProbeCtxt<'me, 'a, 'tcx, F> {
|
||||
cx: ProbeCtxt<'me, 'a, 'tcx, F, QueryResult<'tcx>>,
|
||||
source: CandidateSource<'tcx>,
|
||||
pub(in crate::solve) struct TraitProbeCtxt<'me, 'a, Infcx, I, F>
|
||||
where
|
||||
Infcx: InferCtxtLike<Interner = I>,
|
||||
I: Interner,
|
||||
{
|
||||
cx: ProbeCtxt<'me, 'a, Infcx, I, F, QueryResult<I>>,
|
||||
source: CandidateSource<I>,
|
||||
}
|
||||
|
||||
impl<'tcx, F> TraitProbeCtxt<'_, '_, 'tcx, F>
|
||||
impl<Infcx, I, F> TraitProbeCtxt<'_, '_, Infcx, I, F>
|
||||
where
|
||||
F: FnOnce(&QueryResult<'tcx>) -> inspect::ProbeKind<TyCtxt<'tcx>>,
|
||||
Infcx: InferCtxtLike<Interner = I>,
|
||||
I: Interner,
|
||||
F: FnOnce(&QueryResult<I>) -> inspect::ProbeKind<I>,
|
||||
{
|
||||
#[instrument(level = "debug", skip_all, fields(source = ?self.source))]
|
||||
pub(in crate::solve) fn enter(
|
||||
self,
|
||||
f: impl FnOnce(&mut EvalCtxt<'_, InferCtxt<'tcx>>) -> QueryResult<'tcx>,
|
||||
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution> {
|
||||
f: impl FnOnce(&mut EvalCtxt<'_, Infcx>) -> QueryResult<I>,
|
||||
) -> Result<Candidate<I>, NoSolution> {
|
||||
self.cx.enter(|ecx| f(ecx)).map(|result| Candidate { source: self.source, result })
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> EvalCtxt<'a, InferCtxt<'tcx>> {
|
||||
impl<'a, Infcx, I> EvalCtxt<'a, Infcx, I>
|
||||
where
|
||||
Infcx: InferCtxtLike<Interner = I>,
|
||||
I: Interner,
|
||||
{
|
||||
/// `probe_kind` is only called when proof tree building is enabled so it can be
|
||||
/// as expensive as necessary to output the desired information.
|
||||
pub(in crate::solve) fn probe<F, T>(&mut self, probe_kind: F) -> ProbeCtxt<'_, 'a, 'tcx, F, T>
|
||||
pub(in crate::solve) fn probe<F, T>(
|
||||
&mut self,
|
||||
probe_kind: F,
|
||||
) -> ProbeCtxt<'_, 'a, Infcx, I, F, T>
|
||||
where
|
||||
F: FnOnce(&T) -> inspect::ProbeKind<TyCtxt<'tcx>>,
|
||||
F: FnOnce(&T) -> inspect::ProbeKind<I>,
|
||||
{
|
||||
ProbeCtxt { ecx: self, probe_kind, _result: PhantomData }
|
||||
}
|
||||
|
@ -83,28 +98,20 @@ impl<'a, 'tcx> EvalCtxt<'a, InferCtxt<'tcx>> {
|
|||
pub(in crate::solve) fn probe_builtin_trait_candidate(
|
||||
&mut self,
|
||||
source: BuiltinImplSource,
|
||||
) -> TraitProbeCtxt<
|
||||
'_,
|
||||
'a,
|
||||
'tcx,
|
||||
impl FnOnce(&QueryResult<'tcx>) -> inspect::ProbeKind<TyCtxt<'tcx>>,
|
||||
> {
|
||||
) -> TraitProbeCtxt<'_, 'a, Infcx, I, impl FnOnce(&QueryResult<I>) -> inspect::ProbeKind<I>>
|
||||
{
|
||||
self.probe_trait_candidate(CandidateSource::BuiltinImpl(source))
|
||||
}
|
||||
|
||||
pub(in crate::solve) fn probe_trait_candidate(
|
||||
&mut self,
|
||||
source: CandidateSource<'tcx>,
|
||||
) -> TraitProbeCtxt<
|
||||
'_,
|
||||
'a,
|
||||
'tcx,
|
||||
impl FnOnce(&QueryResult<'tcx>) -> inspect::ProbeKind<TyCtxt<'tcx>>,
|
||||
> {
|
||||
source: CandidateSource<I>,
|
||||
) -> TraitProbeCtxt<'_, 'a, Infcx, I, impl FnOnce(&QueryResult<I>) -> inspect::ProbeKind<I>>
|
||||
{
|
||||
TraitProbeCtxt {
|
||||
cx: ProbeCtxt {
|
||||
ecx: self,
|
||||
probe_kind: move |result: &QueryResult<'tcx>| inspect::ProbeKind::TraitCandidate {
|
||||
probe_kind: move |result: &QueryResult<I>| inspect::ProbeKind::TraitCandidate {
|
||||
source,
|
||||
result: *result,
|
||||
},
|
||||
|
|
|
@ -72,4 +72,6 @@ pub trait InferCtxtLike: Sized {
|
|||
fn resolve_vars_if_possible<T>(&self, value: T) -> T
|
||||
where
|
||||
T: TypeFoldable<Self::Interner>;
|
||||
|
||||
fn probe<T>(&self, probe: impl FnOnce() -> T) -> T;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue