@@ -208,15 +208,28 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
208
208
i, self . resolver. unresolved_imports) ;
209
209
210
210
let module_root = self . resolver . graph_root . get_module ( ) ;
211
- self . resolve_imports_for_module_subtree ( module_root. clone ( ) ) ;
211
+ let errors = self . resolve_imports_for_module_subtree ( module_root. clone ( ) ) ;
212
212
213
213
if self . resolver . unresolved_imports == 0 {
214
214
debug ! ( "(resolving imports) success" ) ;
215
215
break ;
216
216
}
217
217
218
218
if self . resolver . unresolved_imports == prev_unresolved_imports {
219
- self . resolver . report_unresolved_imports ( module_root) ;
219
+ // resolving failed
220
+ if errors. len ( ) > 0 {
221
+ for ( span, path, help) in errors {
222
+ resolve_error ( self . resolver ,
223
+ span,
224
+ ResolutionError :: UnresolvedImport ( Some ( ( & * path, & * help) ) ) ) ;
225
+ }
226
+ } else {
227
+ // report unresolved imports only if no hard error was already reported
228
+ // to avoid generating multiple errors on the same import
229
+ // imports that are still undeterminate at this point are actually blocked
230
+ // by errored imports, so there is no point reporting them
231
+ self . resolver . report_unresolved_imports ( module_root) ;
232
+ }
220
233
break ;
221
234
}
222
235
@@ -227,11 +240,13 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
227
240
228
241
/// Attempts to resolve imports for the given module and all of its
229
242
/// submodules.
230
- fn resolve_imports_for_module_subtree ( & mut self , module_ : Rc < Module > ) {
243
+ fn resolve_imports_for_module_subtree ( & mut self , module_ : Rc < Module > )
244
+ -> Vec < ( Span , String , String ) > {
245
+ let mut errors = Vec :: new ( ) ;
231
246
debug ! ( "(resolving imports for module subtree) resolving {}" ,
232
247
module_to_string( & * module_) ) ;
233
248
let orig_module = replace ( & mut self . resolver . current_module , module_. clone ( ) ) ;
234
- self . resolve_imports_for_module ( module_. clone ( ) ) ;
249
+ errors . extend ( self . resolve_imports_for_module ( module_. clone ( ) ) ) ;
235
250
self . resolver . current_module = orig_module;
236
251
237
252
build_reduced_graph:: populate_module_if_necessary ( self . resolver , & module_) ;
@@ -241,53 +256,65 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
241
256
// Nothing to do.
242
257
}
243
258
Some ( child_module) => {
244
- self . resolve_imports_for_module_subtree ( child_module) ;
259
+ errors . extend ( self . resolve_imports_for_module_subtree ( child_module) ) ;
245
260
}
246
261
}
247
262
}
248
263
249
264
for ( _, child_module) in module_. anonymous_children . borrow ( ) . iter ( ) {
250
- self . resolve_imports_for_module_subtree ( child_module. clone ( ) ) ;
265
+ errors . extend ( self . resolve_imports_for_module_subtree ( child_module. clone ( ) ) ) ;
251
266
}
267
+
268
+ errors
252
269
}
253
270
254
271
/// Attempts to resolve imports for the given module only.
255
- fn resolve_imports_for_module ( & mut self , module : Rc < Module > ) {
272
+ fn resolve_imports_for_module ( & mut self , module : Rc < Module > ) -> Vec < ( Span , String , String ) > {
273
+ let mut errors = Vec :: new ( ) ;
274
+
256
275
if module. all_imports_resolved ( ) {
257
276
debug ! ( "(resolving imports for module) all imports resolved for \
258
277
{}",
259
278
module_to_string( & * module) ) ;
260
- return ;
279
+ return errors ;
261
280
}
262
281
263
- let imports = module. imports . borrow ( ) ;
282
+ let mut imports = module. imports . borrow_mut ( ) ;
264
283
let import_count = imports. len ( ) ;
265
- while module. resolved_import_count . get ( ) < import_count {
284
+ let mut indeterminate_imports = Vec :: new ( ) ;
285
+ while module. resolved_import_count . get ( ) + indeterminate_imports. len ( ) < import_count {
266
286
let import_index = module. resolved_import_count . get ( ) ;
267
- let import_directive = & ( * imports) [ import_index] ;
268
287
match self . resolve_import_for_module ( module. clone ( ) ,
269
- import_directive ) {
288
+ & imports [ import_index ] ) {
270
289
ResolveResult :: Failed ( err) => {
290
+ let import_directive = & imports[ import_index] ;
271
291
let ( span, help) = match err {
272
292
Some ( ( span, msg) ) => ( span, format ! ( ". {}" , msg) ) ,
273
293
None => ( import_directive. span , String :: new ( ) )
274
294
} ;
275
- resolve_error ( self . resolver ,
276
- span,
277
- ResolutionError :: UnresolvedImport (
278
- Some ( ( & * import_path_to_string (
279
- & import_directive. module_path ,
280
- import_directive. subclass ) ,
281
- & * help) ) )
282
- ) ;
295
+ errors. push ( ( span,
296
+ import_path_to_string (
297
+ & import_directive. module_path ,
298
+ import_directive. subclass
299
+ ) ,
300
+ help) )
301
+ }
302
+ ResolveResult :: Indeterminate => { }
303
+ ResolveResult :: Success ( ( ) ) => {
304
+ // count success
305
+ module. resolved_import_count
306
+ . set ( module. resolved_import_count . get ( ) + 1 ) ;
307
+ continue ;
283
308
}
284
- ResolveResult :: Indeterminate => break , // Bail out. We'll come around next time.
285
- ResolveResult :: Success ( ( ) ) => ( ) // Good. Continue.
286
309
}
310
+ // This resolution was not successful, keep it for later
311
+ indeterminate_imports. push ( imports. swap_remove ( import_index) ) ;
287
312
288
- module. resolved_import_count
289
- . set ( module. resolved_import_count . get ( ) + 1 ) ;
290
313
}
314
+
315
+ imports. extend ( indeterminate_imports) ;
316
+
317
+ errors
291
318
}
292
319
293
320
/// Attempts to resolve the given import. The return value indicates
@@ -367,11 +394,10 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
367
394
}
368
395
369
396
// Decrement the count of unresolved globs if necessary. But only if
370
- // the resolution result is indeterminate -- otherwise we'll stop
371
- // processing imports here. (See the loop in
372
- // resolve_imports_for_module).
397
+ // the resolution result is a success -- other cases will
398
+ // be handled by the main loop.
373
399
374
- if ! resolution_result. indeterminate ( ) {
400
+ if resolution_result. success ( ) {
375
401
match import_directive. subclass {
376
402
GlobImport => {
377
403
assert ! ( module_. glob_count. get( ) >= 1 ) ;
0 commit comments