summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_trait_selection/src/solve/eval_ctxt/commit_if_ok.rs
blob: 67b6801059af79755c5191192f71e9e1826cb2cc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
use super::{EvalCtxt, NestedGoals};
use crate::solve::inspect;
use rustc_middle::traits::query::NoSolution;

impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
    pub(in crate::solve) fn commit_if_ok<T>(
        &mut self,
        f: impl FnOnce(&mut EvalCtxt<'_, 'tcx>) -> Result<T, NoSolution>,
    ) -> Result<T, NoSolution> {
        let mut nested_ecx = EvalCtxt {
            infcx: self.infcx,
            variables: self.variables,
            var_values: self.var_values,
            predefined_opaques_in_body: self.predefined_opaques_in_body,
            max_input_universe: self.max_input_universe,
            search_graph: self.search_graph,
            nested_goals: NestedGoals::new(),
            tainted: self.tainted,
            inspect: self.inspect.new_probe(),
        };

        let result = nested_ecx.infcx.commit_if_ok(|_| f(&mut nested_ecx));
        if result.is_ok() {
            let EvalCtxt {
                infcx: _,
                variables: _,
                var_values: _,
                predefined_opaques_in_body: _,
                max_input_universe: _,
                search_graph: _,
                nested_goals,
                tainted,
                inspect,
            } = nested_ecx;
            self.nested_goals.extend(nested_goals);
            self.tainted = tainted;
            self.inspect.integrate_snapshot(inspect);
        } else {
            nested_ecx.inspect.probe_kind(inspect::ProbeKind::CommitIfOk);
            self.inspect.finish_probe(nested_ecx.inspect);
        }

        result
    }
}