rustc_trait_selection/traits/query/type_op/
prove_predicate.rs1use rustc_hir::LangItem;
2use rustc_infer::traits::Obligation;
3use rustc_middle::traits::ObligationCause;
4use rustc_middle::traits::query::NoSolution;
5pub use rustc_middle::traits::query::type_op::ProvePredicate;
6use rustc_middle::ty::{self, ParamEnvAnd, TyCtxt};
7use rustc_span::Span;
8
9use crate::infer::canonical::{CanonicalQueryInput, CanonicalQueryResponse};
10use crate::traits::ObligationCtxt;
11
12impl<'tcx> super::QueryTypeOp<'tcx> for ProvePredicate<'tcx> {
13 type QueryResponse = ();
14
15 fn try_fast_path(
16 tcx: TyCtxt<'tcx>,
17 key: &ParamEnvAnd<'tcx, Self>,
18 ) -> Option<Self::QueryResponse> {
19 if let ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_ref)) =
24 key.value.predicate.kind().skip_binder()
25 && tcx.is_lang_item(trait_ref.def_id(), LangItem::Sized)
26 && trait_ref.self_ty().is_trivially_sized(tcx)
27 {
28 return Some(());
29 }
30
31 if let ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(arg)) =
32 key.value.predicate.kind().skip_binder()
33 {
34 match arg.as_type()?.kind() {
35 ty::Param(_)
36 | ty::Bool
37 | ty::Char
38 | ty::Int(_)
39 | ty::Float(_)
40 | ty::Str
41 | ty::Uint(_) => {
42 return Some(());
43 }
44 _ => {}
45 }
46 }
47
48 None
49 }
50
51 fn perform_query(
52 tcx: TyCtxt<'tcx>,
53 canonicalized: CanonicalQueryInput<'tcx, ParamEnvAnd<'tcx, Self>>,
54 ) -> Result<CanonicalQueryResponse<'tcx, ()>, NoSolution> {
55 tcx.type_op_prove_predicate(canonicalized)
56 }
57
58 fn perform_locally_with_next_solver(
59 ocx: &ObligationCtxt<'_, 'tcx>,
60 key: ParamEnvAnd<'tcx, Self>,
61 span: Span,
62 ) -> Result<Self::QueryResponse, NoSolution> {
63 ocx.register_obligation(Obligation::new(
64 ocx.infcx.tcx,
65 ObligationCause::dummy_with_span(span),
66 key.param_env,
67 key.value.predicate,
68 ));
69 Ok(())
70 }
71}