charon_driver/translate/
translate_constants.rs1use crate::hax;
3use rustc_middle::ty;
4
5use super::translate_ctx::*;
6use charon_lib::ast::*;
7
8impl<'tcx, 'ctx> ItemTransCtx<'tcx, 'ctx> {
9 fn translate_constant_literal_to_constant_expr_kind(
10 &mut self,
11 _span: Span,
12 v: &hax::ConstantLiteral,
13 ) -> Result<ConstantExprKind, Error> {
14 let lit = match v {
15 hax::ConstantLiteral::ByteStr(bs) => Literal::ByteStr(bs.clone()),
16 hax::ConstantLiteral::Str(str) => {
17 assert!(self.t_ctx.options.unsized_strings);
20
21 let str_bytes = str.as_bytes();
22 return Ok(ConstantExprKind::RawMemory(
23 str_bytes.iter().map(|b| Byte::Value(*b)).collect(),
24 ));
25 }
26 hax::ConstantLiteral::Char(c) => Literal::Char(*c),
27 hax::ConstantLiteral::Bool(b) => Literal::Bool(*b),
28 hax::ConstantLiteral::Int(i) => {
29 use crate::hax::ConstantInt;
30 let scalar = match i {
31 ConstantInt::Int(v, int_type) => {
32 let ty = Self::translate_hax_int_ty(int_type);
33 ScalarValue::Signed(ty, *v)
34 }
35 ConstantInt::Uint(v, uint_type) => {
36 let ty = Self::translate_hax_uint_ty(uint_type);
37 ScalarValue::Unsigned(ty, *v)
38 }
39 };
40 Literal::Scalar(scalar)
41 }
42 hax::ConstantLiteral::Float(value, float_type) => {
43 let value = value.clone();
44 let ty = match float_type {
45 hax::FloatTy::F16 => FloatTy::F16,
46 hax::FloatTy::F32 => FloatTy::F32,
47 hax::FloatTy::F64 => FloatTy::F64,
48 hax::FloatTy::F128 => FloatTy::F128,
49 };
50 Literal::Float(FloatValue { value, ty })
51 }
52 hax::ConstantLiteral::PtrNoProvenance(v) => {
53 return Ok(ConstantExprKind::PtrNoProvenance(*v));
54 }
55 };
56 Ok(ConstantExprKind::Literal(lit))
57 }
58
59 pub(crate) fn translate_constant_expr(
65 &mut self,
66 span: Span,
67 v: &hax::ConstantExpr,
68 ) -> Result<ConstantExpr, Error> {
69 let ty = self.translate_ty(span, &v.ty)?;
70 let kind = match v.contents.as_ref() {
71 hax::ConstantExprKind::Literal(lit) => {
72 self.translate_constant_literal_to_constant_expr_kind(span, lit)?
73 }
74 hax::ConstantExprKind::Adt { kind, fields } => {
75 let fields: Vec<ConstantExpr> = fields
76 .iter()
77 .map(|f| self.translate_constant_expr(span, &f.value))
78 .try_collect()?;
79 use crate::hax::VariantKind;
80 let vid = if let VariantKind::Enum { index, .. } = *kind {
81 Some(self.translate_variant_id(index))
82 } else {
83 None
84 };
85 ConstantExprKind::Adt(vid, fields)
86 }
87 hax::ConstantExprKind::Array { fields } => {
88 let fields: Vec<ConstantExpr> = fields
89 .iter()
90 .map(|x| self.translate_constant_expr(span, x))
91 .try_collect()?;
92
93 ConstantExprKind::Array(fields)
94 }
95 hax::ConstantExprKind::Tuple { fields } => {
96 let fields: Vec<ConstantExpr> = fields
97 .iter()
98 .map(|f| self.translate_constant_expr(span, f))
100 .try_collect()?;
101 ConstantExprKind::Adt(None, fields)
102 }
103 hax::ConstantExprKind::NamedGlobal(item) => match &item.in_trait {
104 Some(impl_expr) => {
105 let trait_ref = self.translate_trait_impl_expr(span, impl_expr)?;
106 assert!(item.generic_args.is_empty());
108 let const_id =
109 self.translate_assoc_const_id(trait_ref.trait_id(), &item.def_id)?;
110 ConstantExprKind::TraitConst(trait_ref, const_id)
111 }
112 None => {
113 let global_ref = self.translate_global_decl_ref(span, item)?;
114 ConstantExprKind::Global(global_ref)
115 }
116 },
117 hax::ConstantExprKind::Borrow(v)
118 if let hax::ConstantExprKind::Literal(hax::ConstantLiteral::Str(s)) =
119 v.contents.as_ref()
120 && !self.t_ctx.options.unsized_strings =>
121 {
122 ConstantExprKind::Literal(Literal::Str(s.clone()))
123 }
124
125 hax::ConstantExprKind::Borrow(v) => {
126 let mut val = self.translate_constant_expr(span, v)?;
127 let metadata = match (v.contents.as_ref(), val.ty.kind()) {
128 (hax::ConstantExprKind::Array { fields }, TyKind::Slice(subty)) => {
129 let len = ConstantExpr::mk_usize(ScalarValue::Unsigned(
130 UIntTy::Usize,
131 fields.len() as u128,
132 ));
133 val.ty = Ty::mk_array(subty.clone(), len.clone());
135 Some(UnsizingMetadata::Length(Box::new(len)))
136 }
137
138 (hax::ConstantExprKind::Literal(hax::ConstantLiteral::Str(s)), _) => {
139 let len = ConstantExpr::mk_usize(ScalarValue::Unsigned(
140 UIntTy::Usize,
141 s.len() as u128,
142 ));
143 let subty = TyKind::Literal(LiteralTy::UInt(UIntTy::U8)).into();
145 val.ty = Ty::mk_array(subty, len.clone());
146 Some(UnsizingMetadata::Length(Box::new(len)))
147 }
148
149 _ => None,
150 };
151 ConstantExprKind::Ref(Box::new(val), metadata)
152 }
153 hax::ConstantExprKind::Cast { .. } => {
154 register_error!(
155 self,
156 span,
157 "Unsupported constant: `ConstantExprKind::Cast {{..}}`",
158 );
159 ConstantExprKind::Opaque("`ConstantExprKind::Cast {{..}}`".into())
160 }
161 hax::ConstantExprKind::RawBorrow { mutability, arg } => {
162 let arg = self.translate_constant_expr(span, arg)?;
163 let rk = RefKind::mutable(mutability.is_mut());
164 ConstantExprKind::Ptr(rk, Box::new(arg), None)
165 }
166 hax::ConstantExprKind::ConstRef { id } => {
167 match self.lookup_const_generic_var(span, id) {
168 Ok(var) => ConstantExprKind::Var(var),
169 Err(err) => ConstantExprKind::Opaque(err.msg),
170 }
171 }
172 hax::ConstantExprKind::FnDef(item) => {
173 let fn_ptr = self.translate_fn_ptr(span, item, TransItemSourceKind::Fun)?;
174 ConstantExprKind::FnDef(fn_ptr)
175 }
176 hax::ConstantExprKind::FnPtr(item) => {
177 let fn_ptr = self.translate_fn_ptr(span, item, TransItemSourceKind::Fun)?;
178 ConstantExprKind::FnPtr(fn_ptr)
179 }
180 hax::ConstantExprKind::Memory(bytes) => {
181 ConstantExprKind::RawMemory(bytes.iter().map(|b| Byte::Value(*b)).collect())
182 }
183 hax::ConstantExprKind::Todo(msg) => {
184 register_error!(self, span, "Unsupported constant: {:?}", msg);
185 ConstantExprKind::Opaque(msg.into())
186 }
187 };
188
189 Ok(ConstantExpr { kind, ty })
190 }
191
192 pub(crate) fn translate_ty_constant_expr(
193 &mut self,
194 span: Span,
195 c: &ty::Const<'tcx>,
196 ) -> Result<ConstantExpr, Error> {
197 let c = self.catch_sinto(span, c)?;
198 self.translate_constant_expr(span, &c)
199 }
200}