Skip to content

Commit 210f768

Browse files
committed
handle gen/kill sets together
1 parent 243c5a5 commit 210f768

File tree

3 files changed

+51
-51
lines changed

3 files changed

+51
-51
lines changed

src/librustc_mir/dataflow/impls/mod.rs

Lines changed: 16 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
1515
use rustc::ty::TyCtxt;
1616
use rustc::mir::{self, Mir, Location};
17-
use rustc_data_structures::bitslice::BitSlice; // adds set_bit/get_bit to &[usize] bitvector rep.
1817
use rustc_data_structures::bitslice::{BitwiseOperator};
1918
use rustc_data_structures::indexed_set::{IdxSet};
2019
use rustc_data_structures::indexed_vec::Idx;
@@ -504,7 +503,6 @@ impl<'a, 'gcx, 'tcx> BitDenotation for MovingOutStatements<'a, 'gcx, 'tcx> {
504503
let stmt = &mir[location.block].statements[location.statement_index];
505504
let loc_map = &move_data.loc_map;
506505
let path_map = &move_data.path_map;
507-
let bits_per_block = self.bits_per_block();
508506

509507
match stmt.kind {
510508
// this analysis only tries to find moves explicitly
@@ -515,21 +513,15 @@ impl<'a, 'gcx, 'tcx> BitDenotation for MovingOutStatements<'a, 'gcx, 'tcx> {
515513
_ => {
516514
debug!("stmt {:?} at loc {:?} moves out of move_indexes {:?}",
517515
stmt, location, &loc_map[location]);
518-
for move_index in &loc_map[location] {
519-
// Every path deinitialized by a *particular move*
520-
// has corresponding bit, "gen'ed" (i.e. set)
521-
// here, in dataflow vector
522-
zero_to_one(sets.gen_set.words_mut(), *move_index);
523-
}
516+
// Every path deinitialized by a *particular move*
517+
// has corresponding bit, "gen'ed" (i.e. set)
518+
// here, in dataflow vector
519+
sets.gen_all_and_assert_dead(&loc_map[location]);
524520
}
525521
}
526522

527523
for_location_inits(tcx, mir, move_data, location,
528-
|mpi| for moi in &path_map[mpi] {
529-
assert!(moi.index() < bits_per_block);
530-
sets.kill_set.add(&moi);
531-
}
532-
);
524+
|mpi| sets.kill_all(&path_map[mpi]));
533525
}
534526

535527
fn terminator_effect(&self,
@@ -543,18 +535,10 @@ impl<'a, 'gcx, 'tcx> BitDenotation for MovingOutStatements<'a, 'gcx, 'tcx> {
543535

544536
debug!("terminator {:?} at loc {:?} moves out of move_indexes {:?}",
545537
term, location, &loc_map[location]);
546-
let bits_per_block = self.bits_per_block();
547-
for move_index in &loc_map[location] {
548-
assert!(move_index.index() < bits_per_block);
549-
zero_to_one(sets.gen_set.words_mut(), *move_index);
550-
}
538+
sets.gen_all_and_assert_dead(&loc_map[location]);
551539

552540
for_location_inits(tcx, mir, move_data, location,
553-
|mpi| for moi in &path_map[mpi] {
554-
assert!(moi.index() < bits_per_block);
555-
sets.kill_set.add(&moi);
556-
}
557-
);
541+
|mpi| sets.kill_all(&path_map[mpi]));
558542
}
559543

