]>
git.proxmox.com Git - rustc.git/blob - compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs
1 use crate::infer
::canonical
::OriginalQueryValues
;
2 use crate::infer
::InferCtxt
;
4 EvaluationResult
, OverflowError
, PredicateObligation
, SelectionContext
, TraitQueryMode
,
7 pub trait InferCtxtExt
<'tcx
> {
8 fn predicate_may_hold(&self, obligation
: &PredicateObligation
<'tcx
>) -> bool
;
10 fn predicate_must_hold_considering_regions(
12 obligation
: &PredicateObligation
<'tcx
>,
15 fn predicate_must_hold_modulo_regions(&self, obligation
: &PredicateObligation
<'tcx
>) -> bool
;
17 fn evaluate_obligation(
19 obligation
: &PredicateObligation
<'tcx
>,
20 ) -> Result
<EvaluationResult
, OverflowError
>;
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.
26 fn evaluate_obligation_no_overflow(
28 obligation
: &PredicateObligation
<'tcx
>,
29 ) -> EvaluationResult
;
32 impl<'cx
, 'tcx
> InferCtxtExt
<'tcx
> for InferCtxt
<'cx
, 'tcx
> {
33 /// Evaluates whether the predicate can be satisfied (by any means)
34 /// in the given `ParamEnv`.
35 fn predicate_may_hold(&self, obligation
: &PredicateObligation
<'tcx
>) -> bool
{
36 self.evaluate_obligation_no_overflow(obligation
).may_apply()
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.
43 /// This version may conservatively fail when outlives obligations
45 fn predicate_must_hold_considering_regions(
47 obligation
: &PredicateObligation
<'tcx
>,
49 self.evaluate_obligation_no_overflow(obligation
).must_apply_considering_regions()
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.
56 /// This version ignores all outlives constraints.
57 fn predicate_must_hold_modulo_regions(&self, obligation
: &PredicateObligation
<'tcx
>) -> bool
{
58 self.evaluate_obligation_no_overflow(obligation
).must_apply_modulo_regions()
61 /// Evaluate a given predicate, capturing overflow and propagating it back.
62 fn evaluate_obligation(
64 obligation
: &PredicateObligation
<'tcx
>,
65 ) -> Result
<EvaluationResult
, OverflowError
> {
66 let mut _orig_values
= OriginalQueryValues
::default();
67 let c_pred
= self.canonicalize_query_keep_static(
68 obligation
.param_env
.and(obligation
.predicate
),
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`.
74 self.tcx
.evaluate_obligation(c_pred
)
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.
80 fn evaluate_obligation_no_overflow(
82 obligation
: &PredicateObligation
<'tcx
>,
83 ) -> EvaluationResult
{
84 match self.evaluate_obligation(obligation
) {
86 Err(OverflowError
) => {
87 let mut selcx
= SelectionContext
::with_query_mode(&self, TraitQueryMode
::Standard
);
88 selcx
.evaluate_root_obligation(obligation
).unwrap_or_else(|r
| {
90 obligation
.cause
.span
,
91 "Overflow should be caught earlier in standard query mode: {:?}, {:?}",