charon_driver/translate/
translate_constants.rs1use rustc_middle::ty;
3
4use crate::translate::translate_bodies::translate_variant_id;
5
6use super::translate_ctx::*;
7use charon_lib::ast::*;
8
9impl<'tcx, 'ctx> ItemTransCtx<'tcx, 'ctx> {
10 fn translate_constant_literal_to_constant_expr_kind(
11 &mut self,
12 span: Span,
13 v: &hax::ConstantLiteral,
14 ) -> Result<ConstantExprKind, Error> {
15 let lit = match v {
16 hax::ConstantLiteral::ByteStr(bs) => Literal::ByteStr(bs.clone()),
17 hax::ConstantLiteral::Str(..) => {
18 raise_error!(self, span, "found a `str` constants not behind a reference")
21 }
22 hax::ConstantLiteral::Char(c) => Literal::Char(*c),
23 hax::ConstantLiteral::Bool(b) => Literal::Bool(*b),
24 hax::ConstantLiteral::Int(i) => {
25 use hax::ConstantInt;
26 let scalar = match i {
27 ConstantInt::Int(v, int_type) => {
28 let ty = Self::translate_hax_int_ty(int_type);
29 ScalarValue::Signed(ty, *v)
30 }
31 ConstantInt::Uint(v, uint_type) => {
32 let ty = Self::translate_hax_uint_ty(uint_type);
33 ScalarValue::Unsigned(ty, *v)
34 }
35 };
36 Literal::Scalar(scalar)
37 }
38 hax::ConstantLiteral::Float(value, float_type) => {
39 let value = value.clone();
40 let ty = match float_type {
41 hax::FloatTy::F16 => FloatTy::F16,
42 hax::FloatTy::F32 => FloatTy::F32,
43 hax::FloatTy::F64 => FloatTy::F64,
44 hax::FloatTy::F128 => FloatTy::F128,
45 };
46 Literal::Float(FloatValue { value, ty })
47 }
48 hax::ConstantLiteral::PtrNoProvenance(v) => {
49 return Ok(ConstantExprKind::PtrNoProvenance(*v));
50 }
51 };
52 Ok(ConstantExprKind::Literal(lit))
53 }
54
55 pub(crate) fn translate_constant_expr(
61 &mut self,
62 span: Span,
63 v: &hax::ConstantExpr,
64 ) -> Result<ConstantExpr, Error> {
65 let ty = self.translate_ty(span, &v.ty)?;
66 let kind = match v.contents.as_ref() {
67 hax::ConstantExprKind::Literal(lit) => {
68 self.translate_constant_literal_to_constant_expr_kind(span, lit)?
69 }
70 hax::ConstantExprKind::Adt { kind, fields } => {
71 let fields: Vec<ConstantExpr> = fields
72 .iter()
73 .map(|f| self.translate_constant_expr(span, &f.value))
74 .try_collect()?;
75 use hax::VariantKind;
76 let vid = if let VariantKind::Enum { index, .. } = *kind {
77 Some(translate_variant_id(index))
78 } else {
79 None
80 };
81 ConstantExprKind::Adt(vid, fields)
82 }
83 hax::ConstantExprKind::Array { fields } => {
84 let fields: Vec<ConstantExpr> = fields
85 .iter()
86 .map(|x| self.translate_constant_expr(span, x))
87 .try_collect()?;
88
89 if matches!(v.ty.kind(), hax::TyKind::Slice { .. }) {
90 ConstantExprKind::Slice(fields)
91 } else {
92 ConstantExprKind::Array(fields)
93 }
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 name = self.translate_trait_item_name(&item.def_id)?;
109 ConstantExprKind::TraitConst(trait_ref, name)
110 }
111 None => {
112 let global_ref = self.translate_global_decl_ref(span, item)?;
113 ConstantExprKind::Global(global_ref)
114 }
115 },
116 hax::ConstantExprKind::Borrow(v)
117 if let hax::ConstantExprKind::Literal(hax::ConstantLiteral::Str(s)) =
118 v.contents.as_ref() =>
119 {
120 ConstantExprKind::Literal(Literal::Str(s.clone()))
121 }
122 hax::ConstantExprKind::Borrow(v) => {
123 let val = self.translate_constant_expr(span, v)?;
124 ConstantExprKind::Ref(Box::new(val))
125 }
126 hax::ConstantExprKind::Cast { .. } => {
127 register_error!(
128 self,
129 span,
130 "Unsupported constant: `ConstantExprKind::Cast {{..}}`",
131 );
132 ConstantExprKind::Opaque("`ConstantExprKind::Cast {{..}}`".into())
133 }
134 hax::ConstantExprKind::RawBorrow { mutability, arg } => {
135 let arg = self.translate_constant_expr(span, arg)?;
136 let rk = RefKind::mutable(mutability.is_mut());
137 ConstantExprKind::Ptr(rk, Box::new(arg))
138 }
139 hax::ConstantExprKind::ConstRef { id } => {
140 match self.lookup_const_generic_var(span, id) {
141 Ok(var) => ConstantExprKind::Var(var),
142 Err(err) => ConstantExprKind::Opaque(err.msg),
143 }
144 }
145 hax::ConstantExprKind::FnDef(item) => {
146 let fn_ptr = self.translate_fn_ptr(span, item, TransItemSourceKind::Fun)?;
147 ConstantExprKind::FnDef(fn_ptr)
148 }
149 hax::ConstantExprKind::FnPtr(item) => {
150 let fn_ptr = self.translate_fn_ptr(span, item, TransItemSourceKind::Fun)?;
151 ConstantExprKind::FnPtr(fn_ptr)
152 }
153 hax::ConstantExprKind::Memory(bytes) => {
154 ConstantExprKind::RawMemory(bytes.iter().map(|b| Byte::Value(*b)).collect())
155 }
156 hax::ConstantExprKind::Todo(msg) => {
157 register_error!(self, span, "Unsupported constant: {:?}", msg);
158 ConstantExprKind::Opaque(msg.into())
159 }
160 };
161
162 Ok(ConstantExpr { kind, ty })
163 }
164
165 pub(crate) fn translate_ty_constant_expr(
166 &mut self,
167 span: Span,
168 c: &ty::Const<'tcx>,
169 ) -> Result<ConstantExpr, Error> {
170 let c = self.catch_sinto(span, c)?;
171 self.translate_constant_expr(span, &c)
172 }
173}