@@ -2,20 +2,19 @@ use rustc_abi::Size;
22use rustc_ast:: { self as ast, UintTy } ;
33use rustc_hir:: LangItem ;
44use rustc_middle:: bug;
5- use rustc_middle:: mir:: interpret:: LitToConstInput ;
6- use rustc_middle:: ty:: { self , ScalarInt , TyCtxt , TypeVisitableExt as _} ;
5+ use rustc_middle:: ty:: { self , LitToConstInput , ScalarInt , Ty , TyCtxt , TypeVisitableExt as _} ;
76use tracing:: trace;
87
98use crate :: builder:: parse_float_into_scalar;
109
1110pub ( crate ) fn lit_to_const < ' tcx > (
1211 tcx : TyCtxt < ' tcx > ,
1312 lit_input : LitToConstInput < ' tcx > ,
14- ) -> ty:: Const < ' tcx > {
15- let LitToConstInput { lit, ty, neg } = lit_input;
13+ ) -> Option < ty:: Value < ' tcx > > {
14+ let LitToConstInput { lit, ty : expected_ty , neg } = lit_input;
1615
17- if let Err ( guar ) = ty . error_reported ( ) {
18- return ty :: Const :: new_error ( tcx , guar ) ;
16+ if expected_ty . error_reported ( ) . is_err ( ) {
17+ return None ;
1918 }
2019
2120 let trunc = |n, width : ty:: UintTy | {
@@ -32,63 +31,84 @@ pub(crate) fn lit_to_const<'tcx>(
3231 . unwrap_or_else ( || bug ! ( "expected to create ScalarInt from uint {:?}" , result) )
3332 } ;
3433
35- let valtree = match ( lit, ty . kind ( ) ) {
36- ( ast:: LitKind :: Str ( s, _) , ty :: Ref ( _ , inner_ty , _ ) ) if inner_ty . is_str ( ) => {
34+ let ( valtree, valtree_ty ) = match ( lit, expected_ty . kind ( ) ) {
35+ ( ast:: LitKind :: Str ( s, _) , _ ) => {
3736 let str_bytes = s. as_str ( ) . as_bytes ( ) ;
38- ty:: ValTree :: from_raw_bytes ( tcx, str_bytes)
39- }
40- ( ast:: LitKind :: Str ( s, _) , ty:: Str ) if tcx. features ( ) . deref_patterns ( ) => {
41- // String literal patterns may have type `str` if `deref_patterns` is enabled, in order
42- // to allow `deref!("..."): String`.
43- let str_bytes = s. as_str ( ) . as_bytes ( ) ;
44- ty:: ValTree :: from_raw_bytes ( tcx, str_bytes)
37+ let valtree_ty = Ty :: new_imm_ref ( tcx, tcx. lifetimes . re_static , tcx. types . str_ ) ;
38+ ( ty:: ValTree :: from_raw_bytes ( tcx, str_bytes) , valtree_ty)
4539 }
4640 ( ast:: LitKind :: ByteStr ( byte_sym, _) , ty:: Ref ( _, inner_ty, _) )
4741 if let ty:: Slice ( ty) | ty:: Array ( ty, _) = inner_ty. kind ( )
4842 && let ty:: Uint ( UintTy :: U8 ) = ty. kind ( ) =>
4943 {
50- ty:: ValTree :: from_raw_bytes ( tcx, byte_sym. as_byte_str ( ) )
44+ ( ty:: ValTree :: from_raw_bytes ( tcx, byte_sym. as_byte_str ( ) ) , expected_ty )
5145 }
5246 ( ast:: LitKind :: ByteStr ( byte_sym, _) , ty:: Slice ( inner_ty) | ty:: Array ( inner_ty, _) )
5347 if tcx. features ( ) . deref_patterns ( )
5448 && let ty:: Uint ( UintTy :: U8 ) = inner_ty. kind ( ) =>
5549 {
5650 // Byte string literal patterns may have type `[u8]` or `[u8; N]` if `deref_patterns` is
5751 // enabled, in order to allow, e.g., `deref!(b"..."): Vec<u8>`.
58- ty:: ValTree :: from_raw_bytes ( tcx, byte_sym. as_byte_str ( ) )
52+ ( ty:: ValTree :: from_raw_bytes ( tcx, byte_sym. as_byte_str ( ) ) , expected_ty )
5953 }
60- ( ast:: LitKind :: Byte ( n) , ty:: Uint ( ty:: UintTy :: U8 ) ) => {
61- ty:: ValTree :: from_scalar_int ( tcx, n. into ( ) )
54+ ( ast:: LitKind :: ByteStr ( byte_sym, _) , _) => {
55+ let valtree = ty:: ValTree :: from_raw_bytes ( tcx, byte_sym. as_byte_str ( ) ) ;
56+ let valtree_ty = Ty :: new_array ( tcx, tcx. types . u8 , byte_sym. as_byte_str ( ) . len ( ) as u64 ) ;
57+ ( valtree, valtree_ty)
6258 }
63- ( ast:: LitKind :: CStr ( byte_sym, _) , ty:: Ref ( _, inner_ty, _) ) if matches ! ( inner_ty. kind( ) , ty:: Adt ( def, _) if tcx. is_lang_item( def. did( ) , LangItem :: CStr ) ) =>
59+ ( ast:: LitKind :: Byte ( n) , _) => ( ty:: ValTree :: from_scalar_int ( tcx, n. into ( ) ) , tcx. types . u8 ) ,
60+ ( ast:: LitKind :: CStr ( byte_sym, _) , _)
61+ if let Some ( cstr_def_id) = tcx. lang_items ( ) . get ( LangItem :: CStr ) =>
6462 {
6563 // A CStr is a newtype around a byte slice, so we create the inner slice here.
6664 // We need a branch for each "level" of the data structure.
65+ let cstr_ty = tcx. type_of ( cstr_def_id) . skip_binder ( ) ;
6766 let bytes = ty:: ValTree :: from_raw_bytes ( tcx, byte_sym. as_byte_str ( ) ) ;
68- ty:: ValTree :: from_branches ( tcx, [ ty:: Const :: new_value ( tcx, bytes, * inner_ty) ] )
67+ let valtree =
68+ ty:: ValTree :: from_branches ( tcx, [ ty:: Const :: new_value ( tcx, bytes, cstr_ty) ] ) ;
69+ let valtree_ty = Ty :: new_imm_ref ( tcx, tcx. lifetimes . re_static , cstr_ty) ;
70+ ( valtree, valtree_ty)
6971 }
70- ( ast:: LitKind :: Int ( n, _) , ty:: Uint ( ui) ) if !neg => {
72+ ( ast:: LitKind :: Int ( n, ast:: LitIntType :: Unsigned ( ui) ) , _) if !neg => {
73+ let scalar_int = trunc ( n. get ( ) , ui) ;
74+ ( ty:: ValTree :: from_scalar_int ( tcx, scalar_int) , Ty :: new_uint ( tcx, ui) )
75+ }
76+ ( ast:: LitKind :: Int ( _, ast:: LitIntType :: Unsigned ( _) ) , _) if neg => return None ,
77+ ( ast:: LitKind :: Int ( n, ast:: LitIntType :: Signed ( i) ) , _) => {
78+ let scalar_int =
79+ trunc ( if neg { u128:: wrapping_neg ( n. get ( ) ) } else { n. get ( ) } , i. to_unsigned ( ) ) ;
80+ ( ty:: ValTree :: from_scalar_int ( tcx, scalar_int) , Ty :: new_int ( tcx, i) )
81+ }
82+ ( ast:: LitKind :: Int ( n, ast:: LitIntType :: Unsuffixed ) , ty:: Uint ( ui) ) if !neg => {
7183 let scalar_int = trunc ( n. get ( ) , * ui) ;
72- ty:: ValTree :: from_scalar_int ( tcx, scalar_int)
84+ ( ty:: ValTree :: from_scalar_int ( tcx, scalar_int) , Ty :: new_uint ( tcx , * ui ) )
7385 }
74- ( ast:: LitKind :: Int ( n, _ ) , ty:: Int ( i) ) => {
86+ ( ast:: LitKind :: Int ( n, ast :: LitIntType :: Unsuffixed ) , ty:: Int ( i) ) => {
7587 // Unsigned "negation" has the same bitwise effect as signed negation,
7688 // which gets the result we want without additional casts.
7789 let scalar_int =
7890 trunc ( if neg { u128:: wrapping_neg ( n. get ( ) ) } else { n. get ( ) } , i. to_unsigned ( ) ) ;
79- ty:: ValTree :: from_scalar_int ( tcx, scalar_int)
91+ ( ty:: ValTree :: from_scalar_int ( tcx, scalar_int) , Ty :: new_int ( tcx, * i) )
92+ }
93+ ( ast:: LitKind :: Bool ( b) , _) => ( ty:: ValTree :: from_scalar_int ( tcx, b. into ( ) ) , tcx. types . bool ) ,
94+ ( ast:: LitKind :: Float ( n, ast:: LitFloatType :: Suffixed ( fty) ) , _) => {
95+ let fty = match fty {
96+ ast:: FloatTy :: F16 => ty:: FloatTy :: F16 ,
97+ ast:: FloatTy :: F32 => ty:: FloatTy :: F32 ,
98+ ast:: FloatTy :: F64 => ty:: FloatTy :: F64 ,
99+ ast:: FloatTy :: F128 => ty:: FloatTy :: F128 ,
100+ } ;
101+ let bits = parse_float_into_scalar ( n, fty, neg) ?;
102+ ( ty:: ValTree :: from_scalar_int ( tcx, bits) , Ty :: new_float ( tcx, fty) )
80103 }
81- ( ast:: LitKind :: Bool ( b) , ty:: Bool ) => ty:: ValTree :: from_scalar_int ( tcx, b. into ( ) ) ,
82- ( ast:: LitKind :: Float ( n, _) , ty:: Float ( fty) ) => {
83- let bits = parse_float_into_scalar ( n, * fty, neg) . unwrap_or_else ( || {
84- tcx. dcx ( ) . bug ( format ! ( "couldn't parse float literal: {:?}" , lit_input. lit) )
85- } ) ;
86- ty:: ValTree :: from_scalar_int ( tcx, bits)
104+ ( ast:: LitKind :: Float ( n, ast:: LitFloatType :: Unsuffixed ) , ty:: Float ( fty) ) => {
105+ let bits = parse_float_into_scalar ( n, * fty, neg) ?;
106+ ( ty:: ValTree :: from_scalar_int ( tcx, bits) , Ty :: new_float ( tcx, * fty) )
87107 }
88- ( ast:: LitKind :: Char ( c) , ty :: Char ) => ty:: ValTree :: from_scalar_int ( tcx, c. into ( ) ) ,
89- ( ast:: LitKind :: Err ( guar ) , _) => return ty :: Const :: new_error ( tcx , guar ) ,
90- _ => return ty :: Const :: new_misc_error ( tcx ) ,
108+ ( ast:: LitKind :: Char ( c) , _ ) => ( ty:: ValTree :: from_scalar_int ( tcx, c. into ( ) ) , tcx . types . char ) ,
109+ ( ast:: LitKind :: Err ( _ ) , _) => return None ,
110+ _ => return None ,
91111 } ;
92112
93- ty:: Const :: new_value ( tcx , valtree, ty )
113+ Some ( ty:: Value { ty : valtree_ty , valtree } )
94114}
0 commit comments