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 },
42 Array {
43 fields: Vec<ConstantExpr>,
44 },
45 Tuple {
46 fields: Vec<ConstantExpr>,
47 },
48 GlobalName(ItemRef),
65 TraitConst {
74 impl_expr: ImplExpr,
75 name: String,
76 },
77 Borrow(ConstantExpr),
79 RawBorrow {
81 mutability: Mutability,
82 arg: ConstantExpr,
83 },
84 Cast {
89 source: ConstantExpr,
90 },
91 ConstRef {
92 id: ParamConst,
93 },
94 FnPtr(ItemRef),
95 Memory(Vec<u8>),
99 Todo(String),
100}
101
102#[derive_group(Serializers)]
103#[derive(Clone, Debug, JsonSchema, Hash, PartialEq, Eq, PartialOrd, Ord)]
104pub struct ConstantFieldExpr {
105 pub field: DefId,
106 pub value: ConstantExpr,
107}
108
109pub type ConstantExpr = Decorated<ConstantExprKind>;
114
115pub type ConstantKind = ConstantExpr;
117
118impl From<ConstantFieldExpr> for FieldExpr {
119 fn from(c: ConstantFieldExpr) -> FieldExpr {
120 FieldExpr {
121 value: c.value.into(),
122 field: c.field,
123 }
124 }
125}
126
127impl From<ConstantExpr> for Expr {
128 fn from(c: ConstantExpr) -> Expr {
129 use ConstantExprKind::*;
130 let kind = match *c.contents {
131 Literal(lit) => {
132 use ConstantLiteral::*;
133 let mut neg = false;
134 let node = match lit {
135 Bool(b) => LitKind::Bool(b),
136 Char(c) => LitKind::Char(c),
137 Int(i) => {
138 use LitIntType::*;
139 match i {
140 ConstantInt::Uint(v, t) => LitKind::Int(v, Unsigned(t)),
141 ConstantInt::Int(v, t) => {
142 neg = v.is_negative();
143 LitKind::Int(v.abs_diff(0), Signed(t))
144 }
145 }
146 }
147 Float(f, ty) => LitKind::Float(f, LitFloatType::Suffixed(ty)),
148 PtrNoProvenance(p) => LitKind::Int(p, LitIntType::Unsigned(UintTy::Usize)),
149 ByteStr(raw) => LitKind::ByteStr(raw, StrStyle::Cooked),
150 Str(raw) => LitKind::Str(raw, StrStyle::Cooked),
151 };
152 let span = c.span.clone();
153 let lit = Spanned { span, node };
154 ExprKind::Literal { lit, neg }
155 }
156 Adt { info, fields } => ExprKind::Adt(AdtExpr {
157 info,
158 fields: fields.into_iter().map(|field| field.into()).collect(),
159 base: AdtExprBase::None,
160 user_ty: None,
161 }),
162 GlobalName(item) => ExprKind::GlobalName {
163 item,
164 constructor: None,
165 },
166 Borrow(e) => ExprKind::Borrow {
167 borrow_kind: BorrowKind::Shared,
168 arg: e.into(),
169 },
170 RawBorrow { mutability, arg } => ExprKind::RawBorrow {
171 mutability,
172 arg: arg.into(),
173 },
174 ConstRef { id } => ExprKind::ConstRef { id },
175 Array { fields } => ExprKind::Array {
176 fields: fields.into_iter().map(|field| field.into()).collect(),
177 },
178 Tuple { fields } => ExprKind::Tuple {
179 fields: fields.into_iter().map(|field| field.into()).collect(),
180 },
181 Cast { source } => ExprKind::Cast {
182 source: source.into(),
183 },
184 kind @ (FnPtr { .. } | TraitConst { .. } | Memory { .. }) => {
185 ExprKind::Todo(format!("Unsupported constant kind. kind={:#?}", kind))
186 }
187 Todo(msg) => ExprKind::Todo(msg),
188 };
189 Decorated {
190 contents: Box::new(kind),
191 ty: c.ty,
192 span: c.span,
193 hir_id: c.hir_id,
194 attributes: c.attributes,
195 }
196 }
197}
198
199#[cfg(feature = "rustc")]
200pub use self::uneval::*;
201#[cfg(feature = "rustc")]
202mod uneval;