about summary refs log tree commit diff
path: root/src/librustc_mir/borrow_check
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2018-10-18 09:00:11 -0400
committerNiko Matsakis <niko@alum.mit.edu>2018-10-19 09:34:28 -0400
commite20fa70bb349026226616b92ea44f7bdfd270d75 (patch)
tree485403f6d182cba48565675e2fefdba395235493 /src/librustc_mir/borrow_check
parentbfb1d959c3cc64d54d1a1f3d586d90b6ce0d5357 (diff)
downloadrust-e20fa70bb349026226616b92ea44f7bdfd270d75.tar.gz
rust-e20fa70bb349026226616b92ea44f7bdfd270d75.zip
suppress duplicate -- or near duplicate -- type test errors
Diffstat (limited to 'src/librustc_mir/borrow_check')
-rw-r--r--src/librustc_mir/borrow_check/nll/region_infer/mod.rs30
1 files changed, 26 insertions, 4 deletions
diff --git a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs
index 0fabcfe4564..95b3943746d 100644
--- a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs
@@ -25,7 +25,7 @@ use rustc::mir::{
 use rustc::ty::{self, RegionVid, Ty, TyCtxt, TypeFoldable};
 use rustc::util::common;
 use rustc_data_structures::bit_set::BitSet;
-use rustc_data_structures::fx::FxHashMap;
+use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_data_structures::graph::scc::Sccs;
 use rustc_data_structures::indexed_vec::IndexVec;
 use rustc_errors::{Diagnostic, DiagnosticBuilder};
@@ -580,6 +580,11 @@ impl<'tcx> RegionInferenceContext<'tcx> {
     ) {
         let tcx = infcx.tcx;
 
+        // Sometimes we register equivalent type-tests that would
+        // result in basically the exact same error being reported to
+        // the user. Avoid that.
+        let mut deduplicate_errors = FxHashSet::default();
+
         for type_test in &self.type_tests {
             debug!("check_type_test: {:?}", type_test);
 
@@ -605,11 +610,29 @@ impl<'tcx> RegionInferenceContext<'tcx> {
                 }
             }
 
-            // Oh the humanity. Obviously we will do better than this error eventually.
+            // Type-test failed. Report the error.
+
+            // Try to convert the lower-bound region into something named we can print for the user.
             let lower_bound_region = self.to_error_region(type_test.lower_bound);
+
+            // Skip duplicate-ish errors.
+            let type_test_span = type_test.locations.span(mir);
+            let erased_generic_kind = tcx.erase_regions(&type_test.generic_kind);
+            if !deduplicate_errors.insert((erased_generic_kind, lower_bound_region, type_test.locations)) {
+                continue;
+            } else {
+                debug!(
+                    "check_type_test: reporting error for erased_generic_kind={:?}, \
+                     lower_bound_region={:?}, \
+                     type_test.locations={:?}",
+                    erased_generic_kind,
+                    lower_bound_region,
+                    type_test.locations,
+                );
+            }
+
             if let Some(lower_bound_region) = lower_bound_region {
                 let region_scope_tree = &tcx.region_scope_tree(mir_def_id);
-                let type_test_span = type_test.locations.span(mir);
                 infcx
                     .construct_generic_bound_failure(
                         region_scope_tree,
@@ -629,7 +652,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
                 // to report it; we could probably handle it by
                 // iterating over the universal regions and reporting
                 // an error that multiple bounds are required.
-                let type_test_span = type_test.locations.span(mir);
                 tcx.sess
                     .struct_span_err(
                         type_test_span,