1
- use rustc:: mir:: interpret:: { ConstValue , Scalar } ;
2
- use rustc:: ty:: { self , layout:: Size , ParamEnv , Ty , TyCtxt } ;
1
+ use rustc:: mir:: interpret:: {
2
+ truncate, Allocation , ConstValue , LitToConstError , LitToConstInput , Scalar ,
3
+ } ;
4
+ use rustc:: ty:: { self , layout:: Size , ParamEnv , TyCtxt } ;
3
5
use rustc_span:: symbol:: Symbol ;
4
6
use syntax:: ast;
5
7
6
- #[ derive( PartialEq ) ]
7
- crate enum LitToConstError {
8
- UnparseableFloat ,
9
- Reported ,
10
- }
11
-
12
8
crate fn lit_to_const < ' tcx > (
13
- lit : & ' tcx ast:: LitKind ,
14
9
tcx : TyCtxt < ' tcx > ,
15
- ty : Ty < ' tcx > ,
16
- neg : bool ,
10
+ lit_input : LitToConstInput < ' tcx > ,
17
11
) -> Result < & ' tcx ty:: Const < ' tcx > , LitToConstError > {
18
- use syntax :: ast :: * ;
12
+ let LitToConstInput { lit , ty , neg } = lit_input ;
19
13
20
14
let trunc = |n| {
21
15
let param_ty = ParamEnv :: reveal_all ( ) . and ( ty) ;
@@ -26,35 +20,50 @@ crate fn lit_to_const<'tcx>(
26
20
Ok ( ConstValue :: Scalar ( Scalar :: from_uint ( result, width) ) )
27
21
} ;
28
22
29
- use rustc:: mir:: interpret:: * ;
30
23
let lit = match * lit {
31
- LitKind :: Str ( ref s, _) => {
24
+ ast :: LitKind :: Str ( ref s, _) => {
32
25
let s = s. as_str ( ) ;
33
26
let allocation = Allocation :: from_byte_aligned_bytes ( s. as_bytes ( ) ) ;
34
27
let allocation = tcx. intern_const_alloc ( allocation) ;
35
28
ConstValue :: Slice { data : allocation, start : 0 , end : s. len ( ) }
36
29
}
37
- LitKind :: ByteStr ( ref data) => {
38
- let id = tcx. allocate_bytes ( data) ;
39
- ConstValue :: Scalar ( Scalar :: Ptr ( id. into ( ) ) )
30
+ ast:: LitKind :: ByteStr ( ref data) => {
31
+ if let ty:: Ref ( _, ref_ty, _) = ty. kind {
32
+ match ref_ty. kind {
33
+ ty:: Slice ( _) => {
34
+ let allocation = Allocation :: from_byte_aligned_bytes ( data as & Vec < u8 > ) ;
35
+ let allocation = tcx. intern_const_alloc ( allocation) ;
36
+ ConstValue :: Slice { data : allocation, start : 0 , end : data. len ( ) }
37
+ }
38
+ ty:: Array ( _, _) => {
39
+ let id = tcx. allocate_bytes ( data) ;
40
+ ConstValue :: Scalar ( Scalar :: Ptr ( id. into ( ) ) )
41
+ }
42
+ _ => {
43
+ bug ! ( "bytestring should have type of either &[u8] or &[u8; _], not {}" , ty)
44
+ }
45
+ }
46
+ } else {
47
+ bug ! ( "bytestring should have type of either &[u8] or &[u8; _], not {}" , ty)
48
+ }
40
49
}
41
- LitKind :: Byte ( n) => ConstValue :: Scalar ( Scalar :: from_uint ( n, Size :: from_bytes ( 1 ) ) ) ,
42
- LitKind :: Int ( n, _) if neg => {
50
+ ast :: LitKind :: Byte ( n) => ConstValue :: Scalar ( Scalar :: from_uint ( n, Size :: from_bytes ( 1 ) ) ) ,
51
+ ast :: LitKind :: Int ( n, _) if neg => {
43
52
let n = n as i128 ;
44
53
let n = n. overflowing_neg ( ) . 0 ;
45
54
trunc ( n as u128 ) ?
46
55
}
47
- LitKind :: Int ( n, _) => trunc ( n) ?,
48
- LitKind :: Float ( n, _) => {
56
+ ast :: LitKind :: Int ( n, _) => trunc ( n) ?,
57
+ ast :: LitKind :: Float ( n, _) => {
49
58
let fty = match ty. kind {
50
59
ty:: Float ( fty) => fty,
51
60
_ => bug ! ( ) ,
52
61
} ;
53
62
parse_float ( n, fty, neg) . map_err ( |_| LitToConstError :: UnparseableFloat ) ?
54
63
}
55
- LitKind :: Bool ( b) => ConstValue :: Scalar ( Scalar :: from_bool ( b) ) ,
56
- LitKind :: Char ( c) => ConstValue :: Scalar ( Scalar :: from_char ( c) ) ,
57
- LitKind :: Err ( _) => unreachable ! ( ) ,
64
+ ast :: LitKind :: Bool ( b) => ConstValue :: Scalar ( Scalar :: from_bool ( b) ) ,
65
+ ast :: LitKind :: Char ( c) => ConstValue :: Scalar ( Scalar :: from_char ( c) ) ,
66
+ ast :: LitKind :: Err ( _) => return Err ( LitToConstError :: Reported ) ,
58
67
} ;
59
68
Ok ( tcx. mk_const ( ty:: Const { val : ty:: ConstKind :: Value ( lit) , ty } ) )
60
69
}
0 commit comments