@@ -22,6 +22,11 @@ pub struct Body {
2222
2323 /// Debug information pertaining to user variables, including captures.
2424 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 > ,
2530}
2631
2732pub type BasicBlockIdx = usize ;
@@ -36,14 +41,15 @@ impl Body {
3641 locals : LocalDecls ,
3742 arg_count : usize ,
3843 var_debug_info : Vec < VarDebugInfo > ,
44+ spread_arg : Option < Local > ,
3945 ) -> Self {
4046 // If locals doesn't contain enough entries, it can lead to panics in
4147 // `ret_local`, `arg_locals`, and `inner_locals`.
4248 assert ! (
4349 locals. len( ) > arg_count,
4450 "A Body must contain at least a local for the return value and each of the function's arguments"
4551 ) ;
46- Self { blocks, locals, arg_count, var_debug_info }
52+ Self { blocks, locals, arg_count, var_debug_info, spread_arg }
4753 }
4854
4955 /// Return local that holds this function's return value.
@@ -75,6 +81,11 @@ impl Body {
7581 self . locals . get ( local)
7682 }
7783
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+
7889 pub fn dump < W : io:: Write > ( & self , w : & mut W ) -> io:: Result < ( ) > {
7990 writeln ! ( w, "{}" , function_body( self ) ) ?;
8091 self . blocks
@@ -98,6 +109,10 @@ impl Body {
98109 . collect :: < Result < Vec < _ > , _ > > ( ) ?;
99110 Ok ( ( ) )
100111 }
112+
113+ pub fn spread_arg ( & self ) -> Option < Local > {
114+ self . spread_arg
115+ }
101116}
102117
103118type LocalDecls = Vec < LocalDecl > ;
@@ -248,6 +263,57 @@ pub enum AssertMessage {
248263 MisalignedPointerDereference { required : Operand , found : Operand } ,
249264}
250265
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+
251317#[ derive( Copy , Clone , Debug , Eq , PartialEq ) ]
252318pub enum BinOp {
253319 Add ,
@@ -325,6 +391,7 @@ pub enum CoroutineKind {
325391 Async ( CoroutineSource ) ,
326392 Coroutine ,
327393 Gen ( CoroutineSource ) ,
394+ AsyncGen ( CoroutineSource ) ,
328395}
329396
330397#[ derive( Copy , Clone , Debug , Eq , PartialEq ) ]
0 commit comments