]>
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(); | |
dfeec247 XL |
67 | let c_pred = self |
68 | .canonicalize_query(&obligation.param_env.and(obligation.predicate), &mut _orig_values); | |
83c7162d XL |
69 | // Run canonical query. If overflow occurs, rerun from scratch but this time |
70 | // in standard trait query mode so that overflow is handled appropriately | |
71 | // within `SelectionContext`. | |
e74abb32 | 72 | self.tcx.evaluate_obligation(c_pred) |
0bf4aa26 XL |
73 | } |
74 | ||
75 | // Helper function that canonicalizes and runs the query. If an | |
76 | // overflow results, we re-run it in the local context so we can | |
77 | // report a nice error. | |
ba9703b0 | 78 | fn evaluate_obligation_no_overflow( |
0bf4aa26 XL |
79 | &self, |
80 | obligation: &PredicateObligation<'tcx>, | |
81 | ) -> EvaluationResult { | |
82 | match self.evaluate_obligation(obligation) { | |
83c7162d XL |
83 | Ok(result) => result, |
84 | Err(OverflowError) => { | |
dfeec247 XL |
85 | let mut selcx = SelectionContext::with_query_mode(&self, TraitQueryMode::Standard); |
86 | selcx.evaluate_root_obligation(obligation).unwrap_or_else(|r| { | |
87 | span_bug!( | |
88 | obligation.cause.span, | |
89 | "Overflow should be caught earlier in standard query mode: {:?}, {:?}", | |
90 | obligation, | |
91 | r, | |
92 | ) | |
93 | }) | |
83c7162d XL |
94 | } |
95 | } | |
96 | } | |
97 | } |