@@ -7,7 +7,6 @@ use rustc_data_structures::sync::Lrc;
77use rustc_hir:: def:: { DefKind , Res } ;
88use rustc_hir:: { BinOp , BinOpKind , Block , Expr , ExprKind , HirId , Item , ItemKind , Node , QPath , UnOp } ;
99use rustc_lint:: LateContext ;
10- use rustc_middle:: mir:: interpret:: Scalar ;
1110use rustc_middle:: ty:: subst:: { Subst , SubstsRef } ;
1211use rustc_middle:: ty:: { self , EarlyBinder , FloatTy , ScalarInt , Ty , TyCtxt } ;
1312use rustc_middle:: { bug, span_bug} ;
@@ -423,14 +422,14 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> {
423422 let result = self
424423 . lcx
425424 . tcx
426- . const_eval_resolve (
425+ . const_eval_resolve_for_typeck (
427426 self . param_env ,
428427 ty:: Unevaluated :: new ( ty:: WithOptConstParam :: unknown ( def_id) , substs) ,
429428 None ,
430429 )
431430 . ok ( )
432- . map ( |val| rustc_middle:: ty:: Const :: from_value ( self . lcx . tcx , val, ty) ) ?;
433- let result = miri_to_const ( result) ;
431+ . and_then ( |val| val . map ( |val| rustc_middle:: ty:: Const :: from_value ( self . lcx . tcx , val, ty) ) ) ?;
432+ let result = miri_to_const ( self . lcx . tcx , result) ;
434433 if result. is_some ( ) {
435434 self . needed_resolution = true ;
436435 }
@@ -580,80 +579,69 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> {
580579 }
581580}
582581
583- pub fn miri_to_const ( result : ty:: Const < ' _ > ) -> Option < Constant > {
584- use rustc_middle:: mir:: interpret:: ConstValue ;
582+ pub fn miri_to_const < ' tcx > ( tcx : TyCtxt < ' tcx > , result : ty:: Const < ' tcx > ) -> Option < Constant > {
585583 match result. kind ( ) {
586- ty:: ConstKind :: Value ( ConstValue :: Scalar ( Scalar :: Int ( int ) ) ) => {
587- match result. ty ( ) . kind ( ) {
588- ty:: Bool => Some ( Constant :: Bool ( int == ScalarInt :: TRUE ) ) ,
589- ty:: Uint ( _) | ty:: Int ( _) => Some ( Constant :: Int ( int. assert_bits ( int. size ( ) ) ) ) ,
590- ty:: Float ( FloatTy :: F32 ) => Some ( Constant :: F32 ( f32:: from_bits (
584+ ty:: ConstKind :: Value ( valtree ) => {
585+ match ( valtree , result. ty ( ) . kind ( ) ) {
586+ ( ty:: ValTree :: Leaf ( int ) , ty :: Bool ) => Some ( Constant :: Bool ( int == ScalarInt :: TRUE ) ) ,
587+ ( ty:: ValTree :: Leaf ( int ) , ty :: Uint ( _) | ty:: Int ( _) ) => Some ( Constant :: Int ( int. assert_bits ( int. size ( ) ) ) ) ,
588+ ( ty:: ValTree :: Leaf ( int ) , ty :: Float ( FloatTy :: F32 ) ) => Some ( Constant :: F32 ( f32:: from_bits (
591589 int. try_into ( ) . expect ( "invalid f32 bit representation" ) ,
592590 ) ) ) ,
593- ty:: Float ( FloatTy :: F64 ) => Some ( Constant :: F64 ( f64:: from_bits (
591+ ( ty:: ValTree :: Leaf ( int ) , ty :: Float ( FloatTy :: F64 ) ) => Some ( Constant :: F64 ( f64:: from_bits (
594592 int. try_into ( ) . expect ( "invalid f64 bit representation" ) ,
595593 ) ) ) ,
596- ty:: RawPtr ( type_and_mut) => {
594+ ( ty:: ValTree :: Leaf ( int ) , ty :: RawPtr ( type_and_mut) ) => {
597595 if let ty:: Uint ( _) = type_and_mut. ty . kind ( ) {
598596 return Some ( Constant :: RawPtr ( int. assert_bits ( int. size ( ) ) ) ) ;
599597 }
600598 None
601599 } ,
602- // FIXME: implement other conversions.
603- _ => None ,
604- }
605- } ,
606- ty:: ConstKind :: Value ( ConstValue :: Slice { data, start, end } ) => match result. ty ( ) . kind ( ) {
607- ty:: Ref ( _, tam, _) => match tam. kind ( ) {
608- ty:: Str => String :: from_utf8 (
609- data. inner ( )
610- . inspect_with_uninit_and_ptr_outside_interpreter ( start..end)
611- . to_owned ( ) ,
612- )
613- . ok ( )
614- . map ( Constant :: Str ) ,
615- _ => None ,
616- } ,
617- _ => None ,
618- } ,
619- ty:: ConstKind :: Value ( ConstValue :: ByRef { alloc, offset : _ } ) => match result. ty ( ) . kind ( ) {
620- ty:: Array ( sub_type, len) => match sub_type. kind ( ) {
621- ty:: Float ( FloatTy :: F32 ) => match miri_to_const ( * len) {
622- Some ( Constant :: Int ( len) ) => alloc
623- . inner ( )
624- . inspect_with_uninit_and_ptr_outside_interpreter ( 0 ..( 4 * len as usize ) )
625- . to_owned ( )
626- . chunks ( 4 )
627- . map ( |chunk| {
628- Some ( Constant :: F32 ( f32:: from_le_bytes (
629- chunk. try_into ( ) . expect ( "this shouldn't happen" ) ,
630- ) ) )
631- } )
632- . collect :: < Option < Vec < Constant > > > ( )
633- . map ( Constant :: Vec ) ,
634- _ => None ,
635- } ,
636- ty:: Float ( FloatTy :: F64 ) => match miri_to_const ( * len) {
637- Some ( Constant :: Int ( len) ) => alloc
638- . inner ( )
639- . inspect_with_uninit_and_ptr_outside_interpreter ( 0 ..( 8 * len as usize ) )
640- . to_owned ( )
641- . chunks ( 8 )
642- . map ( |chunk| {
643- Some ( Constant :: F64 ( f64:: from_le_bytes (
644- chunk. try_into ( ) . expect ( "this shouldn't happen" ) ,
645- ) ) )
646- } )
647- . collect :: < Option < Vec < Constant > > > ( )
648- . map ( Constant :: Vec ) ,
600+ ( ty:: ValTree :: Branch ( _) , ty:: Ref ( _, inner_ty, _) ) if * inner_ty == tcx. types . str_ => valtree
601+ . try_to_raw_bytes ( tcx, result. ty ( ) )
602+ . and_then ( |bytes| String :: from_utf8 ( bytes. to_owned ( ) ) . ok ( ) . map ( Constant :: Str ) ) ,
603+ ( ty:: ValTree :: Branch ( _) , ty:: Array ( arr_ty, len) ) => match arr_ty. kind ( ) {
604+ ty:: Float ( float_ty) => {
605+ let chunk_size = match float_ty {
606+ FloatTy :: F32 => 4 ,
607+ FloatTy :: F64 => 8 ,
608+ } ;
609+
610+ match miri_to_const ( tcx, * len) {
611+ Some ( Constant :: Int ( _) ) => valtree. try_to_raw_bytes ( tcx, result. ty ( ) ) . and_then ( |bytes| {
612+ bytes
613+ . to_owned ( )
614+ . chunks ( chunk_size)
615+ . map ( |chunk| match float_ty {
616+ FloatTy :: F32 => {
617+ let float = f32:: from_le_bytes (
618+ chunk
619+ . try_into ( )
620+ . expect ( & format ! ( "expected to construct f32 from {:?}" , chunk) ) ,
621+ ) ;
622+ Some ( Constant :: F32 ( float) )
623+ } ,
624+ FloatTy :: F64 => {
625+ let float = f64:: from_le_bytes (
626+ chunk
627+ . try_into ( )
628+ . expect ( & format ! ( "expected to construct f64 from {:?}" , chunk) ) ,
629+ ) ;
630+ Some ( Constant :: F64 ( float) )
631+ } ,
632+ } )
633+ . collect :: < Option < Vec < Constant > > > ( )
634+ . map ( Constant :: Vec )
635+ } ) ,
636+ _ => None ,
637+ }
638+ } ,
649639 _ => None ,
650640 } ,
651- // FIXME: implement other array type conversions.
641+ // FIXME: implement other conversions.
652642 _ => None ,
653- } ,
654- _ => None ,
643+ }
655644 } ,
656- // FIXME: implement other conversions.
657645 _ => None ,
658646 }
659647}
0 commit comments