]> git.proxmox.com Git - rustc.git/blame - compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs
New upstream version 1.56.0~beta.4+dfsg1
[rustc.git] / compiler / rustc_trait_selection / src / traits / query / evaluate_obligation.rs
CommitLineData
9fa01778 1use crate::infer::canonical::OriginalQueryValues;
dfeec247 2use crate::infer::InferCtxt;
e1599b0c 3use crate::traits::{
dfeec247 4 EvaluationResult, OverflowError, PredicateObligation, SelectionContext, TraitQueryMode,
e1599b0c 5};
83c7162d 6
ba9703b0
XL
7pub 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
32impl<'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}