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
use crate::rustc_middle::ty::DefIdTree;
use rustc_hir::{def::DefKind, def_id::DefId};
use rustc_middle::ty::{self, Ty, TyCtxt};

pub fn provide(providers: &mut ty::query::Providers) {
    *providers = ty::query::Providers { assumed_wf_types, ..*providers };
}

fn assumed_wf_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx ty::List<Ty<'tcx>> {
    match tcx.def_kind(def_id) {
        DefKind::Fn => {
            let sig = tcx.fn_sig(def_id);
            let liberated_sig = tcx.liberate_late_bound_regions(def_id, sig);
            liberated_sig.inputs_and_output
        }
        DefKind::AssocFn => {
            let sig = tcx.fn_sig(def_id);
            let liberated_sig = tcx.liberate_late_bound_regions(def_id, sig);
            let mut assumed_wf_types: Vec<_> =
                tcx.assumed_wf_types(tcx.parent(def_id)).as_slice().into();
            assumed_wf_types.extend(liberated_sig.inputs_and_output);
            tcx.intern_type_list(&assumed_wf_types)
        }
        DefKind::Impl => match tcx.impl_trait_ref(def_id) {
            Some(trait_ref) => {
                let types: Vec<_> = trait_ref.substs.types().collect();
                tcx.intern_type_list(&types)
            }
            // Only the impl self type
            None => tcx.intern_type_list(&[tcx.type_of(def_id)]),
        },
        DefKind::AssocConst | DefKind::AssocTy => tcx.assumed_wf_types(tcx.parent(def_id)),
        DefKind::Mod
        | DefKind::Struct
        | DefKind::Union
        | DefKind::Enum
        | DefKind::Variant
        | DefKind::Trait
        | DefKind::TyAlias
        | DefKind::ForeignTy
        | DefKind::TraitAlias
        | DefKind::TyParam
        | DefKind::Const
        | DefKind::ConstParam
        | DefKind::Static(_)
        | DefKind::Ctor(_, _)
        | DefKind::Macro(_)
        | DefKind::ExternCrate
        | DefKind::Use
        | DefKind::ForeignMod
        | DefKind::AnonConst
        | DefKind::InlineConst
        | DefKind::OpaqueTy
        | DefKind::ImplTraitPlaceholder
        | DefKind::Field
        | DefKind::LifetimeParam
        | DefKind::GlobalAsm
        | DefKind::Closure
        | DefKind::Generator => ty::List::empty(),
    }
}