@@ -37,7 +37,7 @@ use hir::{self, InlineAsm};
3737use std:: borrow:: { Cow } ;
3838use rustc_data_structures:: sync:: ReadGuard ;
3939use std:: fmt:: { self , Debug , Formatter , Write } ;
40- use std:: { iter, mem, u32} ;
40+ use std:: { iter, mem, option , u32} ;
4141use std:: ops:: { Index , IndexMut } ;
4242use std:: vec:: IntoIter ;
4343use syntax:: ast:: { self , Name } ;
@@ -859,12 +859,17 @@ pub enum TerminatorKind<'tcx> {
859859 } ,
860860}
861861
862+ pub type Successors < ' a > =
863+ iter:: Chain < option:: IntoIter < & ' a BasicBlock > , slice:: Iter < ' a , BasicBlock > > ;
864+ pub type SuccessorsMut < ' a > =
865+ iter:: Chain < option:: IntoIter < & ' a mut BasicBlock > , slice:: IterMut < ' a , BasicBlock > > ;
866+
862867impl < ' tcx > Terminator < ' tcx > {
863- pub fn successors ( & self ) -> Cow < [ BasicBlock ] > {
868+ pub fn successors ( & self ) -> Successors {
864869 self . kind . successors ( )
865870 }
866871
867- pub fn successors_mut ( & mut self ) -> Vec < & mut BasicBlock > {
872+ pub fn successors_mut ( & mut self ) -> SuccessorsMut {
868873 self . kind . successors_mut ( )
869874 }
870875
@@ -885,72 +890,71 @@ impl<'tcx> TerminatorKind<'tcx> {
885890 }
886891 }
887892
888- pub fn successors ( & self ) -> Cow < [ BasicBlock ] > {
893+ pub fn successors ( & self ) -> Successors {
889894 use self :: TerminatorKind :: * ;
890895 match * self {
891- Goto { target : ref b } => slice:: from_ref ( b) . into_cow ( ) ,
892- SwitchInt { targets : ref b, .. } => b[ ..] . into_cow ( ) ,
893- Resume | Abort | GeneratorDrop => ( & [ ] ) . into_cow ( ) ,
894- Return => ( & [ ] ) . into_cow ( ) ,
895- Unreachable => ( & [ ] ) . into_cow ( ) ,
896- Call { destination : Some ( ( _, t) ) , cleanup : Some ( c) , .. } => vec ! [ t, c] . into_cow ( ) ,
897- Call { destination : Some ( ( _, ref t) ) , cleanup : None , .. } =>
898- slice:: from_ref ( t) . into_cow ( ) ,
899- Call { destination : None , cleanup : Some ( ref c) , .. } => slice:: from_ref ( c) . into_cow ( ) ,
900- Call { destination : None , cleanup : None , .. } => ( & [ ] ) . into_cow ( ) ,
901- Yield { resume : t, drop : Some ( c) , .. } => vec ! [ t, c] . into_cow ( ) ,
902- Yield { resume : ref t, drop : None , .. } => slice:: from_ref ( t) . into_cow ( ) ,
903- DropAndReplace { target, unwind : Some ( unwind) , .. } |
904- Drop { target, unwind : Some ( unwind) , .. } => {
905- vec ! [ target, unwind] . into_cow ( )
896+ Resume | Abort | GeneratorDrop | Return | Unreachable |
897+ Call { destination : None , cleanup : None , .. } => {
898+ None . into_iter ( ) . chain ( & [ ] )
899+ }
900+ Goto { target : ref t } |
901+ Call { destination : None , cleanup : Some ( ref t) , .. } |
902+ Call { destination : Some ( ( _, ref t) ) , cleanup : None , .. } |
903+ Yield { resume : ref t, drop : None , .. } |
904+ DropAndReplace { target : ref t, unwind : None , .. } |
905+ Drop { target : ref t, unwind : None , .. } |
906+ Assert { target : ref t, cleanup : None , .. } |
907+ FalseUnwind { real_target : ref t, unwind : None } => {
908+ Some ( t) . into_iter ( ) . chain ( & [ ] )
906909 }
907- DropAndReplace { ref target, unwind : None , .. } |
908- Drop { ref target, unwind : None , .. } => {
909- slice:: from_ref ( target) . into_cow ( )
910+ Call { destination : Some ( ( _, ref t) ) , cleanup : Some ( ref u) , .. } |
911+ Yield { resume : ref t, drop : Some ( ref u) , .. } |
912+ DropAndReplace { target : ref t, unwind : Some ( ref u) , .. } |
913+ Drop { target : ref t, unwind : Some ( ref u) , .. } |
914+ Assert { target : ref t, cleanup : Some ( ref u) , .. } |
915+ FalseUnwind { real_target : ref t, unwind : Some ( ref u) } => {
916+ Some ( t) . into_iter ( ) . chain ( slice:: from_ref ( u) )
917+ }
918+ SwitchInt { ref targets, .. } => {
919+ None . into_iter ( ) . chain ( & targets[ ..] )
910920 }
911- Assert { target, cleanup : Some ( unwind) , .. } => vec ! [ target, unwind] . into_cow ( ) ,
912- Assert { ref target, .. } => slice:: from_ref ( target) . into_cow ( ) ,
913921 FalseEdges { ref real_target, ref imaginary_targets } => {
914- let mut s = vec ! [ * real_target] ;
915- s. extend_from_slice ( imaginary_targets) ;
916- s. into_cow ( )
922+ Some ( real_target) . into_iter ( ) . chain ( & imaginary_targets[ ..] )
917923 }
918- FalseUnwind { real_target : t, unwind : Some ( u) } => vec ! [ t, u] . into_cow ( ) ,
919- FalseUnwind { real_target : ref t, unwind : None } => slice:: from_ref ( t) . into_cow ( ) ,
920924 }
921925 }
922926
923- // FIXME: no mootable cow. I’m honestly not sure what a “cow” between `&mut [BasicBlock]` and
924- // `Vec<&mut BasicBlock>` would look like in the first place.
925- pub fn successors_mut ( & mut self ) -> Vec < & mut BasicBlock > {
927+ pub fn successors_mut ( & mut self ) -> SuccessorsMut {
926928 use self :: TerminatorKind :: * ;
927929 match * self {
928- Goto { target : ref mut b } => vec ! [ b] ,
929- SwitchInt { targets : ref mut b, .. } => b. iter_mut ( ) . collect ( ) ,
930- Resume | Abort | GeneratorDrop => Vec :: new ( ) ,
931- Return => Vec :: new ( ) ,
932- Unreachable => Vec :: new ( ) ,
933- Call { destination : Some ( ( _, ref mut t) ) , cleanup : Some ( ref mut c) , .. } => vec ! [ t, c] ,
934- Call { destination : Some ( ( _, ref mut t) ) , cleanup : None , .. } => vec ! [ t] ,
935- Call { destination : None , cleanup : Some ( ref mut c) , .. } => vec ! [ c] ,
936- Call { destination : None , cleanup : None , .. } => vec ! [ ] ,
937- Yield { resume : ref mut t, drop : Some ( ref mut c) , .. } => vec ! [ t, c] ,
938- Yield { resume : ref mut t, drop : None , .. } => vec ! [ t] ,
939- DropAndReplace { ref mut target, unwind : Some ( ref mut unwind) , .. } |
940- Drop { ref mut target, unwind : Some ( ref mut unwind) , .. } => vec ! [ target, unwind] ,
941- DropAndReplace { ref mut target, unwind : None , .. } |
942- Drop { ref mut target, unwind : None , .. } => {
943- vec ! [ target]
930+ Resume | Abort | GeneratorDrop | Return | Unreachable |
931+ Call { destination : None , cleanup : None , .. } => {
932+ None . into_iter ( ) . chain ( & mut [ ] )
933+ }
934+ Goto { target : ref mut t } |
935+ Call { destination : None , cleanup : Some ( ref mut t) , .. } |
936+ Call { destination : Some ( ( _, ref mut t) ) , cleanup : None , .. } |
937+ Yield { resume : ref mut t, drop : None , .. } |
938+ DropAndReplace { target : ref mut t, unwind : None , .. } |
939+ Drop { target : ref mut t, unwind : None , .. } |
940+ Assert { target : ref mut t, cleanup : None , .. } |
941+ FalseUnwind { real_target : ref mut t, unwind : None } => {
942+ Some ( t) . into_iter ( ) . chain ( & mut [ ] )
943+ }
944+ Call { destination : Some ( ( _, ref mut t) ) , cleanup : Some ( ref mut u) , .. } |
945+ Yield { resume : ref mut t, drop : Some ( ref mut u) , .. } |
946+ DropAndReplace { target : ref mut t, unwind : Some ( ref mut u) , .. } |
947+ Drop { target : ref mut t, unwind : Some ( ref mut u) , .. } |
948+ Assert { target : ref mut t, cleanup : Some ( ref mut u) , .. } |
949+ FalseUnwind { real_target : ref mut t, unwind : Some ( ref mut u) } => {
950+ Some ( t) . into_iter ( ) . chain ( slice:: from_ref_mut ( u) )
951+ }
952+ SwitchInt { ref mut targets, .. } => {
953+ None . into_iter ( ) . chain ( & mut targets[ ..] )
944954 }
945- Assert { ref mut target, cleanup : Some ( ref mut unwind) , .. } => vec ! [ target, unwind] ,
946- Assert { ref mut target, .. } => vec ! [ target] ,
947955 FalseEdges { ref mut real_target, ref mut imaginary_targets } => {
948- let mut s = vec ! [ real_target] ;
949- s. extend ( imaginary_targets. iter_mut ( ) ) ;
950- s
956+ Some ( real_target) . into_iter ( ) . chain ( & mut imaginary_targets[ ..] )
951957 }
952- FalseUnwind { real_target : ref mut t, unwind : Some ( ref mut u) } => vec ! [ t, u] ,
953- FalseUnwind { ref mut real_target, unwind : None } => vec ! [ real_target] ,
954958 }
955959 }
956960
@@ -1070,18 +1074,18 @@ impl<'tcx> BasicBlockData<'tcx> {
10701074impl < ' tcx > Debug for TerminatorKind < ' tcx > {
10711075 fn fmt ( & self , fmt : & mut Formatter ) -> fmt:: Result {
10721076 self . fmt_head ( fmt) ?;
1073- let successors = self . successors ( ) ;
1077+ let successor_count = self . successors ( ) . count ( ) ;
10741078 let labels = self . fmt_successor_labels ( ) ;
1075- assert_eq ! ( successors . len ( ) , labels. len( ) ) ;
1079+ assert_eq ! ( successor_count , labels. len( ) ) ;
10761080
1077- match successors . len ( ) {
1081+ match successor_count {
10781082 0 => Ok ( ( ) ) ,
10791083
1080- 1 => write ! ( fmt, " -> {:?}" , successors[ 0 ] ) ,
1084+ 1 => write ! ( fmt, " -> {:?}" , self . successors( ) . nth ( 0 ) . unwrap ( ) ) ,
10811085
10821086 _ => {
10831087 write ! ( fmt, " -> [" ) ?;
1084- for ( i, target) in successors . iter ( ) . enumerate ( ) {
1088+ for ( i, target) in self . successors ( ) . enumerate ( ) {
10851089 if i > 0 {
10861090 write ! ( fmt, ", " ) ?;
10871091 }
@@ -1969,7 +1973,7 @@ impl<'tcx> ControlFlowGraph for Mir<'tcx> {
19691973 fn successors < ' graph > ( & ' graph self , node : Self :: Node )
19701974 -> <Self as GraphSuccessors < ' graph > >:: Iter
19711975 {
1972- self . basic_blocks [ node] . terminator ( ) . successors ( ) . into_owned ( ) . into_iter ( )
1976+ self . basic_blocks [ node] . terminator ( ) . successors ( ) . cloned ( )
19731977 }
19741978}
19751979
@@ -1980,7 +1984,7 @@ impl<'a, 'b> GraphPredecessors<'b> for Mir<'a> {
19801984
19811985impl < ' a , ' b > GraphSuccessors < ' b > for Mir < ' a > {
19821986 type Item = BasicBlock ;
1983- type Iter = IntoIter < BasicBlock > ;
1987+ type Iter = iter :: Cloned < Successors < ' b > > ;
19841988}
19851989
19861990#[ derive( Copy , Clone , PartialEq , Eq , Hash , Ord , PartialOrd ) ]
0 commit comments