Unnamed repository; edit this file 'description' to name the repository.
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
120
121
122
123
124
125
126
127
use hir_def::TraitId;
use macros::{TypeFoldable, TypeVisitable};

use crate::{
    FnAbi,
    next_solver::{
        Binder, Clauses, DbInterner, EarlyBinder, FnSig, GenericArg, PolyFnSig,
        StoredBoundVarKinds, StoredClauses, StoredGenericArg, StoredGenericArgs, StoredTy,
        StoredTys, TraitRef, Ty, abi::Safety,
    },
};

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct StoredEarlyBinder<T>(T);

impl<T> StoredEarlyBinder<T> {
    #[inline]
    pub fn bind(value: T) -> Self {
        Self(value)
    }

    #[inline]
    pub fn skip_binder(self) -> T {
        self.0
    }

    #[inline]
    pub fn as_ref(&self) -> StoredEarlyBinder<&T> {
        StoredEarlyBinder(&self.0)
    }

    #[inline]
    pub fn get_with<'db, 'a, R>(&'a self, f: impl FnOnce(&'a T) -> R) -> EarlyBinder<'db, R> {
        EarlyBinder::bind(f(&self.0))
    }
}

impl StoredEarlyBinder<StoredTy> {
    #[inline]
    pub fn get<'db>(&self) -> EarlyBinder<'db, Ty<'db>> {
        self.get_with(|it| it.as_ref())
    }
}

impl StoredEarlyBinder<StoredGenericArg> {
    #[inline]
    pub fn get<'db>(&self) -> EarlyBinder<'db, GenericArg<'db>> {
        self.get_with(|it| it.as_ref())
    }
}

impl StoredEarlyBinder<StoredClauses> {
    #[inline]
    pub fn get<'db>(&self) -> EarlyBinder<'db, Clauses<'db>> {
        self.get_with(|it| it.as_ref())
    }
}

impl StoredEarlyBinder<StoredPolyFnSig> {
    #[inline]
    pub fn get<'db>(&'db self) -> EarlyBinder<'db, PolyFnSig<'db>> {
        self.get_with(|it| it.get())
    }
}

impl StoredEarlyBinder<StoredTraitRef> {
    #[inline]
    pub fn get<'db>(&'db self, interner: DbInterner<'db>) -> EarlyBinder<'db, TraitRef<'db>> {
        self.get_with(|it| it.get(interner))
    }
}

#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct StoredPolyFnSig {
    bound_vars: StoredBoundVarKinds,
    inputs_and_output: StoredTys,
    c_variadic: bool,
    safety: Safety,
    abi: FnAbi,
}

impl StoredPolyFnSig {
    #[inline]
    pub fn new(sig: PolyFnSig<'_>) -> Self {
        let bound_vars = sig.bound_vars().store();
        let sig = sig.skip_binder();
        Self {
            bound_vars,
            inputs_and_output: sig.inputs_and_output.store(),
            c_variadic: sig.c_variadic,
            safety: sig.safety,
            abi: sig.abi,
        }
    }

    #[inline]
    pub fn get(&self) -> PolyFnSig<'_> {
        Binder::bind_with_vars(
            FnSig {
                inputs_and_output: self.inputs_and_output.as_ref(),
                c_variadic: self.c_variadic,
                safety: self.safety,
                abi: self.abi,
            },
            self.bound_vars.as_ref(),
        )
    }
}

#[derive(Debug, Clone, PartialEq, Eq, Hash, TypeVisitable, TypeFoldable)]
pub struct StoredTraitRef {
    #[type_visitable(ignore)]
    def_id: TraitId,
    args: StoredGenericArgs,
}

impl StoredTraitRef {
    #[inline]
    pub fn new(trait_ref: TraitRef<'_>) -> Self {
        Self { def_id: trait_ref.def_id.0, args: trait_ref.args.store() }
    }

    #[inline]
    pub fn get<'db>(&'db self, interner: DbInterner<'db>) -> TraitRef<'db> {
        TraitRef::new_from_args(interner, self.def_id.into(), self.args.as_ref())
    }
}