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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
use rustc_hir::def_id::DefId;
use rustc_index::vec::{Idx, IndexVec};

use crate::middle::exported_symbols::ExportedSymbol;
use crate::mir::Body;
use crate::ty::abstract_const::Node;
use crate::ty::{
    self, Const, FnSig, GeneratorDiagnosticData, GenericPredicates, Predicate, TraitRef, Ty,
};

pub trait ParameterizedOverTcx: 'static {
    #[allow(unused_lifetimes)]
    type Value<'tcx>;
}

impl<T: ParameterizedOverTcx> ParameterizedOverTcx for &'static [T] {
    type Value<'tcx> = &'tcx [T::Value<'tcx>];
}

impl<T: ParameterizedOverTcx> ParameterizedOverTcx for Option<T> {
    type Value<'tcx> = Option<T::Value<'tcx>>;
}

impl<A: ParameterizedOverTcx, B: ParameterizedOverTcx> ParameterizedOverTcx for (A, B) {
    type Value<'tcx> = (A::Value<'tcx>, B::Value<'tcx>);
}

impl<I: Idx + 'static, T: ParameterizedOverTcx> ParameterizedOverTcx for IndexVec<I, T> {
    type Value<'tcx> = IndexVec<I, T::Value<'tcx>>;
}

impl<T: ParameterizedOverTcx> ParameterizedOverTcx for ty::Binder<'static, T> {
    type Value<'tcx> = ty::Binder<'tcx, T::Value<'tcx>>;
}

#[macro_export]
macro_rules! trivially_parameterized_over_tcx {
    ($($ty:ty),+ $(,)?) => {
        $(
            impl $crate::ty::ParameterizedOverTcx for $ty {
                #[allow(unused_lifetimes)]
                type Value<'tcx> = $ty;
            }
        )*
    }
}

trivially_parameterized_over_tcx! {
    usize,
    (),
    u32,
    std::string::String,
    crate::metadata::ModChild,
    crate::middle::codegen_fn_attrs::CodegenFnAttrs,
    crate::middle::exported_symbols::SymbolExportInfo,
    crate::mir::ConstQualifs,
    ty::Generics,
    ty::ImplPolarity,
    ty::ReprOptions,
    ty::TraitDef,
    ty::Visibility,
    ty::adjustment::CoerceUnsizedInfo,
    ty::fast_reject::SimplifiedTypeGen<DefId>,
    rustc_ast::Attribute,
    rustc_ast::MacArgs,
    rustc_attr::ConstStability,
    rustc_attr::Deprecation,
    rustc_attr::Stability,
    rustc_hir::Constness,
    rustc_hir::Defaultness,
    rustc_hir::GeneratorKind,
    rustc_hir::IsAsync,
    rustc_hir::LangItem,
    rustc_hir::def::DefKind,
    rustc_hir::def_id::DefIndex,
    rustc_hir::definitions::DefKey,
    rustc_index::bit_set::FiniteBitSet<u32>,
    rustc_session::cstore::ForeignModule,
    rustc_session::cstore::LinkagePreference,
    rustc_session::cstore::NativeLib,
    rustc_span::DebuggerVisualizerFile,
    rustc_span::ExpnData,
    rustc_span::ExpnHash,
    rustc_span::ExpnId,
    rustc_span::SourceFile,
    rustc_span::Span,
    rustc_span::Symbol,
    rustc_span::def_id::DefPathHash,
    rustc_span::hygiene::SyntaxContextData,
    rustc_span::symbol::Ident,
    rustc_type_ir::Variance,
}

// HACK(compiler-errors): This macro rule can only take an ident,
// not a path, due to parsing ambiguity reasons. That means we gotta
// import all of these types above.
#[macro_export]
macro_rules! parameterized_over_tcx {
    ($($ident:ident),+ $(,)?) => {
        $(
            impl $crate::ty::ParameterizedOverTcx for $ident<'static> {
                type Value<'tcx> = $ident<'tcx>;
            }
        )*
    }
}

parameterized_over_tcx! {
    Ty,
    FnSig,
    GenericPredicates,
    TraitRef,
    Const,
    Predicate,
    GeneratorDiagnosticData,
    Body,
    Node,
    ExportedSymbol,
}