Skip to content

Commit a58099b

Browse files
Move some files around
1 parent 8199be0 commit a58099b

File tree

12 files changed

+1556
-1528
lines changed

12 files changed

+1556
-1528
lines changed
Lines changed: 258 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,258 @@
1+
use rustc_data_structures::stable_hasher::HashStable;
2+
use rustc_serialize::{Decodable, Decoder, Encodable};
3+
use std::cmp::Ordering;
4+
use std::fmt;
5+
use std::hash;
6+
7+
use crate::{
8+
DebruijnIndex, DebugWithInfcx, HashStableContext, InferCtxtLike, Interner, OptWithInfcx,
9+
TyDecoder, TyEncoder,
10+
};
11+
12+
use self::ConstKind::*;
13+
14+
/// Represents a constant in Rust.
15+
// #[derive(derive_more::From)]
16+
pub enum ConstKind<I: Interner> {
17+
/// A const generic parameter.
18+
Param(I::ParamConst),
19+
20+
/// Infer the value of the const.
21+
Infer(I::InferConst),
22+
23+
/// Bound const variable, used only when preparing a trait query.
24+
Bound(DebruijnIndex, I::BoundConst),
25+
26+
/// A placeholder const - universally quantified higher-ranked const.
27+
Placeholder(I::PlaceholderConst),
28+
29+
/// An unnormalized const item such as an anon const or assoc const or free const item.
30+
/// Right now anything other than anon consts does not actually work properly but this
31+
/// should
32+
Unevaluated(I::AliasConst),
33+
34+
/// Used to hold computed value.
35+
Value(I::ValueConst),
36+
37+
/// A placeholder for a const which could not be computed; this is
38+
/// propagated to avoid useless error messages.
39+
Error(I::ErrorGuaranteed),
40+
41+
/// Unevaluated non-const-item, used by `feature(generic_const_exprs)` to represent
42+
/// const arguments such as `N + 1` or `foo(N)`
43+
Expr(I::ExprConst),
44+
}
45+
46+
const fn const_kind_discriminant<I: Interner>(value: &ConstKind<I>) -> usize {
47+
match value {
48+
Param(_) => 0,
49+
Infer(_) => 1,
50+
Bound(_, _) => 2,
51+
Placeholder(_) => 3,
52+
Unevaluated(_) => 4,
53+
Value(_) => 5,
54+
Error(_) => 6,
55+
Expr(_) => 7,
56+
}
57+
}
58+
59+
impl<I: Interner> hash::Hash for ConstKind<I> {
60+
fn hash<H: hash::Hasher>(&self, state: &mut H) {
61+
const_kind_discriminant(self).hash(state);
62+
match self {
63+
Param(p) => p.hash(state),
64+
Infer(i) => i.hash(state),
65+
Bound(d, b) => {
66+
d.hash(state);
67+
b.hash(state);
68+
}
69+
Placeholder(p) => p.hash(state),
70+
Unevaluated(u) => u.hash(state),
71+
Value(v) => v.hash(state),
72+
Error(e) => e.hash(state),
73+
Expr(e) => e.hash(state),
74+
}
75+
}
76+
}
77+
78+
impl<CTX: HashStableContext, I: Interner> HashStable<CTX> for ConstKind<I>
79+
where
80+
I::ParamConst: HashStable<CTX>,
81+
I::InferConst: HashStable<CTX>,
82+
I::BoundConst: HashStable<CTX>,
83+
I::PlaceholderConst: HashStable<CTX>,
84+
I::AliasConst: HashStable<CTX>,
85+
I::ValueConst: HashStable<CTX>,
86+
I::ErrorGuaranteed: HashStable<CTX>,
87+
I::ExprConst: HashStable<CTX>,
88+
{
89+
fn hash_stable(
90+
&self,
91+
hcx: &mut CTX,
92+
hasher: &mut rustc_data_structures::stable_hasher::StableHasher,
93+
) {
94+
const_kind_discriminant(self).hash_stable(hcx, hasher);
95+
match self {
96+
Param(p) => p.hash_stable(hcx, hasher),
97+
Infer(i) => i.hash_stable(hcx, hasher),
98+
Bound(d, b) => {
99+
d.hash_stable(hcx, hasher);
100+
b.hash_stable(hcx, hasher);
101+
}
102+
Placeholder(p) => p.hash_stable(hcx, hasher),
103+
Unevaluated(u) => u.hash_stable(hcx, hasher),
104+
Value(v) => v.hash_stable(hcx, hasher),
105+
Error(e) => e.hash_stable(hcx, hasher),
106+
Expr(e) => e.hash_stable(hcx, hasher),
107+
}
108+
}
109+
}
110+
111+
impl<I: Interner, D: TyDecoder<I = I>> Decodable<D> for ConstKind<I>
112+
where
113+
I::ParamConst: Decodable<D>,
114+
I::InferConst: Decodable<D>,
115+
I::BoundConst: Decodable<D>,
116+
I::PlaceholderConst: Decodable<D>,
117+
I::AliasConst: Decodable<D>,
118+
I::ValueConst: Decodable<D>,
119+
I::ErrorGuaranteed: Decodable<D>,
120+
I::ExprConst: Decodable<D>,
121+
{
122+
fn decode(d: &mut D) -> Self {
123+
match Decoder::read_usize(d) {
124+
0 => Param(Decodable::decode(d)),
125+
1 => Infer(Decodable::decode(d)),
126+
2 => Bound(Decodable::decode(d), Decodable::decode(d)),
127+
3 => Placeholder(Decodable::decode(d)),
128+
4 => Unevaluated(Decodable::decode(d)),
129+
5 => Value(Decodable::decode(d)),
130+
6 => Error(Decodable::decode(d)),
131+
7 => Expr(Decodable::decode(d)),
132+
_ => panic!(
133+
"{}",
134+
format!(
135+
"invalid enum variant tag while decoding `{}`, expected 0..{}",
136+
"ConstKind", 8,
137+
)
138+
),
139+
}
140+
}
141+
}
142+
143+
impl<I: Interner, E: TyEncoder<I = I>> Encodable<E> for ConstKind<I>
144+
where
145+
I::ParamConst: Encodable<E>,
146+
I::InferConst: Encodable<E>,
147+
I::BoundConst: Encodable<E>,
148+
I::PlaceholderConst: Encodable<E>,
149+
I::AliasConst: Encodable<E>,
150+
I::ValueConst: Encodable<E>,
151+
I::ErrorGuaranteed: Encodable<E>,
152+
I::ExprConst: Encodable<E>,
153+
{
154+
fn encode(&self, e: &mut E) {
155+
let disc = const_kind_discriminant(self);
156+
match self {
157+
Param(p) => e.emit_enum_variant(disc, |e| p.encode(e)),
158+
Infer(i) => e.emit_enum_variant(disc, |e| i.encode(e)),
159+
Bound(d, b) => e.emit_enum_variant(disc, |e| {
160+
d.encode(e);
161+
b.encode(e);
162+
}),
163+
Placeholder(p) => e.emit_enum_variant(disc, |e| p.encode(e)),
164+
Unevaluated(u) => e.emit_enum_variant(disc, |e| u.encode(e)),
165+
Value(v) => e.emit_enum_variant(disc, |e| v.encode(e)),
166+
Error(er) => e.emit_enum_variant(disc, |e| er.encode(e)),
167+
Expr(ex) => e.emit_enum_variant(disc, |e| ex.encode(e)),
168+
}
169+
}
170+
}
171+
172+
impl<I: Interner> PartialOrd for ConstKind<I> {
173+
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
174+
Some(self.cmp(other))
175+
}
176+
}
177+
178+
impl<I: Interner> Ord for ConstKind<I> {
179+
fn cmp(&self, other: &Self) -> Ordering {
180+
const_kind_discriminant(self)
181+
.cmp(&const_kind_discriminant(other))
182+
.then_with(|| match (self, other) {
183+
(Param(p1), Param(p2)) => p1.cmp(p2),
184+
(Infer(i1), Infer(i2)) => i1.cmp(i2),
185+
(Bound(d1, b1), Bound(d2, b2)) => d1.cmp(d2).then_with(|| b1.cmp(b2)),
186+
(Placeholder(p1), Placeholder(p2)) => p1.cmp(p2),
187+
(Unevaluated(u1), Unevaluated(u2)) => u1.cmp(u2),
188+
(Value(v1), Value(v2)) => v1.cmp(v2),
189+
(Error(e1), Error(e2)) => e1.cmp(e2),
190+
(Expr(e1), Expr(e2)) => e1.cmp(e2),
191+
_ => {
192+
debug_assert!(false, "This branch must be unreachable, maybe the match is missing an arm? self = {self:?}, other = {other:?}");
193+
Ordering::Equal
194+
}
195+
})
196+
}
197+
}
198+
199+
impl<I: Interner> PartialEq for ConstKind<I> {
200+
fn eq(&self, other: &Self) -> bool {
201+
match (self, other) {
202+
(Param(l0), Param(r0)) => l0 == r0,
203+
(Infer(l0), Infer(r0)) => l0 == r0,
204+
(Bound(l0, l1), Bound(r0, r1)) => l0 == r0 && l1 == r1,
205+
(Placeholder(l0), Placeholder(r0)) => l0 == r0,
206+
(Unevaluated(l0), Unevaluated(r0)) => l0 == r0,
207+
(Value(l0), Value(r0)) => l0 == r0,
208+
(Error(l0), Error(r0)) => l0 == r0,
209+
(Expr(l0), Expr(r0)) => l0 == r0,
210+
_ => false,
211+
}
212+
}
213+
}
214+
215+
impl<I: Interner> Eq for ConstKind<I> {}
216+
217+
impl<I: Interner> Clone for ConstKind<I> {
218+
fn clone(&self) -> Self {
219+
match self {
220+
Param(arg0) => Param(arg0.clone()),
221+
Infer(arg0) => Infer(arg0.clone()),
222+
Bound(arg0, arg1) => Bound(arg0.clone(), arg1.clone()),
223+
Placeholder(arg0) => Placeholder(arg0.clone()),
224+
Unevaluated(arg0) => Unevaluated(arg0.clone()),
225+
Value(arg0) => Value(arg0.clone()),
226+
Error(arg0) => Error(arg0.clone()),
227+
Expr(arg0) => Expr(arg0.clone()),
228+
}
229+
}
230+
}
231+
232+
impl<I: Interner> fmt::Debug for ConstKind<I> {
233+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
234+
OptWithInfcx::new_no_ctx(self).fmt(f)
235+
}
236+
}
237+
238+
impl<I: Interner> DebugWithInfcx<I> for ConstKind<I> {
239+
fn fmt<InfCtx: InferCtxtLike<I>>(
240+
this: OptWithInfcx<'_, I, InfCtx, &Self>,
241+
f: &mut core::fmt::Formatter<'_>,
242+
) -> core::fmt::Result {
243+
use ConstKind::*;
244+
245+
match this.data {
246+
Param(param) => write!(f, "{param:?}"),
247+
Infer(var) => write!(f, "{:?}", &this.wrap(var)),
248+
Bound(debruijn, var) => crate::debug_bound_var(f, *debruijn, var.clone()),
249+
Placeholder(placeholder) => write!(f, "{placeholder:?}"),
250+
Unevaluated(uv) => {
251+
write!(f, "{:?}", &this.wrap(uv))
252+
}
253+
Value(valtree) => write!(f, "{valtree:?}"),
254+
Error(_) => write!(f, "{{const error}}"),
255+
Expr(expr) => write!(f, "{:?}", &this.wrap(expr)),
256+
}
257+
}
258+
}

0 commit comments

Comments
 (0)