@@ -3,19 +3,19 @@ use rustc_ast::{self as ast, UintTy};
33use rustc_hir:: LangItem ;
44use rustc_middle:: bug;
55use rustc_middle:: mir:: interpret:: LitToConstInput ;
6- use rustc_middle:: ty:: { self , ScalarInt , TyCtxt , TypeVisitableExt as _} ;
6+ use rustc_middle:: ty:: { self , ScalarInt , Ty , TyCtxt , TypeVisitableExt as _} ;
77use tracing:: trace;
88
99use crate :: builder:: parse_float_into_scalar;
1010
1111pub ( crate ) fn lit_to_const < ' tcx > (
1212 tcx : TyCtxt < ' tcx > ,
1313 lit_input : LitToConstInput < ' tcx > ,
14- ) -> ty:: Const < ' tcx > {
15- let LitToConstInput { lit, ty, neg } = lit_input;
14+ ) -> Option < ty:: Value < ' tcx > > {
15+ let LitToConstInput { lit, ty : expected_ty , neg } = lit_input;
1616
17- if let Err ( guar ) = ty . error_reported ( ) {
18- return ty :: Const :: new_error ( tcx , guar ) ;
17+ if expected_ty . error_reported ( ) . is_err ( ) {
18+ return None ;
1919 }
2020
2121 let trunc = |n, width : ty:: UintTy | {
@@ -32,63 +32,84 @@ pub(crate) fn lit_to_const<'tcx>(
3232 . unwrap_or_else ( || bug ! ( "expected to create ScalarInt from uint {:?}" , result) )
3333 } ;
3434
35- let valtree = match ( lit, ty . kind ( ) ) {
36- ( ast:: LitKind :: Str ( s, _) , ty :: Ref ( _ , inner_ty , _ ) ) if inner_ty . is_str ( ) => {
35+ let ( valtree, valtree_ty ) = match ( lit, expected_ty . kind ( ) ) {
36+ ( ast:: LitKind :: Str ( s, _) , _ ) => {
3737 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)
38+ let valtree_ty = Ty :: new_imm_ref ( tcx, tcx. lifetimes . re_static , tcx. types . str_ ) ;
39+ ( ty:: ValTree :: from_raw_bytes ( tcx, str_bytes) , valtree_ty)
4540 }
4641 ( ast:: LitKind :: ByteStr ( byte_sym, _) , ty:: Ref ( _, inner_ty, _) )
4742 if let ty:: Slice ( ty) | ty:: Array ( ty, _) = inner_ty. kind ( )
4843 && let ty:: Uint ( UintTy :: U8 ) = ty. kind ( ) =>
4944 {
50- ty:: ValTree :: from_raw_bytes ( tcx, byte_sym. as_byte_str ( ) )
45+ ( ty:: ValTree :: from_raw_bytes ( tcx, byte_sym. as_byte_str ( ) ) , expected_ty )
5146 }
5247 ( ast:: LitKind :: ByteStr ( byte_sym, _) , ty:: Slice ( inner_ty) | ty:: Array ( inner_ty, _) )
5348 if tcx. features ( ) . deref_patterns ( )
5449 && let ty:: Uint ( UintTy :: U8 ) = inner_ty. kind ( ) =>
5550 {
5651 // Byte string literal patterns may have type `[u8]` or `[u8; N]` if `deref_patterns` is
5752 // enabled, in order to allow, e.g., `deref!(b"..."): Vec<u8>`.
58- ty:: ValTree :: from_raw_bytes ( tcx, byte_sym. as_byte_str ( ) )
53+ ( ty:: ValTree :: from_raw_bytes ( tcx, byte_sym. as_byte_str ( ) ) , expected_ty )
5954 }
60- ( ast:: LitKind :: Byte ( n) , ty:: Uint ( ty:: UintTy :: U8 ) ) => {
61- ty:: ValTree :: from_scalar_int ( tcx, n. into ( ) )
55+ ( ast:: LitKind :: ByteStr ( byte_sym, _) , _) => {
56+ let valtree = ty:: ValTree :: from_raw_bytes ( tcx, byte_sym. as_byte_str ( ) ) ;
57+ let valtree_ty = Ty :: new_array ( tcx, tcx. types . u8 , byte_sym. as_byte_str ( ) . len ( ) as u64 ) ;
58+ ( valtree, valtree_ty)
6259 }
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 ) ) =>
60+ ( ast:: LitKind :: Byte ( n) , _) => ( ty:: ValTree :: from_scalar_int ( tcx, n. into ( ) ) , tcx. types . u8 ) ,
61+ ( ast:: LitKind :: CStr ( byte_sym, _) , _)
62+ if let Some ( cstr_def_id) = tcx. lang_items ( ) . get ( LangItem :: CStr ) =>
6463 {
6564 // A CStr is a newtype around a byte slice, so we create the inner slice here.
6665 // We need a branch for each "level" of the data structure.
66+ let cstr_ty = tcx. type_of ( cstr_def_id) . skip_binder ( ) ;
6767 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) ] )
68+ let valtree =
69+ ty:: ValTree :: from_branches ( tcx, [ ty:: Const :: new_value ( tcx, bytes, cstr_ty) ] ) ;
70+ let valtree_ty = Ty :: new_imm_ref ( tcx, tcx. lifetimes . re_static , cstr_ty) ;
71+ ( valtree, valtree_ty)
6972 }
70- ( ast:: LitKind :: Int ( n, _) , ty:: Uint ( ui) ) if !neg => {
73+ ( ast:: LitKind :: Int ( n, ast:: LitIntType :: Unsigned ( ui) ) , _) if !neg => {
74+ let scalar_int = trunc ( n. get ( ) , ui) ;
75+ ( ty:: ValTree :: from_scalar_int ( tcx, scalar_int) , Ty :: new_uint ( tcx, ui) )
76+ }
77+ ( ast:: LitKind :: Int ( _, ast:: LitIntType :: Unsigned ( _) ) , _) if neg => return None ,
78+ ( ast:: LitKind :: Int ( n, ast:: LitIntType :: Signed ( i) ) , _) => {
79+ let scalar_int =
80+ trunc ( if neg { u128:: wrapping_neg ( n. get ( ) ) } else { n. get ( ) } , i. to_unsigned ( ) ) ;
81+ ( ty:: ValTree :: from_scalar_int ( tcx, scalar_int) , Ty :: new_int ( tcx, i) )
82+ }
83+ ( ast:: LitKind :: Int ( n, ast:: LitIntType :: Unsuffixed ) , ty:: Uint ( ui) ) if !neg => {
7184 let scalar_int = trunc ( n. get ( ) , * ui) ;
72- ty:: ValTree :: from_scalar_int ( tcx, scalar_int)
85+ ( ty:: ValTree :: from_scalar_int ( tcx, scalar_int) , Ty :: new_uint ( tcx , * ui ) )
7386 }
74- ( ast:: LitKind :: Int ( n, _ ) , ty:: Int ( i) ) => {
87+ ( ast:: LitKind :: Int ( n, ast :: LitIntType :: Unsuffixed ) , ty:: Int ( i) ) => {
7588 // Unsigned "negation" has the same bitwise effect as signed negation,
7689 // which gets the result we want without additional casts.
7790 let scalar_int =
7891 trunc ( if neg { u128:: wrapping_neg ( n. get ( ) ) } else { n. get ( ) } , i. to_unsigned ( ) ) ;
79- ty:: ValTree :: from_scalar_int ( tcx, scalar_int)
92+ ( ty:: ValTree :: from_scalar_int ( tcx, scalar_int) , Ty :: new_int ( tcx, * i) )
93+ }
94+ ( ast:: LitKind :: Bool ( b) , _) => ( ty:: ValTree :: from_scalar_int ( tcx, b. into ( ) ) , tcx. types . bool ) ,
95+ ( ast:: LitKind :: Float ( n, ast:: LitFloatType :: Suffixed ( fty) ) , _) => {
96+ let fty = match fty {
97+ ast:: FloatTy :: F16 => ty:: FloatTy :: F16 ,
98+ ast:: FloatTy :: F32 => ty:: FloatTy :: F32 ,
99+ ast:: FloatTy :: F64 => ty:: FloatTy :: F64 ,
100+ ast:: FloatTy :: F128 => ty:: FloatTy :: F128 ,
101+ } ;
102+ let bits = parse_float_into_scalar ( n, fty, neg) ?;
103+ ( ty:: ValTree :: from_scalar_int ( tcx, bits) , Ty :: new_float ( tcx, fty) )
80104 }
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)
105+ ( ast:: LitKind :: Float ( n, ast:: LitFloatType :: Unsuffixed ) , ty:: Float ( fty) ) => {
106+ let bits = parse_float_into_scalar ( n, * fty, neg) ?;
107+ ( ty:: ValTree :: from_scalar_int ( tcx, bits) , Ty :: new_float ( tcx, * fty) )
87108 }
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 ) ,
109+ ( ast:: LitKind :: Char ( c) , _ ) => ( ty:: ValTree :: from_scalar_int ( tcx, c. into ( ) ) , tcx . types . char ) ,
110+ ( ast:: LitKind :: Err ( _ ) , _) => return None ,
111+ _ => return None ,
91112 } ;
92113
93- ty:: Const :: new_value ( tcx , valtree, ty )
114+ Some ( ty:: Value { ty : valtree_ty , valtree } )
94115}
0 commit comments