1 use crate::infer
::InferCtxt
;
2 use crate::traits
::query
::evaluate_obligation
::InferCtxtExt
;
3 use crate::traits
::{ObligationCause, PredicateObligation}
;
4 use rustc_infer
::traits
::TraitEngine
;
5 use rustc_middle
::ty
::{self, ToPredicate}
;
7 pub(crate) fn update
<'tcx
, T
>(
9 infcx
: &InferCtxt
<'_
, 'tcx
>,
10 obligation
: &PredicateObligation
<'tcx
>,
15 if let ty
::PredicateKind
::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 let trait_ref
= ty
::TraitRef
{
22 substs
: infcx
.tcx
.mk_substs_trait(new_self_ty
, &tpred
.trait_ref
.substs
[1..]),
26 // Then construct a new obligation with Self = () added
27 // to the ParamEnv, and see if it holds.
28 let o
= rustc_infer
::traits
::Obligation
::new(
29 ObligationCause
::dummy(),
35 // (*) binder moved here
36 ty
::PredicateKind
::Trait(ty
::TraitPredicate
{
38 constness
: tpred
.constness
,
39 polarity
: tpred
.polarity
,
42 .to_predicate(infcx
.tcx
),
44 // Don't report overflow errors. Otherwise equivalent to may_hold.
45 if let Ok(result
) = infcx
.probe(|_
| infcx
.evaluate_obligation(&o
)) && result
.may_apply() {
46 engine
.relationships().entry(ty
).or_default().self_in_trait
= true;
50 if let ty
::PredicateKind
::Projection(predicate
) = obligation
.predicate
.kind().skip_binder() {
51 // If the projection predicate (Foo::Bar == X) has X as a non-TyVid,
52 // we need to make it into one.
53 if let Some(vid
) = predicate
.term
.ty().and_then(|ty
| ty
.ty_vid()) {
54 debug
!("relationship: {:?}.output = true", vid
);
55 engine
.relationships().entry(vid
).or_default().output
= true;