]> git.proxmox.com Git - rustc.git/blob - src/librustc/traits/query/evaluate_obligation.rs
New upstream version 1.29.0+dfsg1
[rustc.git] / src / librustc / traits / query / evaluate_obligation.rs
1 // Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 use infer::InferCtxt;
12 use rustc_data_structures::small_vec::SmallVec;
13 use traits::{EvaluationResult, PredicateObligation, SelectionContext,
14 TraitQueryMode, OverflowError};
15
16 impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
17 /// Evaluates whether the predicate can be satisfied (by any means)
18 /// in the given `ParamEnv`.
19 pub fn predicate_may_hold(
20 &self,
21 obligation: &PredicateObligation<'tcx>,
22 ) -> bool {
23 self.evaluate_obligation(obligation).may_apply()
24 }
25
26 /// Evaluates whether the predicate can be satisfied in the given
27 /// `ParamEnv`, and returns `false` if not certain. However, this is
28 /// not entirely accurate if inference variables are involved.
29 pub fn predicate_must_hold(
30 &self,
31 obligation: &PredicateObligation<'tcx>,
32 ) -> bool {
33 self.evaluate_obligation(obligation) == EvaluationResult::EvaluatedToOk
34 }
35
36 // Helper function that canonicalizes and runs the query, as well as handles
37 // overflow.
38 fn evaluate_obligation(
39 &self,
40 obligation: &PredicateObligation<'tcx>,
41 ) -> EvaluationResult {
42 let mut _orig_values = SmallVec::new();
43 let c_pred = self.canonicalize_query(&obligation.param_env.and(obligation.predicate),
44 &mut _orig_values);
45 // Run canonical query. If overflow occurs, rerun from scratch but this time
46 // in standard trait query mode so that overflow is handled appropriately
47 // within `SelectionContext`.
48 match self.tcx.global_tcx().evaluate_obligation(c_pred) {
49 Ok(result) => result,
50 Err(OverflowError) => {
51 let mut selcx =
52 SelectionContext::with_query_mode(&self, TraitQueryMode::Standard);
53 selcx.evaluate_obligation_recursively(obligation)
54 .expect("Overflow should be caught earlier in standard query mode")
55 }
56 }
57 }
58 }