@@ -65,9 +65,6 @@ use super::region_inference::ConcreteFailure;
65
65
use super :: region_inference:: SubSupConflict ;
66
66
use super :: region_inference:: GenericBoundFailure ;
67
67
use super :: region_inference:: GenericKind ;
68
- use super :: region_inference:: ProcessedErrors ;
69
- use super :: region_inference:: ProcessedErrorOrigin ;
70
- use super :: region_inference:: SameRegions ;
71
68
72
69
use hir:: map as hir_map;
73
70
use hir;
@@ -77,11 +74,10 @@ use infer;
77
74
use middle:: region;
78
75
use traits:: { ObligationCause , ObligationCauseCode } ;
79
76
use ty:: { self , TyCtxt , TypeFoldable } ;
80
- use ty:: { Region , ReFree , Issue32330 } ;
77
+ use ty:: { Region , Issue32330 } ;
81
78
use ty:: error:: TypeError ;
82
79
83
80
use std:: fmt;
84
- use syntax:: ast;
85
81
use syntax_pos:: { Pos , Span } ;
86
82
use errors:: DiagnosticBuilder ;
87
83
@@ -255,8 +251,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
255
251
256
252
// try to pre-process the errors, which will group some of them
257
253
// together into a `ProcessedErrors` group:
258
- let processed_errors = self . process_errors ( errors) ;
259
- let errors = processed_errors. as_ref ( ) . unwrap_or ( errors) ;
254
+ let errors = self . process_errors ( errors) ;
260
255
261
256
debug ! ( "report_region_errors: {} errors after preprocessing" , errors. len( ) ) ;
262
257
@@ -278,13 +273,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
278
273
sub_origin, sub_r,
279
274
sup_origin, sup_r) ;
280
275
}
281
-
282
- ProcessedErrors ( ref origins,
283
- ref same_regions) => {
284
- if !same_regions. is_empty ( ) {
285
- self . report_processed_errors ( origins) ;
286
- }
287
- }
288
276
}
289
277
}
290
278
}
@@ -300,202 +288,31 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
300
288
// duplicates that will be unhelpful to the end-user. But
301
289
// obviously it never weeds out ALL errors.
302
290
fn process_errors ( & self , errors : & Vec < RegionResolutionError < ' tcx > > )
303
- -> Option < Vec < RegionResolutionError < ' tcx > > > {
291
+ -> Vec < RegionResolutionError < ' tcx > > {
304
292
debug ! ( "process_errors()" ) ;
305
- let mut origins = Vec :: new ( ) ;
306
-
307
- // we collect up ConcreteFailures and SubSupConflicts that are
308
- // relating free-regions bound on the fn-header and group them
309
- // together into this vector
310
- let mut same_regions = Vec :: new ( ) ;
311
-
312
- // here we put errors that we will not be able to process nicely
313
- let mut other_errors = Vec :: new ( ) ;
314
-
315
- // we collect up GenericBoundFailures in here.
316
- let mut bound_failures = Vec :: new ( ) ;
317
-
318
- for error in errors {
319
- // Check whether we can process this error into some other
320
- // form; if not, fall through.
321
- match * error {
322
- ConcreteFailure ( ref origin, sub, sup) => {
323
- debug ! ( "processing ConcreteFailure" ) ;
324
- if let SubregionOrigin :: CompareImplMethodObligation { .. } = * origin {
325
- // When comparing an impl method against a
326
- // trait method, it is not helpful to suggest
327
- // changes to the impl method. This is
328
- // because the impl method signature is being
329
- // checked using the trait's environment, so
330
- // usually the changes we suggest would
331
- // actually have to be applied to the *trait*
332
- // method (and it's not clear that the trait
333
- // method is even under the user's control).
334
- } else if let Some ( same_frs) = free_regions_from_same_fn ( self . tcx , sub, sup) {
335
- origins. push (
336
- ProcessedErrorOrigin :: ConcreteFailure (
337
- origin. clone ( ) ,
338
- sub,
339
- sup) ) ;
340
- append_to_same_regions ( & mut same_regions, & same_frs) ;
341
- continue ;
342
- }
343
- }
344
- SubSupConflict ( ref var_origin, ref sub_origin, sub, ref sup_origin, sup) => {
345
- debug ! ( "processing SubSupConflict sub: {:?} sup: {:?}" , sub, sup) ;
346
- match ( sub_origin, sup_origin) {
347
- ( & SubregionOrigin :: CompareImplMethodObligation { .. } , _) => {
348
- // As above, when comparing an impl method
349
- // against a trait method, it is not helpful
350
- // to suggest changes to the impl method.
351
- }
352
- ( _, & SubregionOrigin :: CompareImplMethodObligation { .. } ) => {
353
- // See above.
354
- }
355
- _ => {
356
- if let Some ( same_frs) = free_regions_from_same_fn ( self . tcx , sub, sup) {
357
- origins. push (
358
- ProcessedErrorOrigin :: VariableFailure (
359
- var_origin. clone ( ) ) ) ;
360
- append_to_same_regions ( & mut same_regions, & same_frs) ;
361
- continue ;
362
- }
363
- }
364
- }
365
- }
366
- GenericBoundFailure ( ref origin, ref kind, region) => {
367
- bound_failures. push ( ( origin. clone ( ) , kind. clone ( ) , region) ) ;
368
- continue ;
369
- }
370
- ProcessedErrors ( ..) => {
371
- bug ! ( "should not encounter a `ProcessedErrors` yet: {:?}" , error)
372
- }
373
- }
374
-
375
- // No changes to this error.
376
- other_errors. push ( error. clone ( ) ) ;
377
- }
378
-
379
- // ok, let's pull together the errors, sorted in an order that
380
- // we think will help user the best
381
- let mut processed_errors = vec ! [ ] ;
382
-
383
- // first, put the processed errors, if any
384
- if !same_regions. is_empty ( ) {
385
- let common_scope_id = same_regions[ 0 ] . scope_id ;
386
- for sr in & same_regions {
387
- // Since ProcessedErrors is used to reconstruct the function
388
- // declaration, we want to make sure that they are, in fact,
389
- // from the same scope
390
- if sr. scope_id != common_scope_id {
391
- debug ! ( "returning empty result from process_errors because
392
- {} != {}" , sr. scope_id, common_scope_id) ;
393
- return None ;
394
- }
395
- }
396
- assert ! ( origins. len( ) > 0 ) ;
397
- let pe = ProcessedErrors ( origins, same_regions) ;
398
- debug ! ( "errors processed: {:?}" , pe) ;
399
- processed_errors. push ( pe) ;
400
- }
401
-
402
- // next, put the other misc errors
403
- processed_errors. extend ( other_errors) ;
404
-
405
- // finally, put the `T: 'a` errors, but only if there were no
406
- // other errors. otherwise, these have a very high rate of
407
- // being unhelpful in practice. This is because they are
408
- // basically secondary checks that test the state of the
409
- // region graph after the rest of inference is done, and the
410
- // other kinds of errors indicate that the region constraint
411
- // graph is internally inconsistent, so these test results are
412
- // likely to be meaningless.
413
- if processed_errors. is_empty ( ) {
414
- for ( origin, kind, region) in bound_failures {
415
- processed_errors. push ( GenericBoundFailure ( origin, kind, region) ) ;
416
- }
417
- }
418
293
419
- // we should always wind up with SOME errors, unless there were no
420
- // errors to start
421
- assert ! ( if errors. len( ) > 0 { processed_errors. len( ) > 0 } else { true } ) ;
422
-
423
- return Some ( processed_errors) ;
424
-
425
- #[ derive( Debug ) ]
426
- struct FreeRegionsFromSameFn {
427
- sub_fr : ty:: FreeRegion ,
428
- sup_fr : ty:: FreeRegion ,
429
- scope_id : ast:: NodeId
430
- }
431
-
432
- impl FreeRegionsFromSameFn {
433
- fn new ( sub_fr : ty:: FreeRegion ,
434
- sup_fr : ty:: FreeRegion ,
435
- scope_id : ast:: NodeId )
436
- -> FreeRegionsFromSameFn {
437
- FreeRegionsFromSameFn {
438
- sub_fr : sub_fr,
439
- sup_fr : sup_fr,
440
- scope_id : scope_id
441
- }
442
- }
443
- }
444
-
445
- fn free_regions_from_same_fn < ' a , ' gcx , ' tcx > ( tcx : TyCtxt < ' a , ' gcx , ' tcx > ,
446
- sub : & ' tcx Region ,
447
- sup : & ' tcx Region )
448
- -> Option < FreeRegionsFromSameFn > {
449
- debug ! ( "free_regions_from_same_fn(sub={:?}, sup={:?})" , sub, sup) ;
450
- let ( scope_id, fr1, fr2) = match ( sub, sup) {
451
- ( & ReFree ( fr1) , & ReFree ( fr2) ) => {
452
- if fr1. scope != fr2. scope {
453
- return None
454
- }
455
- assert ! ( fr1. scope == fr2. scope) ;
456
- ( fr1. scope . node_id ( & tcx. region_maps ) , fr1, fr2)
457
- } ,
458
- _ => return None
459
- } ;
460
- let parent = tcx. hir . get_parent ( scope_id) ;
461
- let parent_node = tcx. hir . find ( parent) ;
462
- match parent_node {
463
- Some ( node) => match node {
464
- hir_map:: NodeItem ( item) => match item. node {
465
- hir:: ItemFn ( ..) => {
466
- Some ( FreeRegionsFromSameFn :: new ( fr1, fr2, scope_id) )
467
- } ,
468
- _ => None
469
- } ,
470
- hir_map:: NodeImplItem ( ..) |
471
- hir_map:: NodeTraitItem ( ..) => {
472
- Some ( FreeRegionsFromSameFn :: new ( fr1, fr2, scope_id) )
473
- } ,
474
- _ => None
475
- } ,
476
- None => {
477
- debug ! ( "no parent node of scope_id {}" , scope_id) ;
478
- None
479
- }
480
- }
481
- }
294
+ // We want to avoid reporting generic-bound failures if we can
295
+ // avoid it: these have a very high rate of being unhelpful in
296
+ // practice. This is because they are basically secondary
297
+ // checks that test the state of the region graph after the
298
+ // rest of inference is done, and the other kinds of errors
299
+ // indicate that the region constraint graph is internally
300
+ // inconsistent, so these test results are likely to be
301
+ // meaningless.
302
+ //
303
+ // Therefore, we filter them out of the list unless they are
304
+ // the only thing in the list.
305
+
306
+ let is_bound_failure = |e : & RegionResolutionError < ' tcx > | match * e {
307
+ ConcreteFailure ( ..) => false ,
308
+ SubSupConflict ( ..) => false ,
309
+ GenericBoundFailure ( ..) => true ,
310
+ } ;
482
311
483
- fn append_to_same_regions ( same_regions : & mut Vec < SameRegions > ,
484
- same_frs : & FreeRegionsFromSameFn ) {
485
- debug ! ( "append_to_same_regions(same_regions={:?}, same_frs={:?})" ,
486
- same_regions, same_frs) ;
487
- let scope_id = same_frs. scope_id ;
488
- let ( sub_fr, sup_fr) = ( same_frs. sub_fr , same_frs. sup_fr ) ;
489
- for sr in same_regions. iter_mut ( ) {
490
- if sr. contains ( & sup_fr. bound_region ) && scope_id == sr. scope_id {
491
- sr. push ( sub_fr. bound_region ) ;
492
- return
493
- }
494
- }
495
- same_regions. push ( SameRegions {
496
- scope_id : scope_id,
497
- regions : vec ! [ sub_fr. bound_region, sup_fr. bound_region]
498
- } )
312
+ if errors. iter ( ) . all ( |e| is_bound_failure ( e) ) {
313
+ errors. clone ( )
314
+ } else {
315
+ errors. iter ( ) . filter ( |& e| !is_bound_failure ( e) ) . cloned ( ) . collect ( )
499
316
}
500
317
}
501
318
@@ -1072,20 +889,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
1072
889
self . note_region_origin ( & mut err, & sub_origin) ;
1073
890
err. emit ( ) ;
1074
891
}
1075
-
1076
- fn report_processed_errors ( & self ,
1077
- origins : & [ ProcessedErrorOrigin < ' tcx > ] ) {
1078
- for origin in origins. iter ( ) {
1079
- let mut err = match * origin {
1080
- ProcessedErrorOrigin :: VariableFailure ( ref var_origin) =>
1081
- self . report_inference_failure ( var_origin. clone ( ) ) ,
1082
- ProcessedErrorOrigin :: ConcreteFailure ( ref sr_origin, sub, sup) =>
1083
- self . report_concrete_failure ( sr_origin. clone ( ) , sub, sup) ,
1084
- } ;
1085
-
1086
- err. emit ( ) ;
1087
- }
1088
- }
1089
892
}
1090
893
1091
894
impl < ' a , ' gcx , ' tcx > InferCtxt < ' a , ' gcx , ' tcx > {
0 commit comments