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