rustc_trait_selection/traits/query/type_op/
prove_predicate.rs1use 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}