@@ -31,7 +31,7 @@ use dataflow::{do_dataflow};
31
31
use dataflow:: { MoveDataParamEnv } ;
32
32
use dataflow:: { BitDenotation , BlockSets , DataflowResults , DataflowResultsConsumer } ;
33
33
use dataflow:: { MaybeInitializedLvals , MaybeUninitializedLvals } ;
34
- use dataflow:: { MovingOutStatements } ;
34
+ use dataflow:: { MovingOutStatements , EverInitializedLvals } ;
35
35
use dataflow:: { Borrows , BorrowData , BorrowIndex } ;
36
36
use dataflow:: move_paths:: { MoveError , IllegalMoveOriginKind } ;
37
37
use dataflow:: move_paths:: { HasMoveData , MoveData , MovePathIndex , LookupResult , MoveOutIndex } ;
@@ -130,6 +130,9 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
130
130
let flow_move_outs = do_dataflow ( tcx, mir, id, & attributes, & dead_unwinds,
131
131
MovingOutStatements :: new ( tcx, mir, & mdpe) ,
132
132
|bd, i| & bd. move_data ( ) . moves [ i] ) ;
133
+ let flow_ever_inits = do_dataflow ( tcx, mir, id, & attributes, & dead_unwinds,
134
+ EverInitializedLvals :: new ( tcx, mir, & mdpe) ,
135
+ |bd, i| & bd. move_data ( ) . inits [ i] ) ;
133
136
134
137
let mut mbcx = MirBorrowckCtxt {
135
138
tcx : tcx,
@@ -143,7 +146,8 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
143
146
let mut state = InProgress :: new ( flow_borrows,
144
147
flow_inits,
145
148
flow_uninits,
146
- flow_move_outs) ;
149
+ flow_move_outs,
150
+ flow_ever_inits) ;
147
151
148
152
mbcx. analyze_results ( & mut state) ; // entry point for DataflowResultsConsumer
149
153
}
@@ -167,6 +171,7 @@ pub struct InProgress<'b, 'gcx: 'tcx, 'tcx: 'b> {
167
171
inits : FlowInProgress < MaybeInitializedLvals < ' b , ' gcx , ' tcx > > ,
168
172
uninits : FlowInProgress < MaybeUninitializedLvals < ' b , ' gcx , ' tcx > > ,
169
173
move_outs : FlowInProgress < MovingOutStatements < ' b , ' gcx , ' tcx > > ,
174
+ ever_inits : FlowInProgress < EverInitializedLvals < ' b , ' gcx , ' tcx > > ,
170
175
}
171
176
172
177
struct FlowInProgress < BD > where BD : BitDenotation {
@@ -190,7 +195,8 @@ impl<'cx, 'gcx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx
190
195
flow_state. each_flow ( |b| b. reset_to_entry_of ( bb) ,
191
196
|i| i. reset_to_entry_of ( bb) ,
192
197
|u| u. reset_to_entry_of ( bb) ,
193
- |m| m. reset_to_entry_of ( bb) ) ;
198
+ |m| m. reset_to_entry_of ( bb) ,
199
+ |e| e. reset_to_entry_of ( bb) ) ;
194
200
}
195
201
196
202
fn reconstruct_statement_effect ( & mut self ,
@@ -199,7 +205,8 @@ impl<'cx, 'gcx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx
199
205
flow_state. each_flow ( |b| b. reconstruct_statement_effect ( location) ,
200
206
|i| i. reconstruct_statement_effect ( location) ,
201
207
|u| u. reconstruct_statement_effect ( location) ,
202
- |m| m. reconstruct_statement_effect ( location) ) ;
208
+ |m| m. reconstruct_statement_effect ( location) ,
209
+ |e| e. reconstruct_statement_effect ( location) ) ;
203
210
}
204
211
205
212
fn apply_local_effect ( & mut self ,
@@ -208,7 +215,8 @@ impl<'cx, 'gcx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx
208
215
flow_state. each_flow ( |b| b. apply_local_effect ( ) ,
209
216
|i| i. apply_local_effect ( ) ,
210
217
|u| u. apply_local_effect ( ) ,
211
- |m| m. apply_local_effect ( ) ) ;
218
+ |m| m. apply_local_effect ( ) ,
219
+ |e| e. apply_local_effect ( ) ) ;
212
220
}
213
221
214
222
fn reconstruct_terminator_effect ( & mut self ,
@@ -217,7 +225,8 @@ impl<'cx, 'gcx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx
217
225
flow_state. each_flow ( |b| b. reconstruct_terminator_effect ( location) ,
218
226
|i| i. reconstruct_terminator_effect ( location) ,
219
227
|u| u. reconstruct_terminator_effect ( location) ,
220
- |m| m. reconstruct_terminator_effect ( location) ) ;
228
+ |m| m. reconstruct_terminator_effect ( location) ,
229
+ |e| e. reconstruct_terminator_effect ( location) ) ;
221
230
}
222
231
223
232
fn visit_block_entry ( & mut self ,
@@ -750,22 +759,13 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
750
759
}
751
760
752
761
if let Some ( mpi) = self . move_path_for_lvalue ( lvalue) {
753
- if flow_state. inits . curr_state . contains ( & mpi) {
754
- // may already be assigned before reaching this statement;
755
- // report error.
756
- // FIXME: Not ideal, it only finds the assignment that lexically comes first
757
- let assigned_lvalue = & move_data. move_paths [ mpi] . lvalue ;
758
- let assignment_stmt = self . mir . basic_blocks ( ) . iter ( ) . filter_map ( |bb| {
759
- bb. statements . iter ( ) . find ( |stmt| {
760
- if let StatementKind :: Assign ( ref lv, _) = stmt. kind {
761
- * lv == * assigned_lvalue
762
- } else {
763
- false
764
- }
765
- } )
766
- } ) . next ( ) . unwrap ( ) ;
767
- self . report_illegal_reassignment (
768
- context, ( lvalue, span) , assignment_stmt. source_info . span ) ;
762
+ for ii in & move_data. init_path_map [ mpi] {
763
+ if flow_state. ever_inits . curr_state . contains ( ii) {
764
+ let first_assign_span = self . move_data . inits [ * ii] . span ;
765
+ self . report_illegal_reassignment (
766
+ context, ( lvalue, span) , first_assign_span) ;
767
+ break ;
768
+ }
769
769
}
770
770
}
771
771
}
@@ -1852,30 +1852,35 @@ impl<'b, 'gcx, 'tcx> InProgress<'b, 'gcx, 'tcx> {
1852
1852
pub ( super ) fn new ( borrows : DataflowResults < Borrows < ' b , ' gcx , ' tcx > > ,
1853
1853
inits : DataflowResults < MaybeInitializedLvals < ' b , ' gcx , ' tcx > > ,
1854
1854
uninits : DataflowResults < MaybeUninitializedLvals < ' b , ' gcx , ' tcx > > ,
1855
- move_out : DataflowResults < MovingOutStatements < ' b , ' gcx , ' tcx > > )
1855
+ move_out : DataflowResults < MovingOutStatements < ' b , ' gcx , ' tcx > > ,
1856
+ ever_inits : DataflowResults < EverInitializedLvals < ' b , ' gcx , ' tcx > > )
1856
1857
-> Self {
1857
1858
InProgress {
1858
1859
borrows : FlowInProgress :: new ( borrows) ,
1859
1860
inits : FlowInProgress :: new ( inits) ,
1860
1861
uninits : FlowInProgress :: new ( uninits) ,
1861
- move_outs : FlowInProgress :: new ( move_out)
1862
+ move_outs : FlowInProgress :: new ( move_out) ,
1863
+ ever_inits : FlowInProgress :: new ( ever_inits)
1862
1864
}
1863
1865
}
1864
1866
1865
- fn each_flow < XB , XI , XU , XM > ( & mut self ,
1867
+ fn each_flow < XB , XI , XU , XM , XE > ( & mut self ,
1866
1868
mut xform_borrows : XB ,
1867
1869
mut xform_inits : XI ,
1868
1870
mut xform_uninits : XU ,
1869
- mut xform_move_outs : XM ) where
1871
+ mut xform_move_outs : XM ,
1872
+ mut xform_ever_inits : XE ) where
1870
1873
XB : FnMut ( & mut FlowInProgress < Borrows < ' b , ' gcx , ' tcx > > ) ,
1871
1874
XI : FnMut ( & mut FlowInProgress < MaybeInitializedLvals < ' b , ' gcx , ' tcx > > ) ,
1872
1875
XU : FnMut ( & mut FlowInProgress < MaybeUninitializedLvals < ' b , ' gcx , ' tcx > > ) ,
1873
1876
XM : FnMut ( & mut FlowInProgress < MovingOutStatements < ' b , ' gcx , ' tcx > > ) ,
1877
+ XE : FnMut ( & mut FlowInProgress < EverInitializedLvals < ' b , ' gcx , ' tcx > > ) ,
1874
1878
{
1875
1879
xform_borrows ( & mut self . borrows ) ;
1876
1880
xform_inits ( & mut self . inits ) ;
1877
1881
xform_uninits ( & mut self . uninits ) ;
1878
1882
xform_move_outs ( & mut self . move_outs ) ;
1883
+ xform_ever_inits ( & mut self . ever_inits ) ;
1879
1884
}
1880
1885
1881
1886
fn summary ( & self ) -> String {
@@ -1932,6 +1937,17 @@ impl<'b, 'gcx, 'tcx> InProgress<'b, 'gcx, 'tcx> {
1932
1937
& self . move_outs . base_results . operator ( ) . move_data ( ) . moves [ mpi_move_out] ;
1933
1938
s. push_str ( & format ! ( "{:?}" , move_out) ) ;
1934
1939
} ) ;
1940
+ s. push_str ( "] " ) ;
1941
+
1942
+ s. push_str ( "ever_init: [" ) ;
1943
+ let mut saw_one = false ;
1944
+ self . ever_inits . each_state_bit ( |mpi_ever_init| {
1945
+ if saw_one { s. push_str ( ", " ) ; } ;
1946
+ saw_one = true ;
1947
+ let ever_init =
1948
+ & self . ever_inits . base_results . operator ( ) . move_data ( ) . inits [ mpi_ever_init] ;
1949
+ s. push_str ( & format ! ( "{:?}" , ever_init) ) ;
1950
+ } ) ;
1935
1951
s. push_str ( "]" ) ;
1936
1952
1937
1953
return s;
0 commit comments