@@ -22,6 +22,11 @@ pub struct Body {
22
22
23
23
/// Debug information pertaining to user variables, including captures.
24
24
pub var_debug_info : Vec < VarDebugInfo > ,
25
+
26
+ /// Mark an argument (which must be a tuple) as getting passed as its individual components.
27
+ ///
28
+ /// This is used for the "rust-call" ABI such as closures.
29
+ pub ( super ) spread_arg : Option < Local > ,
25
30
}
26
31
27
32
pub type BasicBlockIdx = usize ;
@@ -36,14 +41,15 @@ impl Body {
36
41
locals : LocalDecls ,
37
42
arg_count : usize ,
38
43
var_debug_info : Vec < VarDebugInfo > ,
44
+ spread_arg : Option < Local > ,
39
45
) -> Self {
40
46
// If locals doesn't contain enough entries, it can lead to panics in
41
47
// `ret_local`, `arg_locals`, and `inner_locals`.
42
48
assert ! (
43
49
locals. len( ) > arg_count,
44
50
"A Body must contain at least a local for the return value and each of the function's arguments"
45
51
) ;
46
- Self { blocks, locals, arg_count, var_debug_info }
52
+ Self { blocks, locals, arg_count, var_debug_info, spread_arg }
47
53
}
48
54
49
55
/// Return local that holds this function's return value.
@@ -75,6 +81,11 @@ impl Body {
75
81
self . locals . get ( local)
76
82
}
77
83
84
+ /// Get an iterator for all local declarations.
85
+ pub fn local_decls ( & self ) -> impl Iterator < Item = ( Local , & LocalDecl ) > {
86
+ self . locals . iter ( ) . enumerate ( )
87
+ }
88
+
78
89
pub fn dump < W : io:: Write > ( & self , w : & mut W ) -> io:: Result < ( ) > {
79
90
writeln ! ( w, "{}" , function_body( self ) ) ?;
80
91
self . blocks
@@ -98,6 +109,10 @@ impl Body {
98
109
. collect :: < Result < Vec < _ > , _ > > ( ) ?;
99
110
Ok ( ( ) )
100
111
}
112
+
113
+ pub fn spread_arg ( & self ) -> Option < Local > {
114
+ self . spread_arg
115
+ }
101
116
}
102
117
103
118
type LocalDecls = Vec < LocalDecl > ;
@@ -248,6 +263,57 @@ pub enum AssertMessage {
248
263
MisalignedPointerDereference { required : Operand , found : Operand } ,
249
264
}
250
265
266
+ impl AssertMessage {
267
+ pub fn description ( & self ) -> Result < & ' static str , Error > {
268
+ match self {
269
+ AssertMessage :: Overflow ( BinOp :: Add , _, _) => Ok ( "attempt to add with overflow" ) ,
270
+ AssertMessage :: Overflow ( BinOp :: Sub , _, _) => Ok ( "attempt to subtract with overflow" ) ,
271
+ AssertMessage :: Overflow ( BinOp :: Mul , _, _) => Ok ( "attempt to multiply with overflow" ) ,
272
+ AssertMessage :: Overflow ( BinOp :: Div , _, _) => Ok ( "attempt to divide with overflow" ) ,
273
+ AssertMessage :: Overflow ( BinOp :: Rem , _, _) => {
274
+ Ok ( "attempt to calculate the remainder with overflow" )
275
+ }
276
+ AssertMessage :: OverflowNeg ( _) => Ok ( "attempt to negate with overflow" ) ,
277
+ AssertMessage :: Overflow ( BinOp :: Shr , _, _) => Ok ( "attempt to shift right with overflow" ) ,
278
+ AssertMessage :: Overflow ( BinOp :: Shl , _, _) => Ok ( "attempt to shift left with overflow" ) ,
279
+ AssertMessage :: Overflow ( op, _, _) => Err ( error ! ( "`{:?}` cannot overflow" , op) ) ,
280
+ AssertMessage :: DivisionByZero ( _) => Ok ( "attempt to divide by zero" ) ,
281
+ AssertMessage :: RemainderByZero ( _) => {
282
+ Ok ( "attempt to calculate the remainder with a divisor of zero" )
283
+ }
284
+ AssertMessage :: ResumedAfterReturn ( CoroutineKind :: Coroutine ) => {
285
+ Ok ( "coroutine resumed after completion" )
286
+ }
287
+ AssertMessage :: ResumedAfterReturn ( CoroutineKind :: Async ( _) ) => {
288
+ Ok ( "`async fn` resumed after completion" )
289
+ }
290
+ AssertMessage :: ResumedAfterReturn ( CoroutineKind :: Gen ( _) ) => {
291
+ Ok ( "`async gen fn` resumed after completion" )
292
+ }
293
+ AssertMessage :: ResumedAfterReturn ( CoroutineKind :: AsyncGen ( _) ) => {
294
+ Ok ( "`gen fn` should just keep returning `AssertMessage::None` after completion" )
295
+ }
296
+ AssertMessage :: ResumedAfterPanic ( CoroutineKind :: Coroutine ) => {
297
+ Ok ( "coroutine resumed after panicking" )
298
+ }
299
+ AssertMessage :: ResumedAfterPanic ( CoroutineKind :: Async ( _) ) => {
300
+ Ok ( "`async fn` resumed after panicking" )
301
+ }
302
+ AssertMessage :: ResumedAfterPanic ( CoroutineKind :: Gen ( _) ) => {
303
+ Ok ( "`async gen fn` resumed after panicking" )
304
+ }
305
+ AssertMessage :: ResumedAfterPanic ( CoroutineKind :: AsyncGen ( _) ) => {
306
+ Ok ( "`gen fn` should just keep returning `AssertMessage::None` after panicking" )
307
+ }
308
+
309
+ AssertMessage :: BoundsCheck { .. } => Ok ( "index out of bounds" ) ,
310
+ AssertMessage :: MisalignedPointerDereference { .. } => {
311
+ Ok ( "misaligned pointer dereference" )
312
+ }
313
+ }
314
+ }
315
+ }
316
+
251
317
#[ derive( Copy , Clone , Debug , Eq , PartialEq ) ]
252
318
pub enum BinOp {
253
319
Add ,
@@ -325,6 +391,7 @@ pub enum CoroutineKind {
325
391
Async ( CoroutineSource ) ,
326
392
Coroutine ,
327
393
Gen ( CoroutineSource ) ,
394
+ AsyncGen ( CoroutineSource ) ,
328
395
}
329
396
330
397
#[ derive( Copy , Clone , Debug , Eq , PartialEq ) ]
0 commit comments