1use crate::prelude::*;
2
3#[derive_group(Serializers)]
4#[derive(Clone, Debug, JsonSchema, Hash, PartialEq, Eq, PartialOrd, Ord)]
5pub enum ConstantInt {
6 Int(
7 #[serde(with = "serialize_int::signed")]
8 #[schemars(with = "String")]
9 i128,
10 IntTy,
11 ),
12 Uint(
13 #[serde(with = "serialize_int::unsigned")]
14 #[schemars(with = "String")]
15 u128,
16 UintTy,
17 ),
18}
19
20#[derive_group(Serializers)]
21#[derive(Clone, Debug, JsonSchema, Hash, PartialEq, Eq, PartialOrd, Ord)]
22pub enum ConstantLiteral {
23 Bool(bool),
24 Char(char),
25 Float(String, FloatTy),
26 Int(ConstantInt),
27 PtrNoProvenance(u128),
28 Str(String),
29 ByteStr(Vec<u8>),
30}
31
32#[derive_group(Serializers)]
34#[derive(Clone, Debug, JsonSchema, Hash, PartialEq, Eq, PartialOrd, Ord)]
35pub enum ConstantExprKind {
36 Literal(ConstantLiteral),
37 Adt {
39 info: VariantInformations,
40 fields: Vec<ConstantFieldExpr>,
41 repr: ReprOptions,
42 },
43 Array {
44 fields: Vec<ConstantExpr>,
45 },
46 Tuple {
47 fields: Vec<ConstantExpr>,
48 },
49 GlobalName(ItemRef),
66 TraitConst {
75 impl_expr: ImplExpr,
76 name: String,
77 },
78 Borrow(ConstantExpr),
80 RawBorrow {
82 mutability: Mutability,
83 arg: ConstantExpr,
84 },
85 Cast {
90 source: ConstantExpr,
91 },
92 ConstRef {
93 id: ParamConst,
94 },
95 FnPtr(ItemRef),
96 Memory(Vec<u8>),
100 Todo(String),
101}
102
103#[derive_group(Serializers)]
104#[derive(Clone, Debug, JsonSchema, Hash, PartialEq, Eq, PartialOrd, Ord)]
105pub struct ConstantFieldExpr {
106 pub field: DefId,
107 pub value: ConstantExpr,
108}
109
110pub type ConstantExpr = Decorated<ConstantExprKind>;
115
116pub type ConstantKind = ConstantExpr;
118
119impl From<ConstantFieldExpr> for FieldExpr {
120 fn from(c: ConstantFieldExpr) -> FieldExpr {
121 FieldExpr {
122 value: c.value.into(),
123 field: c.field,
124 }
125 }
126}
127
128impl From<ConstantExpr> for Expr {
129 fn from(c: ConstantExpr) -> Expr {
130 use ConstantExprKind::*;
131 let kind = match *c.contents {
132 Literal(lit) => {
133 use ConstantLiteral::*;
134 let mut neg = false;
135 let node = match lit {
136 Bool(b) => LitKind::Bool(b),
137 Char(c) => LitKind::Char(c),
138 Int(i) => {
139 use LitIntType::*;
140 match i {
141 ConstantInt::Uint(v, t) => LitKind::Int(v, Unsigned(t)),
142 ConstantInt::Int(v, t) => {
143 neg = v.is_negative();
144 LitKind::Int(v.abs_diff(0), Signed(t))
145 }
146 }
147 }
148 Float(f, ty) => LitKind::Float(f, LitFloatType::Suffixed(ty)),
149 PtrNoProvenance(p) => LitKind::Int(p, LitIntType::Unsigned(UintTy::Usize)),
150 ByteStr(raw) => LitKind::ByteStr(raw, StrStyle::Cooked),
151 Str(raw) => LitKind::Str(raw, StrStyle::Cooked),
152 };
153 let span = c.span.clone();
154 let lit = Spanned { span, node };
155 ExprKind::Literal { lit, neg }
156 }
157 Adt { info, fields, repr } => ExprKind::Adt(AdtExpr {
158 info,
159 fields: fields.into_iter().map(|field| field.into()).collect(),
160 base: AdtExprBase::None,
161 user_ty: None,
162 repr,
163 }),
164 GlobalName(item) => ExprKind::GlobalName {
165 item,
166 constructor: None,
167 },
168 Borrow(e) => ExprKind::Borrow {
169 borrow_kind: BorrowKind::Shared,
170 arg: e.into(),
171 },
172 RawBorrow { mutability, arg } => ExprKind::RawBorrow {
173 mutability,
174 arg: arg.into(),
175 },
176 ConstRef { id } => ExprKind::ConstRef { id },
177 Array { fields } => ExprKind::Array {
178 fields: fields.into_iter().map(|field| field.into()).collect(),
179 },
180 Tuple { fields } => ExprKind::Tuple {
181 fields: fields.into_iter().map(|field| field.into()).collect(),
182 },
183 Cast { source } => ExprKind::Cast {
184 source: source.into(),
185 },
186 kind @ (FnPtr { .. } | TraitConst { .. } | Memory { .. }) => {
187 ExprKind::Todo(format!("Unsupported constant kind. kind={:#?}", kind))
188 }
189 Todo(msg) => ExprKind::Todo(msg),
190 };
191 Decorated {
192 contents: Box::new(kind),
193 ty: c.ty,
194 span: c.span,
195 hir_id: c.hir_id,
196 attributes: c.attributes,
197 }
198 }
199}
200
201#[cfg(feature = "rustc")]
202pub use self::uneval::*;
203#[cfg(feature = "rustc")]
204mod uneval;