diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2018-10-18 09:00:11 -0400 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2018-10-19 09:34:28 -0400 |
| commit | e20fa70bb349026226616b92ea44f7bdfd270d75 (patch) | |
| tree | 485403f6d182cba48565675e2fefdba395235493 /src/librustc_mir | |
| parent | bfb1d959c3cc64d54d1a1f3d586d90b6ce0d5357 (diff) | |
| download | rust-e20fa70bb349026226616b92ea44f7bdfd270d75.tar.gz rust-e20fa70bb349026226616b92ea44f7bdfd270d75.zip | |
suppress duplicate -- or near duplicate -- type test errors
Diffstat (limited to 'src/librustc_mir')
| -rw-r--r-- | src/librustc_mir/borrow_check/nll/region_infer/mod.rs | 30 |
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, |
