1 //! Constant evaluation details
3 use std::convert::TryInto;
6 builtin_type::BuiltinUint,
11 use crate::{Const, ConstData, ConstValue, Interner, TyKind};
13 /// Extension trait for [`Const`]
15 /// Is a [`Const`] unknown?
16 fn is_unknown(&self) -> bool;
19 impl ConstExt for Const {
20 fn is_unknown(&self) -> bool {
21 match self.data(&Interner).value {
23 chalk_ir::ConstValue::Concrete(chalk_ir::ConcreteConst {
24 interned: ConstScalar::Unknown,
27 // interned concrete anything else
28 chalk_ir::ConstValue::Concrete(..) => false,
31 log::error!("is_unknown was called on a non-concrete constant value! {:?}", self);
38 // FIXME: support more than just evaluating literals
39 pub fn eval_usize(expr: &Expr) -> Option<u64> {
41 Expr::Literal(Literal::Uint(v, None))
42 | Expr::Literal(Literal::Uint(v, Some(BuiltinUint::Usize))) => (*v).try_into().ok(),
47 /// Interns a possibly-unknown target usize
48 pub fn usize_const(value: Option<u64>) -> Const {
50 ty: TyKind::Scalar(chalk_ir::Scalar::Uint(chalk_ir::UintTy::Usize)).intern(&Interner),
51 value: ConstValue::Concrete(chalk_ir::ConcreteConst {
52 interned: value.map(ConstScalar::Usize).unwrap_or(ConstScalar::Unknown),