rustc_trait_selection/traits/query/type_op/
prove_predicate.rs

1use rustc_infer::traits::Obligation;
2use rustc_middle::traits::ObligationCause;
3use rustc_middle::traits::query::NoSolution;
4pub use rustc_middle::traits::query::type_op::ProvePredicate;
5use rustc_middle::ty::{self, ParamEnvAnd, TyCtxt};
6use rustc_span::Span;
7
8use crate::infer::canonical::{CanonicalQueryInput, CanonicalQueryResponse};
9use crate::traits::{ObligationCtxt, sizedness_fast_path};
10
11impl<'tcx> super::QueryTypeOp<'tcx> for ProvePredicate<'tcx> {
12    type QueryResponse = ();
13
14    fn try_fast_path(
15        tcx: TyCtxt<'tcx>,
16        key: &ParamEnvAnd<'tcx, Self>,
17    ) -> Option<Self::QueryResponse> {
18        if sizedness_fast_path(tcx, key.value.predicate, key.param_env) {
19            return Some(());
20        }
21
22        if let ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(term)) =
23            key.value.predicate.kind().skip_binder()
24            && term.is_trivially_wf(tcx)
25        {
26            return Some(());
27        }
28
29        None
30    }
31
32    fn perform_query(
33        tcx: TyCtxt<'tcx>,
34        canonicalized: CanonicalQueryInput<'tcx, ParamEnvAnd<'tcx, Self>>,
35    ) -> Result<CanonicalQueryResponse<'tcx, ()>, NoSolution> {
36        tcx.type_op_prove_predicate(canonicalized)
37    }
38
39    fn perform_locally_with_next_solver(
40        ocx: &ObligationCtxt<'_, 'tcx>,
41        key: ParamEnvAnd<'tcx, Self>,
42        span: Span,
43    ) -> Result<Self::QueryResponse, NoSolution> {
44        ocx.register_obligation(Obligation::new(
45            ocx.infcx.tcx,
46            ObligationCause::dummy_with_span(span),
47            key.param_env,
48            key.value.predicate,
49        ));
50        Ok(())
51    }
52}