@@ -37,7 +37,7 @@ use hir::{self, InlineAsm};
37
37
use std:: borrow:: { Cow } ;
38
38
use rustc_data_structures:: sync:: ReadGuard ;
39
39
use std:: fmt:: { self , Debug , Formatter , Write } ;
40
- use std:: { iter, mem, u32} ;
40
+ use std:: { iter, mem, option , u32} ;
41
41
use std:: ops:: { Index , IndexMut } ;
42
42
use std:: vec:: IntoIter ;
43
43
use syntax:: ast:: { self , Name } ;
@@ -859,12 +859,17 @@ pub enum TerminatorKind<'tcx> {
859
859
} ,
860
860
}
861
861
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
+
862
867
impl < ' tcx > Terminator < ' tcx > {
863
- pub fn successors ( & self ) -> Cow < [ BasicBlock ] > {
868
+ pub fn successors ( & self ) -> Successors {
864
869
self . kind . successors ( )
865
870
}
866
871
867
- pub fn successors_mut ( & mut self ) -> Vec < & mut BasicBlock > {
872
+ pub fn successors_mut ( & mut self ) -> SuccessorsMut {
868
873
self . kind . successors_mut ( )
869
874
}
870
875
@@ -885,72 +890,71 @@ impl<'tcx> TerminatorKind<'tcx> {
885
890
}
886
891
}
887
892
888
- pub fn successors ( & self ) -> Cow < [ BasicBlock ] > {
893
+ pub fn successors ( & self ) -> Successors {
889
894
use self :: TerminatorKind :: * ;
890
895
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 ( & [ ] )
906
909
}
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[ ..] )
910
920
}
911
- Assert { target, cleanup : Some ( unwind) , .. } => vec ! [ target, unwind] . into_cow ( ) ,
912
- Assert { ref target, .. } => slice:: from_ref ( target) . into_cow ( ) ,
913
921
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[ ..] )
917
923
}
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 ( ) ,
920
924
}
921
925
}
922
926
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 {
926
928
use self :: TerminatorKind :: * ;
927
929
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[ ..] )
944
954
}
945
- Assert { ref mut target, cleanup : Some ( ref mut unwind) , .. } => vec ! [ target, unwind] ,
946
- Assert { ref mut target, .. } => vec ! [ target] ,
947
955
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[ ..] )
951
957
}
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] ,
954
958
}
955
959
}
956
960
@@ -1070,18 +1074,18 @@ impl<'tcx> BasicBlockData<'tcx> {
1070
1074
impl < ' tcx > Debug for TerminatorKind < ' tcx > {
1071
1075
fn fmt ( & self , fmt : & mut Formatter ) -> fmt:: Result {
1072
1076
self . fmt_head ( fmt) ?;
1073
- let successors = self . successors ( ) ;
1077
+ let successor_count = self . successors ( ) . count ( ) ;
1074
1078
let labels = self . fmt_successor_labels ( ) ;
1075
- assert_eq ! ( successors . len ( ) , labels. len( ) ) ;
1079
+ assert_eq ! ( successor_count , labels. len( ) ) ;
1076
1080
1077
- match successors . len ( ) {
1081
+ match successor_count {
1078
1082
0 => Ok ( ( ) ) ,
1079
1083
1080
- 1 => write ! ( fmt, " -> {:?}" , successors[ 0 ] ) ,
1084
+ 1 => write ! ( fmt, " -> {:?}" , self . successors( ) . nth ( 0 ) . unwrap ( ) ) ,
1081
1085
1082
1086
_ => {
1083
1087
write ! ( fmt, " -> [" ) ?;
1084
- for ( i, target) in successors . iter ( ) . enumerate ( ) {
1088
+ for ( i, target) in self . successors ( ) . enumerate ( ) {
1085
1089
if i > 0 {
1086
1090
write ! ( fmt, ", " ) ?;
1087
1091
}
@@ -1969,7 +1973,7 @@ impl<'tcx> ControlFlowGraph for Mir<'tcx> {
1969
1973
fn successors < ' graph > ( & ' graph self , node : Self :: Node )
1970
1974
-> <Self as GraphSuccessors < ' graph > >:: Iter
1971
1975
{
1972
- self . basic_blocks [ node] . terminator ( ) . successors ( ) . into_owned ( ) . into_iter ( )
1976
+ self . basic_blocks [ node] . terminator ( ) . successors ( ) . cloned ( )
1973
1977
}
1974
1978
}
1975
1979
@@ -1980,7 +1984,7 @@ impl<'a, 'b> GraphPredecessors<'b> for Mir<'a> {
1980
1984
1981
1985
impl < ' a , ' b > GraphSuccessors < ' b > for Mir < ' a > {
1982
1986
type Item = BasicBlock ;
1983
- type Iter = IntoIter < BasicBlock > ;
1987
+ type Iter = iter :: Cloned < Successors < ' b > > ;
1984
1988
}
1985
1989
1986
1990
#[ derive( Copy , Clone , PartialEq , Eq , Hash , Ord , PartialOrd ) ]
0 commit comments