]>
git.proxmox.com Git - rustc.git/blob - compiler/rustc_trait_selection/src/traits/relationships.rs
1 use crate::infer
::InferCtxt
;
2 use crate::traits
::query
::evaluate_obligation
::InferCtxtExt
;
3 use crate::traits
::PredicateObligation
;
4 use rustc_infer
::traits
::TraitEngine
;
7 pub(crate) fn update
<'tcx
, T
>(
9 infcx
: &InferCtxt
<'tcx
>,
10 obligation
: &PredicateObligation
<'tcx
>,
15 if let ty
::PredicateKind
::Clause(ty
::Clause
::Trait(tpred
)) = obligation
.predicate
.kind().skip_binder()
16 && let Some(ty
) = infcx
.shallow_resolve(tpred
.self_ty()).ty_vid().map(|t
| infcx
.root_var(t
))
17 && infcx
.tcx
.lang_items().sized_trait().map_or(false, |st
| st
!= tpred
.trait_ref
.def_id
)
19 let new_self_ty
= infcx
.tcx
.types
.unit
;
21 // Then construct a new obligation with Self = () added
22 // to the ParamEnv, and see if it holds.
23 let o
= obligation
.with(infcx
.tcx
,
28 // (*) binder moved here
29 ty
::PredicateKind
::Clause(ty
::Clause
::Trait(tpred
.with_self_ty(infcx
.tcx
, new_self_ty
)))
32 // Don't report overflow errors. Otherwise equivalent to may_hold.
33 if let Ok(result
) = infcx
.probe(|_
| infcx
.evaluate_obligation(&o
)) && result
.may_apply() {
34 engine
.relationships().entry(ty
).or_default().self_in_trait
= true;
38 if let ty
::PredicateKind
::Clause(ty
::Clause
::Projection(predicate
)) =
39 obligation
.predicate
.kind().skip_binder()
41 // If the projection predicate (Foo::Bar == X) has X as a non-TyVid,
42 // we need to make it into one.
43 if let Some(vid
) = predicate
.term
.ty().and_then(|ty
| ty
.ty_vid()) {
44 debug
!("relationship: {:?}.output = true", vid
);
45 engine
.relationships().entry(vid
).or_default().output
= true;