|
| 1 | +use std::fmt; |
| 2 | + |
1 | 3 | use rustc_data_structures::fx::FxIndexMap; |
2 | 4 | use rustc_data_structures::graph; |
3 | 5 | use rustc_index::bit_set::BitSet; |
4 | | -use rustc_middle::mir::{self,BasicBlock,Body,Location,Place,TerminatorEdges}; |
| 6 | +use rustc_middle::mir::{ |
| 7 | +self,BasicBlock,Body,CallReturnPlaces,Location,Place,TerminatorEdges, |
| 8 | +}; |
5 | 9 | use rustc_middle::ty::{RegionVid,TyCtxt}; |
6 | 10 | use rustc_mir_dataflow::fmt::DebugWithContext; |
7 | 11 | use rustc_mir_dataflow::impls::{EverInitializedPlaces,MaybeUninitializedPlaces}; |
8 | | -use rustc_mir_dataflow::{Analysis,Forward,GenKill,Results,ResultsVisitable}; |
| 12 | +use rustc_mir_dataflow::{Analysis,GenKill,JoinSemiLattice,SwitchIntEdgeEffects}; |
9 | 13 | use tracing::debug; |
10 | 14 |
|
11 | 15 | usecrate::{BorrowSet,PlaceConflictBias,PlaceExt,RegionInferenceContext, places_conflict}; |
12 | 16 |
|
13 | | -/// The results of the dataflow analyses used by the borrow checker. |
14 | | -pub(crate)structBorrowckResults<'a,'tcx>{ |
15 | | -pub(crate)borrows:Results<'tcx,Borrows<'a,'tcx>>, |
16 | | -pub(crate)uninits:Results<'tcx,MaybeUninitializedPlaces<'a,'tcx>>, |
17 | | -pub(crate)ever_inits:Results<'tcx,EverInitializedPlaces<'a,'tcx>>, |
18 | | -} |
19 | | - |
20 | | -/// The transient state of the dataflow analyses used by the borrow checker. |
21 | | -#[derive(Debug)] |
22 | | -pub(crate)structBorrowckDomain<'a,'tcx>{ |
23 | | -pub(crate)borrows: <Borrows<'a,'tcx>asAnalysis<'tcx>>::Domain, |
24 | | -pub(crate)uninits: <MaybeUninitializedPlaces<'a,'tcx>asAnalysis<'tcx>>::Domain, |
25 | | -pub(crate)ever_inits: <EverInitializedPlaces<'a,'tcx>asAnalysis<'tcx>>::Domain, |
| 17 | +// This analysis is different to most others. Its results aren't computed with |
| 18 | +// `iterate_to_fixpoint`, but are instead composed from the results of three sub-analyses that are |
| 19 | +// computed individually with `iterate_to_fixpoint`. |
| 20 | +pub(crate)structBorrowck<'a,'tcx>{ |
| 21 | +pub(crate)borrows:Borrows<'a,'tcx>, |
| 22 | +pub(crate)uninits:MaybeUninitializedPlaces<'a,'tcx>, |
| 23 | +pub(crate)ever_inits:EverInitializedPlaces<'a,'tcx>, |
26 | 24 | } |
27 | 25 |
|
28 | | -impl<'a,'tcx>ResultsVisitable<'tcx>forBorrowckResults<'a,'tcx>{ |
29 | | -typeDirection = Forward; |
| 26 | +impl<'a,'tcx>Analysis<'tcx>forBorrowck<'a,'tcx>{ |
30 | 27 | typeDomain = BorrowckDomain<'a,'tcx>; |
31 | 28 |
|
| 29 | +constNAME:&'staticstr = "borrowck"; |
| 30 | + |
32 | 31 | fnbottom_value(&self,body:&mir::Body<'tcx>) -> Self::Domain{ |
33 | 32 | BorrowckDomain{ |
34 | | -borrows:self.borrows.analysis.bottom_value(body), |
35 | | -uninits:self.uninits.analysis.bottom_value(body), |
36 | | -ever_inits:self.ever_inits.analysis.bottom_value(body), |
| 33 | +borrows:self.borrows.bottom_value(body), |
| 34 | +uninits:self.uninits.bottom_value(body), |
| 35 | +ever_inits:self.ever_inits.bottom_value(body), |
37 | 36 | } |
38 | 37 | } |
39 | 38 |
|
40 | | -fnreset_to_block_entry(&self,state:&mutSelf::Domain,block:BasicBlock){ |
41 | | - state.borrows.clone_from(self.borrows.entry_set_for_block(block)); |
42 | | - state.uninits.clone_from(self.uninits.entry_set_for_block(block)); |
43 | | - state.ever_inits.clone_from(self.ever_inits.entry_set_for_block(block)); |
| 39 | +fninitialize_start_block(&self,_body:&mir::Body<'tcx>,_state:&mutSelf::Domain){ |
| 40 | +// This is only reachable from `iterate_to_fixpoint`, which this analysis doesn't use. |
| 41 | +unreachable!(); |
44 | 42 | } |
45 | 43 |
|
46 | | -fnreconstruct_before_statement_effect( |
| 44 | +fnapply_before_statement_effect( |
47 | 45 | &mutself, |
48 | 46 | state:&mutSelf::Domain, |
49 | 47 | stmt:&mir::Statement<'tcx>, |
50 | 48 | loc:Location, |
51 | 49 | ){ |
52 | | -self.borrows.analysis.apply_before_statement_effect(&mut state.borrows, stmt, loc); |
53 | | -self.uninits.analysis.apply_before_statement_effect(&mut state.uninits, stmt, loc); |
54 | | -self.ever_inits.analysis.apply_before_statement_effect(&mut state.ever_inits, stmt, loc); |
| 50 | +self.borrows.apply_before_statement_effect(&mut state.borrows, stmt, loc); |
| 51 | +self.uninits.apply_before_statement_effect(&mut state.uninits, stmt, loc); |
| 52 | +self.ever_inits.apply_before_statement_effect(&mut state.ever_inits, stmt, loc); |
55 | 53 | } |
56 | 54 |
|
57 | | -fnreconstruct_statement_effect( |
| 55 | +fnapply_statement_effect( |
58 | 56 | &mutself, |
59 | 57 | state:&mutSelf::Domain, |
60 | 58 | stmt:&mir::Statement<'tcx>, |
61 | 59 | loc:Location, |
62 | 60 | ){ |
63 | | -self.borrows.analysis.apply_statement_effect(&mut state.borrows, stmt, loc); |
64 | | -self.uninits.analysis.apply_statement_effect(&mut state.uninits, stmt, loc); |
65 | | -self.ever_inits.analysis.apply_statement_effect(&mut state.ever_inits, stmt, loc); |
| 61 | +self.borrows.apply_statement_effect(&mut state.borrows, stmt, loc); |
| 62 | +self.uninits.apply_statement_effect(&mut state.uninits, stmt, loc); |
| 63 | +self.ever_inits.apply_statement_effect(&mut state.ever_inits, stmt, loc); |
66 | 64 | } |
67 | 65 |
|
68 | | -fnreconstruct_before_terminator_effect( |
| 66 | +fnapply_before_terminator_effect( |
69 | 67 | &mutself, |
70 | 68 | state:&mutSelf::Domain, |
71 | 69 | term:&mir::Terminator<'tcx>, |
72 | 70 | loc:Location, |
73 | 71 | ){ |
74 | | -self.borrows.analysis.apply_before_terminator_effect(&mut state.borrows, term, loc); |
75 | | -self.uninits.analysis.apply_before_terminator_effect(&mut state.uninits, term, loc); |
76 | | -self.ever_inits.analysis.apply_before_terminator_effect(&mut state.ever_inits, term, loc); |
| 72 | +self.borrows.apply_before_terminator_effect(&mut state.borrows, term, loc); |
| 73 | +self.uninits.apply_before_terminator_effect(&mut state.uninits, term, loc); |
| 74 | +self.ever_inits.apply_before_terminator_effect(&mut state.ever_inits, term, loc); |
77 | 75 | } |
78 | 76 |
|
79 | | -fnreconstruct_terminator_effect( |
| 77 | +fnapply_terminator_effect<'mir>( |
80 | 78 | &mutself, |
81 | 79 | state:&mutSelf::Domain, |
82 | | -term:&mir::Terminator<'tcx>, |
| 80 | +term:&'mirmir::Terminator<'tcx>, |
83 | 81 | loc:Location, |
| 82 | +) -> TerminatorEdges<'mir,'tcx>{ |
| 83 | +self.borrows.apply_terminator_effect(&mut state.borrows, term, loc); |
| 84 | +self.uninits.apply_terminator_effect(&mut state.uninits, term, loc); |
| 85 | +self.ever_inits.apply_terminator_effect(&mut state.ever_inits, term, loc); |
| 86 | + |
| 87 | +// This return value doesn't matter. It's only used by `iterate_to_fixpoint`, which this |
| 88 | +// analysis doesn't use. |
| 89 | +TerminatorEdges::None |
| 90 | +} |
| 91 | + |
| 92 | +fnapply_call_return_effect( |
| 93 | +&mutself, |
| 94 | +_state:&mutSelf::Domain, |
| 95 | +_block:BasicBlock, |
| 96 | +_return_places:CallReturnPlaces<'_,'tcx>, |
| 97 | +){ |
| 98 | +// This is only reachable from `iterate_to_fixpoint`, which this analysis doesn't use. |
| 99 | +unreachable!(); |
| 100 | +} |
| 101 | + |
| 102 | +fnapply_switch_int_edge_effects( |
| 103 | +&mutself, |
| 104 | +_block:BasicBlock, |
| 105 | +_discr:&mir::Operand<'tcx>, |
| 106 | +_apply_edge_effects:&mutimplSwitchIntEdgeEffects<Self::Domain>, |
84 | 107 | ){ |
85 | | -self.borrows.analysis.apply_terminator_effect(&mut state.borrows, term, loc); |
86 | | -self.uninits.analysis.apply_terminator_effect(&mut state.uninits, term, loc); |
87 | | -self.ever_inits.analysis.apply_terminator_effect(&mut state.ever_inits, term, loc); |
| 108 | +// This is only reachable from `iterate_to_fixpoint`, which this analysis doesn't use. |
| 109 | +unreachable!(); |
88 | 110 | } |
89 | 111 | } |
90 | 112 |
|
| 113 | +implJoinSemiLatticeforBorrowckDomain<'_,'_>{ |
| 114 | +fnjoin(&mutself,_other:&Self) -> bool{ |
| 115 | +// This is only reachable from `iterate_to_fixpoint`, which this analysis doesn't use. |
| 116 | +unreachable!(); |
| 117 | +} |
| 118 | +} |
| 119 | + |
| 120 | +impl<'tcx,C>DebugWithContext<C>forBorrowckDomain<'_,'tcx> |
| 121 | +where |
| 122 | +C: rustc_mir_dataflow::move_paths::HasMoveData<'tcx>, |
| 123 | +{ |
| 124 | +fnfmt_with(&self,ctxt:&C,f:&mut fmt::Formatter<'_>) -> fmt::Result{ |
| 125 | + f.write_str("borrows: ")?; |
| 126 | +self.borrows.fmt_with(ctxt, f)?; |
| 127 | + f.write_str(" uninits: ")?; |
| 128 | +self.uninits.fmt_with(ctxt, f)?; |
| 129 | + f.write_str(" ever_inits: ")?; |
| 130 | +self.ever_inits.fmt_with(ctxt, f)?; |
| 131 | +Ok(()) |
| 132 | +} |
| 133 | + |
| 134 | +fnfmt_diff_with(&self,old:&Self,ctxt:&C,f:&mut fmt::Formatter<'_>) -> fmt::Result{ |
| 135 | +ifself == old { |
| 136 | +returnOk(()); |
| 137 | +} |
| 138 | + |
| 139 | +ifself.borrows != old.borrows{ |
| 140 | + f.write_str("borrows: ")?; |
| 141 | +self.borrows.fmt_diff_with(&old.borrows, ctxt, f)?; |
| 142 | + f.write_str("\n")?; |
| 143 | +} |
| 144 | + |
| 145 | +ifself.uninits != old.uninits{ |
| 146 | + f.write_str("uninits: ")?; |
| 147 | +self.uninits.fmt_diff_with(&old.uninits, ctxt, f)?; |
| 148 | + f.write_str("\n")?; |
| 149 | +} |
| 150 | + |
| 151 | +ifself.ever_inits != old.ever_inits{ |
| 152 | + f.write_str("ever_inits: ")?; |
| 153 | +self.ever_inits.fmt_diff_with(&old.ever_inits, ctxt, f)?; |
| 154 | + f.write_str("\n")?; |
| 155 | +} |
| 156 | + |
| 157 | +Ok(()) |
| 158 | +} |
| 159 | +} |
| 160 | + |
| 161 | +/// The transient state of the dataflow analyses used by the borrow checker. |
| 162 | +#[derive(Clone,Debug,PartialEq,Eq)] |
| 163 | +pub(crate)structBorrowckDomain<'a,'tcx>{ |
| 164 | +pub(crate)borrows: <Borrows<'a,'tcx>asAnalysis<'tcx>>::Domain, |
| 165 | +pub(crate)uninits: <MaybeUninitializedPlaces<'a,'tcx>asAnalysis<'tcx>>::Domain, |
| 166 | +pub(crate)ever_inits: <EverInitializedPlaces<'a,'tcx>asAnalysis<'tcx>>::Domain, |
| 167 | +} |
| 168 | + |
91 | 169 | rustc_index::newtype_index! { |
92 | 170 | #[orderable] |
93 | 171 | #[debug_format = "bw{}"] |
|
0 commit comments