]> git.lizzy.rs Git - rust.git/blob - src/librustc_mir/dataflow/impls/borrowed_locals.rs
Changes the type `mir::Mir` into `mir::Body`
[rust.git] / src / librustc_mir / dataflow / impls / borrowed_locals.rs
1 pub use super::*;
2
3 use rustc::mir::*;
4 use rustc::mir::visit::Visitor;
5 use crate::dataflow::BitDenotation;
6
7 /// This calculates if any part of a MIR local could have previously been borrowed.
8 /// This means that once a local has been borrowed, its bit will be set
9 /// from that point and onwards, until we see a StorageDead statement for the local,
10 /// at which points there is no memory associated with the local, so it cannot be borrowed.
11 /// This is used to compute which locals are live during a yield expression for
12 /// immovable generators.
13 #[derive(Copy, Clone)]
14 pub struct HaveBeenBorrowedLocals<'a, 'tcx: 'a> {
15     mir: &'a Body<'tcx>,
16 }
17
18 impl<'a, 'tcx: 'a> HaveBeenBorrowedLocals<'a, 'tcx> {
19     pub fn new(mir: &'a Body<'tcx>)
20                -> Self {
21         HaveBeenBorrowedLocals { mir }
22     }
23
24     pub fn mir(&self) -> &Body<'tcx> {
25         self.mir
26     }
27 }
28
29 impl<'a, 'tcx> BitDenotation<'tcx> for HaveBeenBorrowedLocals<'a, 'tcx> {
30     type Idx = Local;
31     fn name() -> &'static str { "has_been_borrowed_locals" }
32     fn bits_per_block(&self) -> usize {
33         self.mir.local_decls.len()
34     }
35
36     fn start_block_effect(&self, _sets: &mut BitSet<Local>) {
37         // Nothing is borrowed on function entry
38     }
39
40     fn statement_effect(&self,
41                         sets: &mut BlockSets<'_, Local>,
42                         loc: Location) {
43         let stmt = &self.mir[loc.block].statements[loc.statement_index];
44
45         BorrowedLocalsVisitor {
46             sets,
47         }.visit_statement(stmt, loc);
48
49         // StorageDead invalidates all borrows and raw pointers to a local
50         match stmt.kind {
51             StatementKind::StorageDead(l) => sets.kill(l),
52             _ => (),
53         }
54     }
55
56     fn terminator_effect(&self,
57                          sets: &mut BlockSets<'_, Local>,
58                          loc: Location) {
59         BorrowedLocalsVisitor {
60             sets,
61         }.visit_terminator(self.mir[loc.block].terminator(), loc);
62     }
63
64     fn propagate_call_return(
65         &self,
66         _in_out: &mut BitSet<Local>,
67         _call_bb: mir::BasicBlock,
68         _dest_bb: mir::BasicBlock,
69         _dest_place: &mir::Place<'tcx>,
70     ) {
71         // Nothing to do when a call returns successfully
72     }
73 }
74
75 impl<'a, 'tcx> BitSetOperator for HaveBeenBorrowedLocals<'a, 'tcx> {
76     #[inline]
77     fn join<T: Idx>(&self, inout_set: &mut BitSet<T>, in_set: &BitSet<T>) -> bool {
78         inout_set.union(in_set) // "maybe" means we union effects of both preds
79     }
80 }
81
82 impl<'a, 'tcx> InitialFlow for HaveBeenBorrowedLocals<'a, 'tcx> {
83     #[inline]
84     fn bottom_value() -> bool {
85         false // bottom = unborrowed
86     }
87 }
88
89 struct BorrowedLocalsVisitor<'b, 'c: 'b> {
90     sets: &'b mut BlockSets<'c, Local>,
91 }
92
93 fn find_local<'tcx>(place: &Place<'tcx>) -> Option<Local> {
94     place.iterate(|place_base, place_projection| {
95         for proj in place_projection {
96             if proj.elem == ProjectionElem::Deref {
97                 return None;
98             }
99         }
100
101         if let PlaceBase::Local(local) = place_base {
102             Some(*local)
103         } else {
104             None
105         }
106     })
107 }
108
109 impl<'tcx, 'b, 'c> Visitor<'tcx> for BorrowedLocalsVisitor<'b, 'c> {
110     fn visit_rvalue(&mut self,
111                     rvalue: &Rvalue<'tcx>,
112                     location: Location) {
113         if let Rvalue::Ref(_, _, ref place) = *rvalue {
114             if let Some(local) = find_local(place) {
115                 self.sets.gen(local);
116             }
117         }
118
119         self.super_rvalue(rvalue, location)
120     }
121 }