@@ -36,7 +36,7 @@ use hir::{self, InlineAsm};
3636use std:: borrow:: { Cow } ;
3737use rustc_data_structures:: sync:: ReadGuard ;
3838use std:: fmt:: { self , Debug , Formatter , Write } ;
39- use std:: { iter, mem, u32} ;
39+ use std:: { iter, mem, option , u32} ;
4040use std:: ops:: { Index , IndexMut } ;
4141use std:: vec:: IntoIter ;
4242use syntax:: ast:: { self , Name } ;
@@ -862,12 +862,17 @@ pub enum TerminatorKind<'tcx> {
862862 } ,
863863}
864864
865+ pub type Successors < ' a > =
866+ iter:: Chain < option:: IntoIter < & ' a BasicBlock > , slice:: Iter < ' a , BasicBlock > > ;
867+ pub type SuccessorsMut < ' a > =
868+ iter:: Chain < option:: IntoIter < & ' a mut BasicBlock > , slice:: IterMut < ' a , BasicBlock > > ;
869+
865870impl < ' tcx > Terminator < ' tcx > {
866- pub fn successors ( & self ) -> Cow < [ BasicBlock ] > {
871+ pub fn successors ( & self ) -> Successors {
867872 self . kind . successors ( )
868873 }
869874
870- pub fn successors_mut ( & mut self ) -> Vec < & mut BasicBlock > {
875+ pub fn successors_mut ( & mut self ) -> SuccessorsMut {
871876 self . kind . successors_mut ( )
872877 }
873878
@@ -888,72 +893,71 @@ impl<'tcx> TerminatorKind<'tcx> {
888893 }
889894 }
890895
891- pub fn successors ( & self ) -> Cow < [ BasicBlock ] > {
896+ pub fn successors ( & self ) -> Successors {
892897 use self :: TerminatorKind :: * ;
893898 match * self {
894- Goto { target : ref b } => slice:: from_ref ( b) . into_cow ( ) ,
895- SwitchInt { targets : ref b, .. } => b[ ..] . into_cow ( ) ,
896- Resume | Abort | GeneratorDrop => ( & [ ] ) . into_cow ( ) ,
897- Return => ( & [ ] ) . into_cow ( ) ,
898- Unreachable => ( & [ ] ) . into_cow ( ) ,
899- Call { destination : Some ( ( _, t) ) , cleanup : Some ( c) , .. } => vec ! [ t, c] . into_cow ( ) ,
900- Call { destination : Some ( ( _, ref t) ) , cleanup : None , .. } =>
901- slice:: from_ref ( t) . into_cow ( ) ,
902- Call { destination : None , cleanup : Some ( ref c) , .. } => slice:: from_ref ( c) . into_cow ( ) ,
903- Call { destination : None , cleanup : None , .. } => ( & [ ] ) . into_cow ( ) ,
904- Yield { resume : t, drop : Some ( c) , .. } => vec ! [ t, c] . into_cow ( ) ,
905- Yield { resume : ref t, drop : None , .. } => slice:: from_ref ( t) . into_cow ( ) ,
906- DropAndReplace { target, unwind : Some ( unwind) , .. } |
907- Drop { target, unwind : Some ( unwind) , .. } => {
908- vec ! [ target, unwind] . into_cow ( )
899+ Resume | Abort | GeneratorDrop | Return | Unreachable |
900+ Call { destination : None , cleanup : None , .. } => {
901+ None . into_iter ( ) . chain ( & [ ] )
902+ }
903+ Goto { target : ref t } |
904+ Call { destination : None , cleanup : Some ( ref t) , .. } |
905+ Call { destination : Some ( ( _, ref t) ) , cleanup : None , .. } |
906+ Yield { resume : ref t, drop : None , .. } |
907+ DropAndReplace { target : ref t, unwind : None , .. } |
908+ Drop { target : ref t, unwind : None , .. } |
909+ Assert { target : ref t, cleanup : None , .. } |
910+ FalseUnwind { real_target : ref t, unwind : None } => {
911+ Some ( t) . into_iter ( ) . chain ( & [ ] )
909912 }
910- DropAndReplace { ref target, unwind : None , .. } |
911- Drop { ref target, unwind : None , .. } => {
912- slice:: from_ref ( target) . into_cow ( )
913+ Call { destination : Some ( ( _, ref t) ) , cleanup : Some ( ref u) , .. } |
914+ Yield { resume : ref t, drop : Some ( ref u) , .. } |
915+ DropAndReplace { target : ref t, unwind : Some ( ref u) , .. } |
916+ Drop { target : ref t, unwind : Some ( ref u) , .. } |
917+ Assert { target : ref t, cleanup : Some ( ref u) , .. } |
918+ FalseUnwind { real_target : ref t, unwind : Some ( ref u) } => {
919+ Some ( t) . into_iter ( ) . chain ( slice:: from_ref ( u) )
920+ }
921+ SwitchInt { ref targets, .. } => {
922+ None . into_iter ( ) . chain ( & targets[ ..] )
913923 }
914- Assert { target, cleanup : Some ( unwind) , .. } => vec ! [ target, unwind] . into_cow ( ) ,
915- Assert { ref target, .. } => slice:: from_ref ( target) . into_cow ( ) ,
916924 FalseEdges { ref real_target, ref imaginary_targets } => {
917- let mut s = vec ! [ * real_target] ;
918- s. extend_from_slice ( imaginary_targets) ;
919- s. into_cow ( )
925+ Some ( real_target) . into_iter ( ) . chain ( & imaginary_targets[ ..] )
920926 }
921- FalseUnwind { real_target : t, unwind : Some ( u) } => vec ! [ t, u] . into_cow ( ) ,
922- FalseUnwind { real_target : ref t, unwind : None } => slice:: from_ref ( t) . into_cow ( ) ,
923927 }
924928 }
925929
926- // FIXME: no mootable cow. I’m honestly not sure what a “cow” between `&mut [BasicBlock]` and
927- // `Vec<&mut BasicBlock>` would look like in the first place.
928- pub fn successors_mut ( & mut self ) -> Vec < & mut BasicBlock > {
930+ pub fn successors_mut ( & mut self ) -> SuccessorsMut {
929931 use self :: TerminatorKind :: * ;
930932 match * self {
931- Goto { target : ref mut b } => vec ! [ b] ,
932- SwitchInt { targets : ref mut b, .. } => b. iter_mut ( ) . collect ( ) ,
933- Resume | Abort | GeneratorDrop => Vec :: new ( ) ,
934- Return => Vec :: new ( ) ,
935- Unreachable => Vec :: new ( ) ,
936- Call { destination : Some ( ( _, ref mut t) ) , cleanup : Some ( ref mut c) , .. } => vec ! [ t, c] ,
937- Call { destination : Some ( ( _, ref mut t) ) , cleanup : None , .. } => vec ! [ t] ,
938- Call { destination : None , cleanup : Some ( ref mut c) , .. } => vec ! [ c] ,
939- Call { destination : None , cleanup : None , .. } => vec ! [ ] ,
940- Yield { resume : ref mut t, drop : Some ( ref mut c) , .. } => vec ! [ t, c] ,
941- Yield { resume : ref mut t, drop : None , .. } => vec ! [ t] ,
942- DropAndReplace { ref mut target, unwind : Some ( ref mut unwind) , .. } |
943- Drop { ref mut target, unwind : Some ( ref mut unwind) , .. } => vec ! [ target, unwind] ,
944- DropAndReplace { ref mut target, unwind : None , .. } |
945- Drop { ref mut target, unwind : None , .. } => {
946- vec ! [ target]
933+ Resume | Abort | GeneratorDrop | Return | Unreachable |
934+ Call { destination : None , cleanup : None , .. } => {
935+ None . into_iter ( ) . chain ( & mut [ ] )
936+ }
937+ Goto { target : ref mut t } |
938+ Call { destination : None , cleanup : Some ( ref mut t) , .. } |
939+ Call { destination : Some ( ( _, ref mut t) ) , cleanup : None , .. } |
940+ Yield { resume : ref mut t, drop : None , .. } |
941+ DropAndReplace { target : ref mut t, unwind : None , .. } |
942+ Drop { target : ref mut t, unwind : None , .. } |
943+ Assert { target : ref mut t, cleanup : None , .. } |
944+ FalseUnwind { real_target : ref mut t, unwind : None } => {
945+ Some ( t) . into_iter ( ) . chain ( & mut [ ] )
946+ }
947+ Call { destination : Some ( ( _, ref mut t) ) , cleanup : Some ( ref mut u) , .. } |
948+ Yield { resume : ref mut t, drop : Some ( ref mut u) , .. } |
949+ DropAndReplace { target : ref mut t, unwind : Some ( ref mut u) , .. } |
950+ Drop { target : ref mut t, unwind : Some ( ref mut u) , .. } |
951+ Assert { target : ref mut t, cleanup : Some ( ref mut u) , .. } |
952+ FalseUnwind { real_target : ref mut t, unwind : Some ( ref mut u) } => {
953+ Some ( t) . into_iter ( ) . chain ( slice:: from_ref_mut ( u) )
954+ }
955+ SwitchInt { ref mut targets, .. } => {
956+ None . into_iter ( ) . chain ( & mut targets[ ..] )
947957 }
948- Assert { ref mut target, cleanup : Some ( ref mut unwind) , .. } => vec ! [ target, unwind] ,
949- Assert { ref mut target, .. } => vec ! [ target] ,
950958 FalseEdges { ref mut real_target, ref mut imaginary_targets } => {
951- let mut s = vec ! [ real_target] ;
952- s. extend ( imaginary_targets. iter_mut ( ) ) ;
953- s
959+ Some ( real_target) . into_iter ( ) . chain ( & mut imaginary_targets[ ..] )
954960 }
955- FalseUnwind { real_target : ref mut t, unwind : Some ( ref mut u) } => vec ! [ t, u] ,
956- FalseUnwind { ref mut real_target, unwind : None } => vec ! [ real_target] ,
957961 }
958962 }
959963
@@ -1073,18 +1077,18 @@ impl<'tcx> BasicBlockData<'tcx> {
10731077impl < ' tcx > Debug for TerminatorKind < ' tcx > {
10741078 fn fmt ( & self , fmt : & mut Formatter ) -> fmt:: Result {
10751079 self . fmt_head ( fmt) ?;
1076- let successors = self . successors ( ) ;
1080+ let successor_count = self . successors ( ) . count ( ) ;
10771081 let labels = self . fmt_successor_labels ( ) ;
1078- assert_eq ! ( successors . len ( ) , labels. len( ) ) ;
1082+ assert_eq ! ( successor_count , labels. len( ) ) ;
10791083
1080- match successors . len ( ) {
1084+ match successor_count {
10811085 0 => Ok ( ( ) ) ,
10821086
1083- 1 => write ! ( fmt, " -> {:?}" , successors[ 0 ] ) ,
1087+ 1 => write ! ( fmt, " -> {:?}" , self . successors( ) . nth ( 0 ) . unwrap ( ) ) ,
10841088
10851089 _ => {
10861090 write ! ( fmt, " -> [" ) ?;
1087- for ( i, target) in successors . iter ( ) . enumerate ( ) {
1091+ for ( i, target) in self . successors ( ) . enumerate ( ) {
10881092 if i > 0 {
10891093 write ! ( fmt, ", " ) ?;
10901094 }
@@ -1943,7 +1947,7 @@ impl<'tcx> ControlFlowGraph for Mir<'tcx> {
19431947 fn successors < ' graph > ( & ' graph self , node : Self :: Node )
19441948 -> <Self as GraphSuccessors < ' graph > >:: Iter
19451949 {
1946- self . basic_blocks [ node] . terminator ( ) . successors ( ) . into_owned ( ) . into_iter ( )
1950+ self . basic_blocks [ node] . terminator ( ) . successors ( ) . cloned ( )
19471951 }
19481952}
19491953
@@ -1954,7 +1958,7 @@ impl<'a, 'b> GraphPredecessors<'b> for Mir<'a> {
19541958
19551959impl < ' a , ' b > GraphSuccessors < ' b > for Mir < ' a > {
19561960 type Item = BasicBlock ;
1957- type Iter = IntoIter < BasicBlock > ;
1961+ type Iter = iter :: Cloned < Successors < ' b > > ;
19581962}
19591963
19601964#[ derive( Copy , Clone , PartialEq , Eq , Hash , Ord , PartialOrd ) ]
0 commit comments