rustc_next_trait_solver/solve/eval_ctxt/
probe.rs1use std::marker::PhantomData;
2
3use rustc_type_ir::search_graph::CandidateHeadUsages;
4use rustc_type_ir::{InferCtxtLike, Interner};
5use tracing::instrument;
6
7use crate::delegate::SolverDelegate;
8use crate::solve::assembly::Candidate;
9use crate::solve::{
10 BuiltinImplSource, CandidateSource, EvalCtxt, NoSolution, QueryResult, inspect,
11};
12
13pub(in crate::solve) struct ProbeCtxt<'me, 'a, D, I, F, T>
14where
15 D: SolverDelegate<Interner = I>,
16 I: Interner,
17{
18 ecx: &'me mut EvalCtxt<'a, D, I>,
19 probe_kind: F,
20 _result: PhantomData<T>,
21}
22
23impl<D, I, F, T> ProbeCtxt<'_, '_, D, I, F, T>
24where
25 F: FnOnce(&T) -> inspect::ProbeKind<I>,
26 D: SolverDelegate<Interner = I>,
27 I: Interner,
28{
29 pub(in crate::solve) fn enter_single_candidate(
30 self,
31 f: impl FnOnce(&mut EvalCtxt<'_, D>) -> T,
32 ) -> (T, CandidateHeadUsages) {
33 self.ecx.search_graph.enter_single_candidate();
34 let mut candidate_usages = CandidateHeadUsages::default();
35 let result = self.enter(|ecx| {
36 let result = f(ecx);
37 candidate_usages = ecx.search_graph.finish_single_candidate();
38 result
39 });
40 (result, candidate_usages)
41 }
42
43 pub(in crate::solve) fn enter(self, f: impl FnOnce(&mut EvalCtxt<'_, D>) -> T) -> T {
44 let ProbeCtxt { ecx: outer, probe_kind, _result } = self;
45
46 let delegate = outer.delegate;
47 let max_input_universe = outer.max_input_universe;
48 let mut nested = EvalCtxt {
49 delegate,
50 var_kinds: outer.var_kinds,
51 var_values: outer.var_values,
52 current_goal_kind: outer.current_goal_kind,
53 max_input_universe,
54 initial_opaque_types_storage_num_entries: outer
55 .initial_opaque_types_storage_num_entries,
56 search_graph: outer.search_graph,
57 nested_goals: outer.nested_goals.clone(),
58 origin_span: outer.origin_span,
59 tainted: outer.tainted,
60 inspect: outer.inspect.take_and_enter_probe(),
61 };
62 let r = nested.delegate.probe(|| {
63 let r = f(&mut nested);
64 nested.inspect.probe_final_state(delegate, max_input_universe);
65 r
66 });
67 if !nested.inspect.is_noop() {
68 let probe_kind = probe_kind(&r);
69 nested.inspect.probe_kind(probe_kind);
70 outer.inspect = nested.inspect.finish_probe();
71 }
72 r
73 }
74}
75
76pub(in crate::solve) struct TraitProbeCtxt<'me, 'a, D, I, F>
77where
78 D: SolverDelegate<Interner = I>,
79 I: Interner,
80{
81 cx: ProbeCtxt<'me, 'a, D, I, F, QueryResult<I>>,
82 source: CandidateSource<I>,
83}
84
85impl<D, I, F> TraitProbeCtxt<'_, '_, D, I, F>
86where
87 D: SolverDelegate<Interner = I>,
88 I: Interner,
89 F: FnOnce(&QueryResult<I>) -> inspect::ProbeKind<I>,
90{
91 #[allow(clippy :: suspicious_else_formatting)]
{
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() ||
{ false } {
__tracing_attr_span =
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("enter",
"rustc_next_trait_solver::solve::eval_ctxt::probe",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_next_trait_solver/src/solve/eval_ctxt/probe.rs"),
::tracing_core::__macro_support::Option::Some(91u32),
::tracing_core::__macro_support::Option::Some("rustc_next_trait_solver::solve::eval_ctxt::probe"),
::tracing_core::field::FieldSet::new(&["source"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{ interest = __CALLSITE.interest(); !interest.is_never() }
&&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest) {
let meta = __CALLSITE.metadata();
::tracing::Span::new(meta,
&{
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = meta.fields().iter();
meta.fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&debug(&self.source)
as &dyn Value))])
})
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[warn(clippy :: suspicious_else_formatting)]
{
#[allow(unknown_lints, unreachable_code, clippy ::
diverging_sub_expression, clippy :: empty_loop, clippy ::
let_unit_value, clippy :: let_with_type_underscore, clippy ::
needless_return, clippy :: unreachable)]
if false {
let __tracing_attr_fake_return: Result<Candidate<I>, NoSolution> =
loop {};
return __tracing_attr_fake_return;
}
{
let (result, head_usages) = self.cx.enter_single_candidate(f);
result.map(|result|
Candidate { source: self.source, result, head_usages })
}
}
}#[instrument(level = "debug", skip_all, fields(source = ?self.source))]
92 pub(in crate::solve) fn enter(
93 self,
94 f: impl FnOnce(&mut EvalCtxt<'_, D>) -> QueryResult<I>,
95 ) -> Result<Candidate<I>, NoSolution> {
96 let (result, head_usages) = self.cx.enter_single_candidate(f);
97 result.map(|result| Candidate { source: self.source, result, head_usages })
98 }
99}
100
101impl<'a, D, I> EvalCtxt<'a, D, I>
102where
103 D: SolverDelegate<Interner = I>,
104 I: Interner,
105{
106 pub(in crate::solve) fn probe<F, T>(&mut self, probe_kind: F) -> ProbeCtxt<'_, 'a, D, I, F, T>
109 where
110 F: FnOnce(&T) -> inspect::ProbeKind<I>,
111 {
112 ProbeCtxt { ecx: self, probe_kind, _result: PhantomData }
113 }
114
115 pub(in crate::solve) fn probe_builtin_trait_candidate(
116 &mut self,
117 source: BuiltinImplSource,
118 ) -> TraitProbeCtxt<'_, 'a, D, I, impl FnOnce(&QueryResult<I>) -> inspect::ProbeKind<I>> {
119 self.probe_trait_candidate(CandidateSource::BuiltinImpl(source))
120 }
121
122 pub(in crate::solve) fn probe_trait_candidate(
123 &mut self,
124 source: CandidateSource<I>,
125 ) -> TraitProbeCtxt<'_, 'a, D, I, impl FnOnce(&QueryResult<I>) -> inspect::ProbeKind<I>> {
126 TraitProbeCtxt {
127 cx: ProbeCtxt {
128 ecx: self,
129 probe_kind: move |result: &QueryResult<I>| inspect::ProbeKind::TraitCandidate {
130 source,
131 result: *result,
132 },
133 _result: PhantomData,
134 },
135 source,
136 }
137 }
138}