@@ -65,9 +65,6 @@ use super::region_inference::ConcreteFailure;
6565use super :: region_inference:: SubSupConflict ;
6666use super :: region_inference:: GenericBoundFailure ;
6767use super :: region_inference:: GenericKind ;
68- use super :: region_inference:: ProcessedErrors ;
69- use super :: region_inference:: ProcessedErrorOrigin ;
70- use super :: region_inference:: SameRegions ;
7168
7269use hir:: map as hir_map;
7370use hir;
@@ -78,12 +75,12 @@ use infer;
7875use middle:: region;
7976use traits:: { ObligationCause , ObligationCauseCode } ;
8077use ty:: { self , TyCtxt , TypeFoldable } ;
81- use ty:: { Region , ReFree } ;
78+ use ty:: Region ;
8279use ty:: error:: TypeError ;
8380
8481use std:: fmt;
85- use syntax:: ast;
8682use syntax_pos:: { Pos , Span } ;
83+ use syntax:: ast;
8784use errors:: DiagnosticBuilder ;
8885
8986impl < ' a , ' gcx , ' tcx > TyCtxt < ' a , ' gcx , ' tcx > {
@@ -256,8 +253,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
256253
257254 // try to pre-process the errors, which will group some of them
258255 // 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) ;
261257
262258 debug ! ( "report_region_errors: {} errors after preprocessing" , errors. len( ) ) ;
263259
@@ -279,13 +275,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
279275 sub_origin, sub_r,
280276 sup_origin, sup_r) ;
281277 }
282-
283- ProcessedErrors ( ref origins,
284- ref same_regions) => {
285- if !same_regions. is_empty ( ) {
286- self . report_processed_errors ( origins) ;
287- }
288- }
289278 }
290279 }
291280 }
@@ -301,202 +290,31 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
301290 // duplicates that will be unhelpful to the end-user. But
302291 // obviously it never weeds out ALL errors.
303292 fn process_errors ( & self , errors : & Vec < RegionResolutionError < ' tcx > > )
304- -> Option < Vec < RegionResolutionError < ' tcx > > > {
293+ -> Vec < RegionResolutionError < ' tcx > > {
305294 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- }
445295
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+ } ;
483313
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 ( )
500318 }
501319 }
502320
@@ -1040,20 +858,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
1040858 err. emit ( ) ;
1041859 }
1042860
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-
1057861 pub fn issue_32330_warnings ( & self , span : Span , issue32330s : & [ ty:: Issue32330 ] ) {
1058862 for issue32330 in issue32330s {
1059863 match * issue32330 {
0 commit comments