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.
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.
12 use infer::canonical::{Canonical, Canonicalize};
13 use traits::{EvaluationResult, PredicateObligation, SelectionContext,
14 TraitQueryMode, OverflowError};
15 use traits::query::CanonicalPredicateGoal;
16 use ty::{ParamEnvAnd, Predicate, TyCtxt};
18 impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
19 /// Evaluates whether the predicate can be satisfied (by any means)
20 /// in the given `ParamEnv`.
21 pub fn predicate_may_hold(
23 obligation: &PredicateObligation<'tcx>,
25 self.evaluate_obligation(obligation).may_apply()
28 /// Evaluates whether the predicate can be satisfied in the given
29 /// `ParamEnv`, and returns `false` if not certain. However, this is
30 /// not entirely accurate if inference variables are involved.
31 pub fn predicate_must_hold(
33 obligation: &PredicateObligation<'tcx>,
35 self.evaluate_obligation(obligation) == EvaluationResult::EvaluatedToOk
38 // Helper function that canonicalizes and runs the query, as well as handles
40 fn evaluate_obligation(
42 obligation: &PredicateObligation<'tcx>,
43 ) -> EvaluationResult {
45 self.canonicalize_query(&obligation.param_env.and(obligation.predicate));
46 // Run canonical query. If overflow occurs, rerun from scratch but this time
47 // in standard trait query mode so that overflow is handled appropriately
48 // within `SelectionContext`.
49 match self.tcx.global_tcx().evaluate_obligation(c_pred) {
51 Err(OverflowError) => {
53 SelectionContext::with_query_mode(&self, TraitQueryMode::Standard);
54 selcx.evaluate_obligation_recursively(obligation)
55 .expect("Overflow should be caught earlier in standard query mode")
61 impl<'gcx: 'tcx, 'tcx> Canonicalize<'gcx, 'tcx> for ParamEnvAnd<'tcx, Predicate<'tcx>> {
62 type Canonicalized = CanonicalPredicateGoal<'gcx>;
65 _gcx: TyCtxt<'_, 'gcx, 'gcx>,
66 value: Canonical<'gcx, Self::Lifted>,
67 ) -> Self::Canonicalized {