4
4
use std:: cmp;
5
5
6
6
use chalk_ir:: TyKind ;
7
- use hir_def:: resolver:: HasResolver ;
7
+ use hir_def:: {
8
+ builtin_type:: { BuiltinInt , BuiltinUint } ,
9
+ resolver:: HasResolver ,
10
+ } ;
8
11
use hir_expand:: mod_path:: ModPath ;
9
12
10
13
use super :: * ;
@@ -300,21 +303,36 @@ impl Evaluator<'_> {
300
303
BeginPanic => Err ( MirEvalError :: Panic ( "<unknown-panic-payload>" . to_string ( ) ) ) ,
301
304
PanicFmt => {
302
305
let message = ( || {
303
- let resolver = self . db . crate_def_map ( self . crate_id ) . crate_root ( ) . resolver ( self . db . upcast ( ) ) ;
306
+ let resolver = self
307
+ . db
308
+ . crate_def_map ( self . crate_id )
309
+ . crate_root ( )
310
+ . resolver ( self . db . upcast ( ) ) ;
304
311
let Some ( format_fn) = resolver. resolve_path_in_value_ns_fully (
305
312
self . db . upcast ( ) ,
306
- & hir_def:: path:: Path :: from_known_path_with_no_generic ( ModPath :: from_segments (
307
- hir_expand:: mod_path:: PathKind :: Abs ,
308
- [ name ! [ std] , name ! [ fmt] , name ! [ format] ] . into_iter ( ) ,
309
- ) ) ,
313
+ & hir_def:: path:: Path :: from_known_path_with_no_generic (
314
+ ModPath :: from_segments (
315
+ hir_expand:: mod_path:: PathKind :: Abs ,
316
+ [ name ! [ std] , name ! [ fmt] , name ! [ format] ] . into_iter ( ) ,
317
+ ) ,
318
+ ) ,
310
319
) else {
311
320
not_supported ! ( "std::fmt::format not found" ) ;
312
321
} ;
313
- let hir_def:: resolver:: ValueNs :: FunctionId ( format_fn) = format_fn else { not_supported ! ( "std::fmt::format is not a function" ) } ;
314
- let message_string = self . interpret_mir ( self . db . mir_body ( format_fn. into ( ) ) . map_err ( |e| MirEvalError :: MirLowerError ( format_fn, e) ) ?, args. map ( |x| IntervalOrOwned :: Owned ( x. clone ( ) ) ) ) ?;
315
- let addr = Address :: from_bytes ( & message_string[ self . ptr_size ( ) ..2 * self . ptr_size ( ) ] ) ?;
322
+ let hir_def:: resolver:: ValueNs :: FunctionId ( format_fn) = format_fn else {
323
+ not_supported ! ( "std::fmt::format is not a function" )
324
+ } ;
325
+ let message_string = self . interpret_mir (
326
+ self . db
327
+ . mir_body ( format_fn. into ( ) )
328
+ . map_err ( |e| MirEvalError :: MirLowerError ( format_fn, e) ) ?,
329
+ args. map ( |x| IntervalOrOwned :: Owned ( x. clone ( ) ) ) ,
330
+ ) ?;
331
+ let addr =
332
+ Address :: from_bytes ( & message_string[ self . ptr_size ( ) ..2 * self . ptr_size ( ) ] ) ?;
316
333
let size = from_bytes ! ( usize , message_string[ 2 * self . ptr_size( ) ..] ) ;
317
- Ok ( std:: string:: String :: from_utf8_lossy ( self . read_memory ( addr, size) ?) . into_owned ( ) )
334
+ Ok ( std:: string:: String :: from_utf8_lossy ( self . read_memory ( addr, size) ?)
335
+ . into_owned ( ) )
318
336
} ) ( )
319
337
. unwrap_or_else ( |e| format ! ( "Failed to render panic format args: {e:?}" ) ) ;
320
338
Err ( MirEvalError :: Panic ( message) )
@@ -483,9 +501,7 @@ impl Evaluator<'_> {
483
501
}
484
502
"syscall" => {
485
503
let Some ( ( id, rest) ) = args. split_first ( ) else {
486
- return Err ( MirEvalError :: TypeError (
487
- "syscall arg1 is not provided" ,
488
- ) ) ;
504
+ return Err ( MirEvalError :: TypeError ( "syscall arg1 is not provided" ) ) ;
489
505
} ;
490
506
let id = from_bytes ! ( i64 , id. get( self ) ?) ;
491
507
self . exec_syscall ( id, rest, destination, locals, span)
@@ -710,22 +726,26 @@ impl Evaluator<'_> {
710
726
}
711
727
match name {
712
728
"size_of" => {
713
- let Some ( ty) = generic_args. as_slice ( Interner ) . get ( 0 ) . and_then ( |it| it. ty ( Interner ) )
729
+ let Some ( ty) =
730
+ generic_args. as_slice ( Interner ) . get ( 0 ) . and_then ( |it| it. ty ( Interner ) )
714
731
else {
715
732
return Err ( MirEvalError :: TypeError ( "size_of generic arg is not provided" ) ) ;
716
733
} ;
717
734
let size = self . size_of_sized ( ty, locals, "size_of arg" ) ?;
718
735
destination. write_from_bytes ( self , & size. to_le_bytes ( ) [ 0 ..destination. size ] )
719
736
}
720
737
"min_align_of" | "pref_align_of" => {
721
- let Some ( ty) = generic_args. as_slice ( Interner ) . get ( 0 ) . and_then ( |it| it. ty ( Interner ) ) else {
738
+ let Some ( ty) =
739
+ generic_args. as_slice ( Interner ) . get ( 0 ) . and_then ( |it| it. ty ( Interner ) )
740
+ else {
722
741
return Err ( MirEvalError :: TypeError ( "align_of generic arg is not provided" ) ) ;
723
742
} ;
724
743
let align = self . layout ( ty) ?. align . abi . bytes ( ) ;
725
744
destination. write_from_bytes ( self , & align. to_le_bytes ( ) [ 0 ..destination. size ] )
726
745
}
727
746
"size_of_val" => {
728
- let Some ( ty) = generic_args. as_slice ( Interner ) . get ( 0 ) . and_then ( |it| it. ty ( Interner ) )
747
+ let Some ( ty) =
748
+ generic_args. as_slice ( Interner ) . get ( 0 ) . and_then ( |it| it. ty ( Interner ) )
729
749
else {
730
750
return Err ( MirEvalError :: TypeError ( "size_of_val generic arg is not provided" ) ) ;
731
751
} ;
@@ -741,8 +761,12 @@ impl Evaluator<'_> {
741
761
}
742
762
}
743
763
"min_align_of_val" => {
744
- let Some ( ty) = generic_args. as_slice ( Interner ) . get ( 0 ) . and_then ( |it| it. ty ( Interner ) ) else {
745
- return Err ( MirEvalError :: TypeError ( "min_align_of_val generic arg is not provided" ) ) ;
764
+ let Some ( ty) =
765
+ generic_args. as_slice ( Interner ) . get ( 0 ) . and_then ( |it| it. ty ( Interner ) )
766
+ else {
767
+ return Err ( MirEvalError :: TypeError (
768
+ "min_align_of_val generic arg is not provided" ,
769
+ ) ) ;
746
770
} ;
747
771
let [ arg] = args else {
748
772
return Err ( MirEvalError :: TypeError ( "min_align_of_val args are not provided" ) ) ;
@@ -756,7 +780,8 @@ impl Evaluator<'_> {
756
780
}
757
781
}
758
782
"type_name" => {
759
- let Some ( ty) = generic_args. as_slice ( Interner ) . get ( 0 ) . and_then ( |it| it. ty ( Interner ) )
783
+ let Some ( ty) =
784
+ generic_args. as_slice ( Interner ) . get ( 0 ) . and_then ( |it| it. ty ( Interner ) )
760
785
else {
761
786
return Err ( MirEvalError :: TypeError ( "type_name generic arg is not provided" ) ) ;
762
787
} ;
@@ -779,7 +804,8 @@ impl Evaluator<'_> {
779
804
. write_from_bytes ( self , & len. to_le_bytes ( ) )
780
805
}
781
806
"needs_drop" => {
782
- let Some ( ty) = generic_args. as_slice ( Interner ) . get ( 0 ) . and_then ( |it| it. ty ( Interner ) )
807
+ let Some ( ty) =
808
+ generic_args. as_slice ( Interner ) . get ( 0 ) . and_then ( |it| it. ty ( Interner ) )
783
809
else {
784
810
return Err ( MirEvalError :: TypeError ( "size_of generic arg is not provided" ) ) ;
785
811
} ;
@@ -831,9 +857,12 @@ impl Evaluator<'_> {
831
857
let lhs = i128:: from_le_bytes ( pad16 ( lhs. get ( self ) ?, false ) ) ;
832
858
let rhs = i128:: from_le_bytes ( pad16 ( rhs. get ( self ) ?, false ) ) ;
833
859
let ans = lhs. wrapping_sub ( rhs) ;
834
- let Some ( ty) = generic_args. as_slice ( Interner ) . get ( 0 ) . and_then ( |it| it. ty ( Interner ) )
860
+ let Some ( ty) =
861
+ generic_args. as_slice ( Interner ) . get ( 0 ) . and_then ( |it| it. ty ( Interner ) )
835
862
else {
836
- return Err ( MirEvalError :: TypeError ( "ptr_offset_from generic arg is not provided" ) ) ;
863
+ return Err ( MirEvalError :: TypeError (
864
+ "ptr_offset_from generic arg is not provided" ,
865
+ ) ) ;
837
866
} ;
838
867
let size = self . size_of_sized ( ty, locals, "ptr_offset_from arg" ) ? as i128 ;
839
868
let ans = ans / size;
@@ -940,7 +969,8 @@ impl Evaluator<'_> {
940
969
"copy_nonoverlapping args are not provided" ,
941
970
) ) ;
942
971
} ;
943
- let Some ( ty) = generic_args. as_slice ( Interner ) . get ( 0 ) . and_then ( |it| it. ty ( Interner ) )
972
+ let Some ( ty) =
973
+ generic_args. as_slice ( Interner ) . get ( 0 ) . and_then ( |it| it. ty ( Interner ) )
944
974
else {
945
975
return Err ( MirEvalError :: TypeError (
946
976
"copy_nonoverlapping generic arg is not provided" ,
@@ -959,9 +989,45 @@ impl Evaluator<'_> {
959
989
let [ ptr, offset] = args else {
960
990
return Err ( MirEvalError :: TypeError ( "offset args are not provided" ) ) ;
961
991
} ;
962
- let Some ( ty) = generic_args. as_slice ( Interner ) . get ( 0 ) . and_then ( |it| it. ty ( Interner ) )
963
- else {
964
- return Err ( MirEvalError :: TypeError ( "offset generic arg is not provided" ) ) ;
992
+ let ty = if name == "offset" {
993
+ let Some ( ty0) =
994
+ generic_args. as_slice ( Interner ) . get ( 0 ) . and_then ( |it| it. ty ( Interner ) )
995
+ else {
996
+ return Err ( MirEvalError :: TypeError ( "offset generic arg is not provided" ) ) ;
997
+ } ;
998
+ let Some ( ty1) =
999
+ generic_args. as_slice ( Interner ) . get ( 1 ) . and_then ( |it| it. ty ( Interner ) )
1000
+ else {
1001
+ return Err ( MirEvalError :: TypeError ( "offset generic arg is not provided" ) ) ;
1002
+ } ;
1003
+ if !matches ! (
1004
+ ty1. as_builtin( ) ,
1005
+ Some (
1006
+ BuiltinType :: Int ( BuiltinInt :: Isize )
1007
+ | BuiltinType :: Uint ( BuiltinUint :: Usize )
1008
+ )
1009
+ ) {
1010
+ return Err ( MirEvalError :: TypeError (
1011
+ "offset generic arg is not usize or isize" ,
1012
+ ) ) ;
1013
+ }
1014
+ match ty0. as_raw_ptr ( ) {
1015
+ Some ( ( ty, _) ) => ty,
1016
+ None => {
1017
+ return Err ( MirEvalError :: TypeError (
1018
+ "offset generic arg is not a raw pointer" ,
1019
+ ) ) ;
1020
+ }
1021
+ }
1022
+ } else {
1023
+ let Some ( ty) =
1024
+ generic_args. as_slice ( Interner ) . get ( 0 ) . and_then ( |it| it. ty ( Interner ) )
1025
+ else {
1026
+ return Err ( MirEvalError :: TypeError (
1027
+ "arith_offset generic arg is not provided" ,
1028
+ ) ) ;
1029
+ } ;
1030
+ ty
965
1031
} ;
966
1032
let ptr = u128:: from_le_bytes ( pad16 ( ptr. get ( self ) ?, false ) ) ;
967
1033
let offset = u128:: from_le_bytes ( pad16 ( offset. get ( self ) ?, false ) ) ;
@@ -1079,7 +1145,8 @@ impl Evaluator<'_> {
1079
1145
let [ arg] = args else {
1080
1146
return Err ( MirEvalError :: TypeError ( "discriminant_value arg is not provided" ) ) ;
1081
1147
} ;
1082
- let Some ( ty) = generic_args. as_slice ( Interner ) . get ( 0 ) . and_then ( |it| it. ty ( Interner ) )
1148
+ let Some ( ty) =
1149
+ generic_args. as_slice ( Interner ) . get ( 0 ) . and_then ( |it| it. ty ( Interner ) )
1083
1150
else {
1084
1151
return Err ( MirEvalError :: TypeError (
1085
1152
"discriminant_value generic arg is not provided" ,
@@ -1139,11 +1206,10 @@ impl Evaluator<'_> {
1139
1206
} ;
1140
1207
let count = from_bytes ! ( usize , count. get( self ) ?) ;
1141
1208
let val = from_bytes ! ( u8 , val. get( self ) ?) ;
1142
- let Some ( ty) = generic_args. as_slice ( Interner ) . get ( 0 ) . and_then ( |it| it. ty ( Interner ) )
1209
+ let Some ( ty) =
1210
+ generic_args. as_slice ( Interner ) . get ( 0 ) . and_then ( |it| it. ty ( Interner ) )
1143
1211
else {
1144
- return Err ( MirEvalError :: TypeError (
1145
- "write_bytes generic arg is not provided" ,
1146
- ) ) ;
1212
+ return Err ( MirEvalError :: TypeError ( "write_bytes generic arg is not provided" ) ) ;
1147
1213
} ;
1148
1214
let dst = Address :: from_bytes ( dst. get ( self ) ?) ?;
1149
1215
let size = self . size_of_sized ( ty, locals, "copy_nonoverlapping ptr type" ) ?;
0 commit comments