]>
Commit | Line | Data |
---|---|---|
9fa01778 | 1 | use crate::infer::canonical::OriginalQueryValues; |
dfeec247 | 2 | use crate::infer::InferCtxt; |
e1599b0c | 3 | use crate::traits::{ |
dfeec247 | 4 | EvaluationResult, OverflowError, PredicateObligation, SelectionContext, TraitQueryMode, |
e1599b0c | 5 | }; |
83c7162d | 6 | |
ba9703b0 XL |
7 | pub trait InferCtxtExt<'tcx> { |
8 | fn predicate_may_hold(&self, obligation: &PredicateObligation<'tcx>) -> bool; | |
9 | ||
10 | fn predicate_must_hold_considering_regions( | |
11 | &self, | |
12 | obligation: &PredicateObligation<'tcx>, | |
13 | ) -> bool; | |
14 | ||
15 | fn predicate_must_hold_modulo_regions(&self, obligation: &PredicateObligation<'tcx>) -> bool; | |
16 | ||
17 | fn evaluate_obligation( | |
18 | &self, | |
19 | obligation: &PredicateObligation<'tcx>, | |
20 | ) -> Result<EvaluationResult, OverflowError>; | |
21 | ||
22 | // Helper function that canonicalizes and runs the query. If an | |
23 | // overflow results, we re-run it in the local context so we can | |
24 | // report a nice error. | |
25 | /*crate*/ | |
26 | fn evaluate_obligation_no_overflow( | |
27 | &self, | |
28 | obligation: &PredicateObligation<'tcx>, | |
29 | ) -> EvaluationResult; | |
30 | } | |
31 | ||
32 | impl<'cx, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'cx, 'tcx> { | |
83c7162d XL |
33 | /// Evaluates whether the predicate can be satisfied (by any means) |
34 | /// in the given `ParamEnv`. | |
ba9703b0 | 35 | fn predicate_may_hold(&self, obligation: &PredicateObligation<'tcx>) -> bool { |
0bf4aa26 | 36 | self.evaluate_obligation_no_overflow(obligation).may_apply() |
83c7162d XL |
37 | } |
38 | ||
39 | /// Evaluates whether the predicate can be satisfied in the given | |
40 | /// `ParamEnv`, and returns `false` if not certain. However, this is | |
41 | /// not entirely accurate if inference variables are involved. | |
0731742a XL |
42 | /// |
43 | /// This version may conservatively fail when outlives obligations | |
44 | /// are required. | |
ba9703b0 | 45 | fn predicate_must_hold_considering_regions( |
0731742a XL |
46 | &self, |
47 | obligation: &PredicateObligation<'tcx>, | |
48 | ) -> bool { | |
49 | self.evaluate_obligation_no_overflow(obligation).must_apply_considering_regions() | |
50 | } | |
51 | ||
52 | /// Evaluates whether the predicate can be satisfied in the given | |
53 | /// `ParamEnv`, and returns `false` if not certain. However, this is | |
54 | /// not entirely accurate if inference variables are involved. | |
55 | /// | |
56 | /// This version ignores all outlives constraints. | |
ba9703b0 | 57 | fn predicate_must_hold_modulo_regions(&self, obligation: &PredicateObligation<'tcx>) -> bool { |
0731742a | 58 | self.evaluate_obligation_no_overflow(obligation).must_apply_modulo_regions() |
83c7162d XL |
59 | } |
60 | ||
0bf4aa26 | 61 | /// Evaluate a given predicate, capturing overflow and propagating it back. |
ba9703b0 | 62 | fn evaluate_obligation( |
83c7162d XL |
63 | &self, |
64 | obligation: &PredicateObligation<'tcx>, | |
0bf4aa26 XL |
65 | ) -> Result<EvaluationResult, OverflowError> { |
66 | let mut _orig_values = OriginalQueryValues::default(); | |
136023e0 XL |
67 | let c_pred = self.canonicalize_query_keep_static( |
68 | obligation.param_env.and(obligation.predicate), | |
69 | &mut _orig_values, | |
70 | ); | |
83c7162d XL |
71 | // Run canonical query. If overflow occurs, rerun from scratch but this time |
72 | // in standard trait query mode so that overflow is handled appropriately | |
73 | // within `SelectionContext`. | |
94222f64 | 74 | self.tcx.at(obligation.cause.span(self.tcx)).evaluate_obligation(c_pred) |
0bf4aa26 XL |
75 | } |
76 | ||
77 | // Helper function that canonicalizes and runs the query. If an | |
78 | // overflow results, we re-run it in the local context so we can | |
79 | // report a nice error. | |
ba9703b0 | 80 | fn evaluate_obligation_no_overflow( |
0bf4aa26 XL |
81 | &self, |
82 | obligation: &PredicateObligation<'tcx>, | |
83 | ) -> EvaluationResult { | |
84 | match self.evaluate_obligation(obligation) { | |
83c7162d XL |
85 | Ok(result) => result, |
86 | Err(OverflowError) => { | |
dfeec247 XL |
87 | let mut selcx = SelectionContext::with_query_mode(&self, TraitQueryMode::Standard); |
88 | selcx.evaluate_root_obligation(obligation).unwrap_or_else(|r| { | |
89 | span_bug!( | |
90 | obligation.cause.span, | |
91 | "Overflow should be caught earlier in standard query mode: {:?}, {:?}", | |
92 | obligation, | |
93 | r, | |
94 | ) | |
95 | }) | |
83c7162d XL |
96 | } |
97 | } | |
98 | } | |
99 | } |