Skip to content

Commit e20fa70

Browse files
committed
suppress duplicate -- or near duplicate -- type test errors
1 parent bfb1d95 commit e20fa70

File tree

2 files changed

+27
-5
lines changed
  • src
    • librustc_mir/borrow_check/nll/region_infer
    • librustc/infer/region_constraints

2 files changed

+27
-5
lines changed

src/librustc/infer/region_constraints/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ pub struct Verify<'tcx> {
149149
pub bound: VerifyBound<'tcx>,
150150
}
151151

152-
#[derive(Copy, Clone, PartialEq, Eq)]
152+
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
153153
pub enum GenericKind<'tcx> {
154154
Param(ty::ParamTy),
155155
Projection(ty::ProjectionTy<'tcx>),

src/librustc_mir/borrow_check/nll/region_infer/mod.rs

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ use rustc::mir::{
2525
use rustc::ty::{self, RegionVid, Ty, TyCtxt, TypeFoldable};
2626
use rustc::util::common;
2727
use rustc_data_structures::bit_set::BitSet;
28-
use rustc_data_structures::fx::FxHashMap;
28+
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
2929
use rustc_data_structures::graph::scc::Sccs;
3030
use rustc_data_structures::indexed_vec::IndexVec;
3131
use rustc_errors::{Diagnostic, DiagnosticBuilder};
@@ -580,6 +580,11 @@ impl<'tcx> RegionInferenceContext<'tcx> {
580580
) {
581581
let tcx = infcx.tcx;
582582

583+
// Sometimes we register equivalent type-tests that would
584+
// result in basically the exact same error being reported to
585+
// the user. Avoid that.
586+
let mut deduplicate_errors = FxHashSet::default();
587+
583588
for type_test in &self.type_tests {
584589
debug!("check_type_test: {:?}", type_test);
585590

@@ -605,11 +610,29 @@ impl<'tcx> RegionInferenceContext<'tcx> {
605610
}
606611
}
607612

608-
// Oh the humanity. Obviously we will do better than this error eventually.
613+
// Type-test failed. Report the error.
614+
615+
// Try to convert the lower-bound region into something named we can print for the user.
609616
let lower_bound_region = self.to_error_region(type_test.lower_bound);
617+
618+
// Skip duplicate-ish errors.
619+
let type_test_span = type_test.locations.span(mir);
620+
let erased_generic_kind = tcx.erase_regions(&type_test.generic_kind);
621+
if !deduplicate_errors.insert((erased_generic_kind, lower_bound_region, type_test.locations)) {
622+
continue;
623+
} else {
624+
debug!(
625+
"check_type_test: reporting error for erased_generic_kind={:?}, \
626+
lower_bound_region={:?}, \
627+
type_test.locations={:?}",
628+
erased_generic_kind,
629+
lower_bound_region,
630+
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

Comments
 (0)