560544
fn propagate_call_return(&self,
@@ -585,11 +569,7 @@ impl<'a, 'gcx, 'tcx> BitDenotation for EverInitializedLvals<'a, 'gcx, 'tcx> {
585569
}
586570

587571
fn start_block_effect(&self, sets: &mut BlockSets<InitIndex>) {
588-
let bits_per_block = self.bits_per_block();
589-
for init_index in (0..self.mir.arg_count).map(InitIndex::new) {
590-
assert!(init_index.index() < bits_per_block);
591-
sets.gen_set.add(&init_index);
592-
}
572+
sets.gen_all((0..self.mir.arg_count).map(InitIndex::new));
593573
}
594574
fn statement_effect(&self,
595575
sets: &mut BlockSets<InitIndex>,
@@ -599,26 +579,19 @@ impl<'a, 'gcx, 'tcx> BitDenotation for EverInitializedLvals<'a, 'gcx, 'tcx> {
599579
let init_path_map = &move_data.init_path_map;
600580
let init_loc_map = &move_data.init_loc_map;
601581
let rev_lookup = &move_data.rev_lookup;
602-
let bits_per_block = self.bits_per_block();
603582

604583
debug!("statement {:?} at loc {:?} initializes move_indexes {:?}",
605584
stmt, location, &init_loc_map[location]);
606-
for init_index in &init_loc_map[location] {
607-
assert!(init_index.index() < bits_per_block);
608-
sets.gen_set.add(init_index);
609-
}
585+
sets.gen_all(&init_loc_map[location]);
610586

611587
match stmt.kind {
612588
mir::StatementKind::StorageDead(local) => {
613589
// End inits for StorageDead, so that an immutable variable can
614590
// be reinitialized on the next iteration of the loop.
615591
if let LookupResult::Exact(mpi) = rev_lookup.find(&mir::Place::Local(local)) {
616592
debug!("stmt {:?} at loc {:?} clears the ever initialized status of {:?}",
617-
stmt, location, &init_path_map[mpi]);
618-
for ii in &init_path_map[mpi] {
619-
assert!(ii.index() < bits_per_block);
620-
sets.kill_set.add(&ii);
621-
}
593+
stmt, location, &init_path_map[mpi]);
594+
sets.kill_all(&init_path_map[mpi]);
622595
}
623596
}
624597
_ => {}
@@ -634,13 +607,11 @@ impl<'a, 'gcx, 'tcx> BitDenotation for EverInitializedLvals<'a, 'gcx, 'tcx> {
634607
let init_loc_map = &move_data.init_loc_map;
635608
debug!("terminator {:?} at loc {:?} initializes move_indexes {:?}",
636609
term, location, &init_loc_map[location]);
637-
let bits_per_block = self.bits_per_block();
638-
for init_index in &init_loc_map[location] {
639-
if move_data.inits[*init_index].kind != InitKind::NonPanicPathOnly {
640-
assert!(init_index.index() < bits_per_block);
641-
sets.gen_set.add(init_index);
642-
}
643-
}
610+
sets.gen_all(
611+
init_loc_map[location].iter().filter(|init_index| {
612+
move_data.inits[**init_index].kind != InitKind::NonPanicPathOnly
613+
})
614+
);
644615
}
645616

646617
fn propagate_call_return(&self,
@@ -663,11 +634,6 @@ impl<'a, 'gcx, 'tcx> BitDenotation for EverInitializedLvals<'a, 'gcx, 'tcx> {
663634
}
664635
}
665636

666-
fn zero_to_one(bitvec: &mut [usize], move_index: MoveOutIndex) {
667-
let retval = bitvec.set_bit(move_index.index());
668-
assert!(retval);
669-
}
670-
671637
impl<'a, 'gcx, 'tcx> BitwiseOperator for MaybeInitializedLvals<'a, 'gcx, 'tcx> {
672638
#[inline]
673639
fn join(&self, pred1: usize, pred2: usize) -> usize {

src/librustc_mir/dataflow/mod.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use rustc::ty::{self, TyCtxt};
1818
use rustc::mir::{self, Mir, BasicBlock, BasicBlockData, Location, Statement, Terminator};
1919
use rustc::session::Session;
2020

21+
use std::borrow::Borrow;
2122
use std::fmt::{self, Debug};
2223
use std::io;
2324
use std::mem;
@@ -492,10 +493,39 @@ impl<'a, E:Idx> BlockSets<'a, E> {
492493
self.gen_set.add(e);
493494
self.kill_set.remove(e);
494495
}
496+
fn gen_all<I>(&mut self, i: I)
497+
where I: IntoIterator,
498+
I::Item: Borrow<E>
499+
{
500+
for j in i {
501+
self.gen(j.borrow());
502+
}
503+
}
504+
505+
fn gen_all_and_assert_dead<I>(&mut self, i: I)
506+
where I: IntoIterator,
507+
I::Item: Borrow<E>
508+
{
509+
for j in i {
510+
let j = j.borrow();
511+
let retval = self.gen_set.add(j);
512+
self.kill_set.remove(j);
513+
assert!(retval);
514+
}
515+
}
516+
495517
fn kill(&mut self, e: &E) {
496518
self.gen_set.remove(e);
497519
self.kill_set.add(e);
498520
}
521+
fn kill_all<I>(&mut self, i: I)
522+
where I: IntoIterator,
523+
I::Item: Borrow<E>
524+
{
525+
for j in i {
526+
self.kill(j.borrow());
527+
}
528+
}
499529
}
500530

501531
impl<E:Idx> AllSets<E> {

src/test/compile-fail/borrowck/borrowck-move-moved-value-into-closure.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
// revisions: ast mir
12+
//[mir]compile-flags: -Z borrowck=mir
13+
1114
#![feature(box_syntax)]
1215

1316
fn call_f<F:FnOnce() -> isize>(f: F) -> isize {
@@ -18,5 +21,6 @@ fn main() {
1821
let t: Box<_> = box 3;
1922

2023
call_f(move|| { *t + 1 });
21-
call_f(move|| { *t + 1 }); //~ ERROR capture of moved value
24+
call_f(move|| { *t + 1 }); //[ast]~ ERROR capture of moved value
25+
//[mir]~^ ERROR use of moved value
2226
}

0 commit comments

Comments
 (0)