rustc_trait_selection/traits/query/
evaluate_obligation.rs1use rustc_infer::traits::solve::Goal;
2use rustc_macros::extension;
3use rustc_middle::span_bug;
4use rustc_next_trait_solver::solve::SolverDelegateEvalExt;
5
6use crate::infer::InferCtxt;
7use crate::infer::canonical::OriginalQueryValues;
8use crate::solve::SolverDelegate;
9use crate::traits::{
10 EvaluationResult, ObligationCtxt, OverflowError, PredicateObligation, SelectionContext,
11};
12
13#[extension(pub trait InferCtxtExt<'tcx>)]
14impl<'tcx> InferCtxt<'tcx> {
15 fn predicate_may_hold(&self, obligation: &PredicateObligation<'tcx>) -> bool {
18 self.evaluate_obligation_no_overflow(obligation).may_apply()
19 }
20
21 fn predicate_may_hold_opaque_types_jank(&self, obligation: &PredicateObligation<'tcx>) -> bool {
24 if self.next_trait_solver() {
25 <&SolverDelegate<'tcx>>::from(self).root_goal_may_hold_opaque_types_jank(Goal::new(
26 self.tcx,
27 obligation.param_env,
28 obligation.predicate,
29 ))
30 } else {
31 self.predicate_may_hold(obligation)
32 }
33 }
34
35 fn predicate_must_hold_considering_regions(
63 &self,
64 obligation: &PredicateObligation<'tcx>,
65 ) -> bool {
66 self.evaluate_obligation_no_overflow(obligation).must_apply_considering_regions()
67 }
68
69 fn predicate_must_hold_modulo_regions(&self, obligation: &PredicateObligation<'tcx>) -> bool {
75 self.evaluate_obligation_no_overflow(obligation).must_apply_modulo_regions()
76 }
77
78 fn evaluate_obligation(
80 &self,
81 obligation: &PredicateObligation<'tcx>,
82 ) -> Result<EvaluationResult, OverflowError> {
83 let mut _orig_values = OriginalQueryValues::default();
84
85 let param_env = obligation.param_env;
86
87 if self.next_trait_solver() {
88 self.probe(|snapshot| {
89 let ocx = ObligationCtxt::new(self);
90 ocx.register_obligation(obligation.clone());
91 let mut result = EvaluationResult::EvaluatedToOk;
92 for error in ocx.select_all_or_error() {
93 if error.is_true_error() {
94 return Ok(EvaluationResult::EvaluatedToErr);
95 } else {
96 result = result.max(EvaluationResult::EvaluatedToAmbig);
97 }
98 }
99 if self.opaque_types_added_in_snapshot(snapshot) {
100 result = result.max(EvaluationResult::EvaluatedToOkModuloOpaqueTypes);
101 } else if self.region_constraints_added_in_snapshot(snapshot) {
102 result = result.max(EvaluationResult::EvaluatedToOkModuloRegions);
103 }
104 Ok(result)
105 })
106 } else {
107 let c_pred =
108 self.canonicalize_query(param_env.and(obligation.predicate), &mut _orig_values);
109 self.tcx.at(obligation.cause.span).evaluate_obligation(c_pred)
110 }
111 }
112
113 fn evaluate_obligation_no_overflow(
117 &self,
118 obligation: &PredicateObligation<'tcx>,
119 ) -> EvaluationResult {
120 match self.evaluate_obligation(obligation) {
124 Ok(result) => result,
125 Err(OverflowError::Canonical) => {
126 let mut selcx = SelectionContext::new(self);
127 selcx.evaluate_root_obligation(obligation).unwrap_or_else(|r| match r {
128 OverflowError::Canonical => {
129 span_bug!(
130 obligation.cause.span,
131 "Overflow should be caught earlier in standard query mode: {:?}, {:?}",
132 obligation,
133 r,
134 )
135 }
136 OverflowError::Error(_) => EvaluationResult::EvaluatedToErr,
137 })
138 }
139 Err(OverflowError::Error(_)) => EvaluationResult::EvaluatedToErr,
140 }
141 }
142}