@@ -3,7 +3,7 @@ use crate::ty::{
33    AdtDef ,  ClosureDef ,  Const ,  CoroutineDef ,  GenericArgs ,  Movability ,  Region ,  RigidTy ,  Ty ,  TyKind , 
44} ; 
55use  crate :: { Error ,  Opaque ,  Span ,  Symbol } ; 
6- use  std:: { io ,  slice } ; 
6+ use  std:: io ; 
77/// The SMIR representation of a single function. 
88#[ derive( Clone ,  Debug ) ]  
99pub  struct  Body  { 
@@ -23,6 +23,8 @@ pub struct Body {
2323    pub ( super )  var_debug_info :  Vec < VarDebugInfo > , 
2424} 
2525
26+ pub  type  BasicBlockIdx  = usize ; 
27+ 
2628impl  Body  { 
2729    /// Constructs a `Body`. 
2830/// 
@@ -114,66 +116,64 @@ pub struct Terminator {
114116} 
115117
116118impl  Terminator  { 
117-     pub  fn  successors ( & self )  -> Successors < ' _ >  { 
119+     pub  fn  successors ( & self )  -> Successors  { 
118120        self . kind . successors ( ) 
119121    } 
120122} 
121123
122- pub  type  Successors < ' a >  = impl   Iterator < Item  =  usize >  +  ' a ; 
124+ pub  type  Successors  = Vec < BasicBlockIdx > ; 
123125
124126#[ derive( Clone ,  Debug ,  Eq ,  PartialEq ) ]  
125127pub  enum  TerminatorKind  { 
126128    Goto  { 
127-         target :  usize , 
129+         target :  BasicBlockIdx , 
128130    } , 
129131    SwitchInt  { 
130132        discr :  Operand , 
131133        targets :  SwitchTargets , 
132-         otherwise :  usize , 
133134    } , 
134135    Resume , 
135136    Abort , 
136137    Return , 
137138    Unreachable , 
138139    Drop  { 
139140        place :  Place , 
140-         target :  usize , 
141+         target :  BasicBlockIdx , 
141142        unwind :  UnwindAction , 
142143    } , 
143144    Call  { 
144145        func :  Operand , 
145146        args :  Vec < Operand > , 
146147        destination :  Place , 
147-         target :  Option < usize > , 
148+         target :  Option < BasicBlockIdx > , 
148149        unwind :  UnwindAction , 
149150    } , 
150151    Assert  { 
151152        cond :  Operand , 
152153        expected :  bool , 
153154        msg :  AssertMessage , 
154-         target :  usize , 
155+         target :  BasicBlockIdx , 
155156        unwind :  UnwindAction , 
156157    } , 
157-     CoroutineDrop , 
158158    InlineAsm  { 
159159        template :  String , 
160160        operands :  Vec < InlineAsmOperand > , 
161161        options :  String , 
162162        line_spans :  String , 
163-         destination :  Option < usize > , 
163+         destination :  Option < BasicBlockIdx > , 
164164        unwind :  UnwindAction , 
165165    } , 
166166} 
167167
168168impl  TerminatorKind  { 
169-     pub  fn  successors ( & self )  -> Successors < ' _ >  { 
169+     pub  fn  successors ( & self )  -> Successors  { 
170170        use  self :: TerminatorKind :: * ; 
171171        match  * self  { 
172-             Call  {  target :  Some ( t) ,  unwind :  UnwindAction :: Cleanup ( ref   u) ,  .. } 
173-             | Drop  {  target :  t,  unwind :  UnwindAction :: Cleanup ( ref   u) ,  .. } 
174-             | Assert  {  target :  t,  unwind :  UnwindAction :: Cleanup ( ref   u) ,  .. } 
175-             | InlineAsm  {  destination :  Some ( t) ,  unwind :  UnwindAction :: Cleanup ( ref   u) ,  .. }  => { 
176-                 Some ( t ) . into_iter ( ) . chain ( slice :: from_ref ( u ) . into_iter ( ) . copied ( ) ) 
172+             Call  {  target :  Some ( t) ,  unwind :  UnwindAction :: Cleanup ( u) ,  .. } 
173+             | Drop  {  target :  t,  unwind :  UnwindAction :: Cleanup ( u) ,  .. } 
174+             | Assert  {  target :  t,  unwind :  UnwindAction :: Cleanup ( u) ,  .. } 
175+             | InlineAsm  {  destination :  Some ( t) ,  unwind :  UnwindAction :: Cleanup ( u) ,  .. }  => { 
176+                 vec ! [ t ,  u ] 
177177            } 
178178            Goto  {  target :  t } 
179179            | Call  {  target :  None ,  unwind :  UnwindAction :: Cleanup ( t) ,  .. } 
@@ -182,21 +182,18 @@ impl TerminatorKind {
182182            | Assert  {  target :  t,  unwind :  _,  .. } 
183183            | InlineAsm  {  destination :  None ,  unwind :  UnwindAction :: Cleanup ( t) ,  .. } 
184184            | InlineAsm  {  destination :  Some ( t) ,  unwind :  _,  .. }  => { 
185-                 Some ( t ) . into_iter ( ) . chain ( ( & [ ] ) . into_iter ( ) . copied ( ) ) 
185+                 vec ! [ t ] 
186186            } 
187187
188-             CoroutineDrop 
189-             | Return 
188+             Return 
190189            | Resume 
191190            | Abort 
192191            | Unreachable 
193192            | Call  {  target :  None ,  unwind :  _,  .. } 
194193            | InlineAsm  {  destination :  None ,  unwind :  _,  .. }  => { 
195-                 None . into_iter ( ) . chain ( ( & [ ] ) . into_iter ( ) . copied ( ) ) 
196-             } 
197-             SwitchInt  {  ref  targets,  .. }  => { 
198-                 None . into_iter ( ) . chain ( targets. targets . iter ( ) . copied ( ) ) 
194+                 vec ! [ ] 
199195            } 
196+             SwitchInt  {  ref  targets,  .. }  => targets. all_targets ( ) , 
200197        } 
201198    } 
202199
@@ -205,7 +202,6 @@ impl TerminatorKind {
205202            TerminatorKind :: Goto  {  .. } 
206203            | TerminatorKind :: Return 
207204            | TerminatorKind :: Unreachable 
208-             | TerminatorKind :: CoroutineDrop 
209205            | TerminatorKind :: Resume 
210206            | TerminatorKind :: Abort 
211207            | TerminatorKind :: SwitchInt  {  .. }  => None , 
@@ -231,7 +227,7 @@ pub enum UnwindAction {
231227    Continue , 
232228    Unreachable , 
233229    Terminate , 
234-     Cleanup ( usize ) , 
230+     Cleanup ( BasicBlockIdx ) , 
235231} 
236232
237233#[ derive( Clone ,  Debug ,  Eq ,  PartialEq ) ]  
@@ -662,10 +658,42 @@ pub struct Constant {
662658    pub  literal :  Const , 
663659} 
664660
661+ /// The possible branch sites of a [TerminatorKind::SwitchInt]. 
665662#[ derive( Clone ,  Debug ,  Eq ,  PartialEq ) ]  
666663pub  struct  SwitchTargets  { 
667-     pub  value :  Vec < u128 > , 
668-     pub  targets :  Vec < usize > , 
664+     /// The conditional branches where the first element represents the value that guards this 
665+ /// branch, and the second element is the branch target. 
666+ branches :  Vec < ( u128 ,  BasicBlockIdx ) > , 
667+     /// The `otherwise` branch which will be taken in case none of the conditional branches are 
668+ /// satisfied. 
669+ otherwise :  BasicBlockIdx , 
670+ } 
671+ 
672+ impl  SwitchTargets  { 
673+     /// All possible targets including the `otherwise` target. 
674+ pub  fn  all_targets ( & self )  -> Successors  { 
675+         self . branches . iter ( ) . map ( |( _,  target) | * target) . chain ( Some ( self . otherwise ) ) . collect ( ) 
676+     } 
677+ 
678+     /// The `otherwise` branch target. 
679+ pub  fn  otherwise ( & self )  -> BasicBlockIdx  { 
680+         self . otherwise 
681+     } 
682+ 
683+     /// The conditional targets which are only taken if the pattern matches the given value. 
684+ pub  fn  branches ( & self )  -> impl  Iterator < Item  = ( u128 ,  BasicBlockIdx ) >  + ' _  { 
685+         self . branches . iter ( ) . copied ( ) 
686+     } 
687+ 
688+     /// The number of targets including `otherwise`. 
689+ pub  fn  len ( & self )  -> usize  { 
690+         self . branches . len ( )  + 1 
691+     } 
692+ 
693+     /// Create a new SwitchTargets from the given branches and `otherwise` target. 
694+ pub  fn  new ( branches :  Vec < ( u128 ,  BasicBlockIdx ) > ,  otherwise :  BasicBlockIdx )  -> SwitchTargets  { 
695+         SwitchTargets  {  branches,  otherwise } 
696+     } 
669697} 
670698
671699#[ derive( Copy ,  Clone ,  Debug ,  Eq ,  PartialEq ) ]  
0 commit comments