1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
use rustc_data_structures::fx::FxHashMap;
use rustc_hir::def_id::DefId;
use rustc_middle::ty::{self, OutlivesPredicate, TyCtxt};

use super::utils::*;

#[derive(Debug)]
pub struct ExplicitPredicatesMap<'tcx> {
    map: FxHashMap<DefId, ty::EarlyBinder<RequiredPredicates<'tcx>>>,
}

impl<'tcx> ExplicitPredicatesMap<'tcx> {
    pub fn new() -> ExplicitPredicatesMap<'tcx> {
        ExplicitPredicatesMap { map: FxHashMap::default() }
    }

    pub(crate) fn explicit_predicates_of(
        &mut self,
        tcx: TyCtxt<'tcx>,
        def_id: DefId,
    ) -> &ty::EarlyBinder<RequiredPredicates<'tcx>> {
        self.map.entry(def_id).or_insert_with(|| {
            let predicates = if def_id.is_local() {
                tcx.explicit_predicates_of(def_id)
            } else {
                tcx.predicates_of(def_id)
            };
            let mut required_predicates = RequiredPredicates::default();

            // process predicates and convert to `RequiredPredicates` entry, see below
            for &(predicate, span) in predicates.predicates {
                match predicate.kind().skip_binder() {
                    ty::PredicateKind::TypeOutlives(OutlivesPredicate(ty, reg)) => {
                        insert_outlives_predicate(
                            tcx,
                            ty.into(),
                            reg,
                            span,
                            &mut required_predicates,
                        )
                    }

                    ty::PredicateKind::RegionOutlives(OutlivesPredicate(reg1, reg2)) => {
                        insert_outlives_predicate(
                            tcx,
                            reg1.into(),
                            reg2,
                            span,
                            &mut required_predicates,
                        )
                    }

                    ty::PredicateKind::Trait(..)
                    | ty::PredicateKind::Projection(..)
                    | ty::PredicateKind::WellFormed(..)
                    | ty::PredicateKind::ObjectSafe(..)
                    | ty::PredicateKind::ClosureKind(..)
                    | ty::PredicateKind::Subtype(..)
                    | ty::PredicateKind::Coerce(..)
                    | ty::PredicateKind::ConstEvaluatable(..)
                    | ty::PredicateKind::ConstEquate(..)
                    | ty::PredicateKind::TypeWellFormedFromEnv(..) => (),
                }
            }

            ty::EarlyBinder(required_predicates)
        })
    }
}