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 } ;
35use rustc_span:: symbol:: Symbol ;
46use syntax:: ast;
57
6- #[ derive( PartialEq ) ]
7- crate enum LitToConstError {
8- UnparseableFloat ,
9- Reported ,
10- }
11-
128crate fn lit_to_const < ' tcx > (
13- lit : & ' tcx ast:: LitKind ,
149 tcx : TyCtxt < ' tcx > ,
15- ty : Ty < ' tcx > ,
16- neg : bool ,
10+ lit_input : LitToConstInput < ' tcx > ,
1711) -> Result < & ' tcx ty:: Const < ' tcx > , LitToConstError > {
18- use syntax :: ast :: * ;
12+ let LitToConstInput { lit , ty , neg } = lit_input ;
1913
2014 let trunc = |n| {
2115 let param_ty = ParamEnv :: reveal_all ( ) . and ( ty) ;
@@ -26,35 +20,50 @@ crate fn lit_to_const<'tcx>(
2620 Ok ( ConstValue :: Scalar ( Scalar :: from_uint ( result, width) ) )
2721 } ;
2822
29- use rustc:: mir:: interpret:: * ;
3023 let lit = match * lit {
31- LitKind :: Str ( ref s, _) => {
24+ ast :: LitKind :: Str ( ref s, _) => {
3225 let s = s. as_str ( ) ;
3326 let allocation = Allocation :: from_byte_aligned_bytes ( s. as_bytes ( ) ) ;
3427 let allocation = tcx. intern_const_alloc ( allocation) ;
3528 ConstValue :: Slice { data : allocation, start : 0 , end : s. len ( ) }
3629 }
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+ }
4049 }
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 => {
4352 let n = n as i128 ;
4453 let n = n. overflowing_neg ( ) . 0 ;
4554 trunc ( n as u128 ) ?
4655 }
47- LitKind :: Int ( n, _) => trunc ( n) ?,
48- LitKind :: Float ( n, _) => {
56+ ast :: LitKind :: Int ( n, _) => trunc ( n) ?,
57+ ast :: LitKind :: Float ( n, _) => {
4958 let fty = match ty. kind {
5059 ty:: Float ( fty) => fty,
5160 _ => bug ! ( ) ,
5261 } ;
5362 parse_float ( n, fty, neg) . map_err ( |_| LitToConstError :: UnparseableFloat ) ?
5463 }
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 ) ,
5867 } ;
5968 Ok ( tcx. mk_const ( ty:: Const { val : ty:: ConstKind :: Value ( lit) , ty } ) )
6069}
0 commit comments