@@ -41,6 +41,7 @@ use std::rc::Rc;
41
41
use syntax_pos:: { Span , DUMMY_SP } ;
42
42
use transform:: { MirPass , MirSource } ;
43
43
use util:: liveness:: LivenessResults ;
44
+ use rustc_errors:: Diagnostic ;
44
45
45
46
use rustc_data_structures:: fx:: FxHashSet ;
46
47
use rustc_data_structures:: indexed_vec:: Idx ;
@@ -102,6 +103,7 @@ mod liveness;
102
103
/// constraints for the regions in the types of variables
103
104
/// - `flow_inits` -- results of a maybe-init dataflow analysis
104
105
/// - `move_data` -- move-data constructed when performing the maybe-init dataflow analysis
106
+ /// - `errors_buffer` -- errors are sent here for future reporting
105
107
pub ( crate ) fn type_check < ' gcx , ' tcx > (
106
108
infcx : & InferCtxt < ' _ , ' gcx , ' tcx > ,
107
109
param_env : ty:: ParamEnv < ' gcx > ,
@@ -115,6 +117,7 @@ pub(crate) fn type_check<'gcx, 'tcx>(
115
117
flow_inits : & mut FlowAtLocation < MaybeInitializedPlaces < ' _ , ' gcx , ' tcx > > ,
116
118
move_data : & MoveData < ' tcx > ,
117
119
elements : & Rc < RegionValueElements > ,
120
+ errors_buffer : & mut Vec < Diagnostic > ,
118
121
) -> MirTypeckRegionConstraints < ' tcx > {
119
122
let implicit_region_bound = infcx. tcx . mk_region ( ty:: ReVar ( universal_regions. fr_fn_body ) ) ;
120
123
let mut constraints = MirTypeckRegionConstraints {
@@ -140,14 +143,13 @@ pub(crate) fn type_check<'gcx, 'tcx>(
140
143
& universal_regions. region_bound_pairs ,
141
144
Some ( implicit_region_bound) ,
142
145
Some ( & mut borrowck_context) ,
146
+ Some ( errors_buffer) ,
143
147
|cx| {
144
148
liveness:: generate ( cx, mir, liveness, flow_inits, move_data) ;
145
-
146
149
cx. equate_inputs_and_outputs ( mir, mir_def_id, universal_regions) ;
147
150
} ,
148
151
) ;
149
152
}
150
-
151
153
constraints
152
154
}
153
155
@@ -159,6 +161,7 @@ fn type_check_internal<'a, 'gcx, 'tcx, F>(
159
161
region_bound_pairs : & ' a [ ( ty:: Region < ' tcx > , GenericKind < ' tcx > ) ] ,
160
162
implicit_region_bound : Option < ty:: Region < ' tcx > > ,
161
163
borrowck_context : Option < & ' a mut BorrowCheckContext < ' a , ' tcx > > ,
164
+ errors_buffer : Option < & mut Vec < Diagnostic > > ,
162
165
mut extra : F ,
163
166
)
164
167
where F : FnMut ( & mut TypeChecker < ' a , ' gcx , ' tcx > )
@@ -180,7 +183,7 @@ fn type_check_internal<'a, 'gcx, 'tcx, F>(
180
183
181
184
if !errors_reported {
182
185
// if verifier failed, don't do further checks to avoid ICEs
183
- checker. typeck_mir ( mir) ;
186
+ checker. typeck_mir ( mir, errors_buffer ) ;
184
187
}
185
188
186
189
extra ( & mut checker) ;
@@ -1227,7 +1230,12 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
1227
1230
}
1228
1231
}
1229
1232
1230
- fn check_local ( & mut self , mir : & Mir < ' tcx > , local : Local , local_decl : & LocalDecl < ' tcx > ) {
1233
+ fn check_local ( & mut self ,
1234
+ mir : & Mir < ' tcx > ,
1235
+ local : Local ,
1236
+ local_decl : & LocalDecl < ' tcx > ,
1237
+ errors_buffer : & mut Option < & mut Vec < Diagnostic > > )
1238
+ {
1231
1239
match mir. local_kind ( local) {
1232
1240
LocalKind :: ReturnPointer | LocalKind :: Arg => {
1233
1241
// return values of normal functions are required to be
@@ -1255,14 +1263,21 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
1255
1263
// slot or local, so to find all unsized rvalues it is enough
1256
1264
// to check all temps, return slots and locals.
1257
1265
if let None = self . reported_errors . replace ( ( ty, span) ) {
1258
- span_err ! (
1259
- self . tcx( ) . sess,
1260
- span,
1261
- E0161 ,
1262
- "cannot move a value of type {0}: the size of {0} \
1263
- cannot be statically determined",
1264
- ty
1265
- ) ;
1266
+ let mut diag = struct_span_err ! ( self . tcx( ) . sess,
1267
+ span,
1268
+ E0161 ,
1269
+ "cannot move a value of type {0}: the size of {0} \
1270
+ cannot be statically determined",
1271
+ ty) ;
1272
+ if let Some ( ref mut errors_buffer) = * errors_buffer {
1273
+ diag. buffer ( errors_buffer) ;
1274
+ } else {
1275
+ // we're allowed to use emit() here because the
1276
+ // NLL migration will be turned on (and thus
1277
+ // errors will need to be buffered) *only if*
1278
+ // errors_buffer is Some.
1279
+ diag. emit ( ) ;
1280
+ }
1266
1281
}
1267
1282
}
1268
1283
}
@@ -1742,12 +1757,15 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
1742
1757
} )
1743
1758
}
1744
1759
1745
- fn typeck_mir ( & mut self , mir : & Mir < ' tcx > ) {
1760
+ fn typeck_mir ( & mut self ,
1761
+ mir : & Mir < ' tcx > ,
1762
+ mut errors_buffer : Option < & mut Vec < Diagnostic > > )
1763
+ {
1746
1764
self . last_span = mir. span ;
1747
1765
debug ! ( "run_on_mir: {:?}" , mir. span) ;
1748
1766
1749
1767
for ( local, local_decl) in mir. local_decls . iter_enumerated ( ) {
1750
- self . check_local ( mir, local, local_decl) ;
1768
+ self . check_local ( mir, local, local_decl, & mut errors_buffer ) ;
1751
1769
}
1752
1770
1753
1771
for ( block, block_data) in mir. basic_blocks ( ) . iter_enumerated ( ) {
@@ -1812,7 +1830,7 @@ impl MirPass for TypeckMir {
1812
1830
1813
1831
let param_env = tcx. param_env ( def_id) ;
1814
1832
tcx. infer_ctxt ( ) . enter ( |infcx| {
1815
- type_check_internal ( & infcx, def_id, param_env, mir, & [ ] , None , None , |_| ( ) ) ;
1833
+ type_check_internal ( & infcx, def_id, param_env, mir, & [ ] , None , None , None , |_| ( ) ) ;
1816
1834
1817
1835
// For verification purposes, we just ignore the resulting
1818
1836
// region constraint sets. Not our problem. =)
0 commit comments