Skip to content

Commit 02365fe

Browse files
committed
Change successor{,_mut} to return a Vec
This helps to avoid the unpleasant restriction of being unable to have multiple successors in non-contiguous block of memory.
1 parent 432460a commit 02365fe

File tree

3 files changed

+28
-28
lines changed

3 files changed

+28
-28
lines changed

src/librustc/mir/repr.rs

Lines changed: 27 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,20 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
use graphviz::IntoCow;
1112
use middle::const_eval::ConstVal;
1213
use middle::def_id::DefId;
1314
use middle::subst::Substs;
1415
use middle::ty::{self, AdtDef, ClosureSubsts, FnOutput, Region, Ty};
1516
use rustc_back::slice;
16-
use rustc_data_structures::tuple_slice::TupleSlice;
1717
use rustc_front::hir::InlineAsm;
18-
use syntax::ast::{self, Name};
19-
use syntax::codemap::Span;
20-
use graphviz::IntoCow;
2118
use std::ascii;
22-
use std::borrow::Cow;
19+
use std::borrow::{Cow};
2320
use std::fmt::{self, Debug, Formatter, Write};
2421
use std::{iter, u32};
2522
use std::ops::{Index, IndexMut};
23+
use syntax::ast::{self, Name};
24+
use syntax::codemap::Span;
2625

2726
/// Lowered representation of a single function.
2827
#[derive(Clone, RustcEncodable, RustcDecodable)]
@@ -335,29 +334,31 @@ impl<'tcx> CallKind<'tcx> {
335334
}
336335

337336
impl<'tcx> Terminator<'tcx> {
338-
pub fn successors(&self) -> &[BasicBlock] {
337+
pub fn successors(&self) -> Cow<[BasicBlock]> {
339338
use self::Terminator::*;
340339
match *self {
341-
Goto { target: ref b } => slice::ref_slice(b),
342-
If { targets: ref b, .. } => b.as_slice(),
343-
Switch { targets: ref b, .. } => b,
344-
SwitchInt { targets: ref b, .. } => b,
345-
Resume => &[],
346-
Return => &[],
347-
Call { ref kind, .. } => kind.successors(),
340+
Goto { target: ref b } => slice::ref_slice(b).into_cow(),
341+
If { targets: (b1, b2), .. } => vec![b1, b2].into_cow(),
342+
Switch { targets: ref b, .. } => b[..].into_cow(),
343+
SwitchInt { targets: ref b, .. } => b[..].into_cow(),
344+
Resume => (&[]).into_cow(),
345+
Return => (&[]).into_cow(),
346+
Call { ref kind, .. } => kind.successors()[..].into_cow(),
348347
}
349348
}
350349

351-
pub fn successors_mut(&mut self) -> &mut [BasicBlock] {
350+
// FIXME: no mootable cow. I’m honestly not sure what a “cow” between `&mut [BasicBlock]` and
351+
// `Vec<&mut BasicBlock>` would look like in the first place.
352+
pub fn successors_mut(&mut self) -> Vec<&mut BasicBlock> {
352353
use self::Terminator::*;
353354
match *self {
354-
Goto { target: ref mut b } => slice::mut_ref_slice(b),
355-
If { targets: ref mut b, .. } => b.as_mut_slice(),
356-
Switch { targets: ref mut b, .. } => b,
357-
SwitchInt { targets: ref mut b, .. } => b,
358-
Resume => &mut [],
359-
Return => &mut [],
360-
Call { ref mut kind, .. } => kind.successors_mut(),
355+
Goto { target: ref mut b } => vec![b],
356+
If { targets: (ref mut b1, ref mut b2), .. } => vec![b1, b2],
357+
Switch { targets: ref mut b, .. } => b.iter_mut().collect(),
358+
SwitchInt { targets: ref mut b, .. } => b.iter_mut().collect(),
359+
Resume => Vec::new(),
360+
Return => Vec::new(),
361+
Call { ref mut kind, .. } => kind.successors_mut().iter_mut().collect(),
361362
}
362363
}
363364
}
@@ -445,22 +446,22 @@ impl<'tcx> Terminator<'tcx> {
445446
use self::Terminator::*;
446447
match *self {
447448
Return | Resume => vec![],
448-
Goto { .. } => vec!["".into_cow()],
449-
If { .. } => vec!["true".into_cow(), "false".into_cow()],
449+
Goto { .. } => vec!["".into()],
450+
If { .. } => vec!["true".into(), "false".into()],
450451
Switch { ref adt_def, .. } => {
451452
adt_def.variants
452453
.iter()
453-
.map(|variant| variant.name.to_string().into_cow())
454+
.map(|variant| variant.name.to_string().into())
454455
.collect()
455456
}
456457
SwitchInt { ref values, .. } => {
457458
values.iter()
458459
.map(|const_val| {
459460
let mut buf = String::new();
460461
fmt_const_val(&mut buf, const_val).unwrap();
461-
buf.into_cow()
462+
buf.into()
462463
})
463-
.chain(iter::once(String::from("otherwise").into_cow()))
464+
.chain(iter::once(String::from("otherwise").into()))
464465
.collect()
465466
}
466467
Call { ref kind, .. } => match *kind {

src/librustc_mir/build/cfg.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,4 +86,3 @@ impl<'tcx> CFG<'tcx> {
8686
self.block_data_mut(block).terminator = Some(terminator);
8787
}
8888
}
89-

src/librustc_mir/transform/simplify_cfg.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ impl SimplifyCfg {
2929

3030
let mut worklist = vec![START_BLOCK];
3131
while let Some(bb) = worklist.pop() {
32-
for succ in mir.basic_block_data(bb).terminator().successors() {
32+
for succ in mir.basic_block_data(bb).terminator().successors().iter() {
3333
if !seen[succ.index()] {
3434
seen[succ.index()] = true;
3535
worklist.push(*succ);

0 commit comments

Comments
 (0)