2 use rustc_middle
::mir
::interpret
::{LitToConstError, LitToConstInput}
;
3 use rustc_middle
::ty
::{self, ParamEnv, ScalarInt, TyCtxt}
;
4 use rustc_span
::DUMMY_SP
;
6 pub(crate) fn lit_to_const
<'tcx
>(
8 lit_input
: LitToConstInput
<'tcx
>,
9 ) -> Result
<ty
::Const
<'tcx
>, LitToConstError
> {
10 let LitToConstInput { lit, ty, neg }
= lit_input
;
13 let param_ty
= ParamEnv
::reveal_all().and(ty
);
17 LitToConstError
::Reported(tcx
.sess
.delay_span_bug(
19 format
!("couldn't compute width of literal: {:?}", lit_input
.lit
),
23 trace
!("trunc {} with size {} and shift {}", n
, width
.bits(), 128 - width
.bits());
24 let result
= width
.truncate(n
);
25 trace
!("trunc result: {}", result
);
27 Ok(ScalarInt
::try_from_uint(result
, width
)
28 .unwrap_or_else(|| bug
!("expected to create ScalarInt from uint {:?}", result
)))
31 let valtree
= match (lit
, &ty
.kind()) {
32 (ast
::LitKind
::Str(s
, _
), ty
::Ref(_
, inner_ty
, _
)) if inner_ty
.is_str() => {
33 let str_bytes
= s
.as_str().as_bytes();
34 ty
::ValTree
::from_raw_bytes(tcx
, str_bytes
)
36 (ast
::LitKind
::ByteStr(data
, _
), ty
::Ref(_
, inner_ty
, _
))
37 if matches
!(inner_ty
.kind(), ty
::Slice(_
)) =>
39 let bytes
= data
as &[u8];
40 ty
::ValTree
::from_raw_bytes(tcx
, bytes
)
42 (ast
::LitKind
::ByteStr(data
, _
), ty
::Ref(_
, inner_ty
, _
)) if inner_ty
.is_array() => {
43 let bytes
= data
as &[u8];
44 ty
::ValTree
::from_raw_bytes(tcx
, bytes
)
46 (ast
::LitKind
::Byte(n
), ty
::Uint(ty
::UintTy
::U8
)) => {
47 ty
::ValTree
::from_scalar_int((*n
).into())
49 (ast
::LitKind
::Int(n
, _
), ty
::Uint(_
)) | (ast
::LitKind
::Int(n
, _
), ty
::Int(_
)) => {
51 trunc(if neg { (*n as i128).overflowing_neg().0 as u128 }
else { *n }
)?
;
52 ty
::ValTree
::from_scalar_int(scalar_int
)
54 (ast
::LitKind
::Bool(b
), ty
::Bool
) => ty
::ValTree
::from_scalar_int((*b
).into()),
55 (ast
::LitKind
::Char(c
), ty
::Char
) => ty
::ValTree
::from_scalar_int((*c
).into()),
56 (ast
::LitKind
::Err
, _
) => {
57 return Err(LitToConstError
::Reported(
58 tcx
.sess
.delay_span_bug(DUMMY_SP
, "encountered LitKind::Err during mir build"),
61 _
=> return Err(LitToConstError
::TypeError
),
64 Ok(tcx
.mk_const(valtree
, ty
))