@@ -25,7 +25,7 @@ use rustc::mir::{
2525use rustc:: ty:: { self , RegionVid , Ty , TyCtxt , TypeFoldable } ;
2626use rustc:: util:: common;
2727use rustc_data_structures:: bit_set:: BitSet ;
28- use rustc_data_structures:: fx:: FxHashMap ;
28+ use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
2929use rustc_data_structures:: graph:: scc:: Sccs ;
3030use rustc_data_structures:: indexed_vec:: IndexVec ;
3131use rustc_errors:: { Diagnostic , DiagnosticBuilder } ;
@@ -67,10 +67,8 @@ pub struct RegionInferenceContext<'tcx> {
6767 constraint_sccs : Rc < Sccs < RegionVid , ConstraintSccIndex > > ,
6868
6969 /// Map closure bounds to a `Span` that should be used for error reporting.
70- closure_bounds_mapping : FxHashMap <
71- Location ,
72- FxHashMap < ( RegionVid , RegionVid ) , ( ConstraintCategory , Span ) > ,
73- > ,
70+ closure_bounds_mapping :
71+ FxHashMap < Location , FxHashMap < ( RegionVid , RegionVid ) , ( ConstraintCategory , Span ) > > ,
7472
7573 /// Contains the minimum universe of any variable within the same
7674 /// SCC. We will ensure that no SCC contains values that are not
@@ -580,6 +578,11 @@ impl<'tcx> RegionInferenceContext<'tcx> {
580578 ) {
581579 let tcx = infcx. tcx ;
582580
581+ // Sometimes we register equivalent type-tests that would
582+ // result in basically the exact same error being reported to
583+ // the user. Avoid that.
584+ let mut deduplicate_errors = FxHashSet :: default ( ) ;
585+
583586 for type_test in & self . type_tests {
584587 debug ! ( "check_type_test: {:?}" , type_test) ;
585588
@@ -605,11 +608,31 @@ impl<'tcx> RegionInferenceContext<'tcx> {
605608 }
606609 }
607610
608- // Oh the humanity. Obviously we will do better than this error eventually.
611+ // Type-test failed. Report the error.
612+
613+ // Try to convert the lower-bound region into something named we can print for the user.
609614 let lower_bound_region = self . to_error_region ( type_test. lower_bound ) ;
615+
616+ // Skip duplicate-ish errors.
617+ let type_test_span = type_test. locations . span ( mir) ;
618+ let erased_generic_kind = tcx. erase_regions ( & type_test. generic_kind ) ;
619+ if !deduplicate_errors. insert ( (
620+ erased_generic_kind,
621+ lower_bound_region,
622+ type_test. locations ,
623+ ) ) {
624+ continue ;
625+ } else {
626+ debug ! (
627+ "check_type_test: reporting error for erased_generic_kind={:?}, \
628+ lower_bound_region={:?}, \
629+ type_test.locations={:?}",
630+ erased_generic_kind, lower_bound_region, type_test. locations,
631+ ) ;
632+ }
633+
610634 if let Some ( lower_bound_region) = lower_bound_region {
611635 let region_scope_tree = & tcx. region_scope_tree ( mir_def_id) ;
612- let type_test_span = type_test. locations . span ( mir) ;
613636 infcx
614637 . construct_generic_bound_failure (
615638 region_scope_tree,
@@ -629,7 +652,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
629652 // to report it; we could probably handle it by
630653 // iterating over the universal regions and reporting
631654 // an error that multiple bounds are required.
632- let type_test_span = type_test. locations . span ( mir) ;
633655 tcx. sess
634656 . struct_span_err (
635657 type_test_span,
0 commit comments