From c0c6603c79280c34aeba14fea1a5cd3d0e8275eb Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 17 Aug 2022 02:22:06 +0000 Subject: [PATCH] Deduplicate errors that come from places like normalization, sized --- .../rustc_typeck/src/check/fn_ctxt/checks.rs | 62 ++++++++++++++----- src/test/ui/iterators/issue-28098.stderr | 34 +--------- .../ui/on-unimplemented/multiple-impls.stderr | 35 +---------- src/test/ui/on-unimplemented/on-impl.stderr | 11 +--- src/test/ui/str/str-idx.stderr | 24 +------ src/test/ui/str/str-mut-idx.stderr | 24 +------ .../mut-borrow-needed-by-trait.stderr | 15 +---- 7 files changed, 53 insertions(+), 152 deletions(-) diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs index 182e69d2aae..7c4d812a1b6 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs @@ -15,6 +15,7 @@ use crate::check::{ use crate::structured_errors::StructuredDiagnostic; use rustc_ast as ast; +use rustc_data_structures::fx::FxHashSet; use rustc_errors::{pluralize, Applicability, Diagnostic, DiagnosticId, MultiSpan}; use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind, Res}; @@ -1612,24 +1613,52 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &self, errors: &mut Vec>, ) { + let mut remap_cause = FxHashSet::default(); + let mut not_adjusted = vec![]; + for error in errors { - self.adjust_fulfillment_error_for_expr_obligation(error); + let before_span = error.obligation.cause.span; + if self.adjust_fulfillment_error_for_expr_obligation(error) { + remap_cause.insert(( + before_span, + error.obligation.predicate, + error.obligation.cause.clone(), + )); + remap_cause.insert(( + before_span, + error.obligation.predicate.without_const(self.tcx), + error.obligation.cause.clone(), + )); + } else { + not_adjusted.push(error); + } + } + + for error in not_adjusted { + for (span, predicate, cause) in &remap_cause { + if *predicate == error.obligation.predicate + && span.contains(error.obligation.cause.span) + { + error.obligation.cause = cause.clone(); + continue; + } + } } } fn adjust_fulfillment_error_for_expr_obligation( &self, error: &mut traits::FulfillmentError<'tcx>, - ) { + ) -> bool { let (traits::ExprItemObligation(def_id, hir_id, idx) | traits::ExprBindingObligation(def_id, _, hir_id, idx)) - = *error.obligation.cause.code().peel_derives() else { return; }; + = *error.obligation.cause.code().peel_derives() else { return false; }; // Skip over mentioning async lang item if Some(def_id) == self.tcx.lang_items().from_generator_fn() && error.obligation.cause.span.desugaring_kind() == Some(rustc_span::DesugaringKind::Async) { - return; + return false; } // Skip over closure arg mismatch, which has a better heuristic // to determine what span to point at. @@ -1638,11 +1667,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) = error.code && let ty::Closure(..) | ty::Generator(..) = expected.skip_binder().self_ty().kind() { - return; + return false; } let Some(unsubstituted_pred) = - self.tcx.predicates_of(def_id).instantiate_identity(self.tcx).predicates.into_iter().nth(idx) else { return; }; + self.tcx.predicates_of(def_id).instantiate_identity(self.tcx).predicates.into_iter().nth(idx) + else { return false; }; let generics = self.tcx.generics_of(def_id); let predicate_substs = match unsubstituted_pred.kind().skip_binder() { @@ -1709,19 +1739,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { if let Some(param_to_point_at) = param_to_point_at && self.point_at_args_if_possible(error, def_id, param_to_point_at, *call_hir_id, callee.span, args) { - return; + return true; } if let Some(fallback_param_to_point_at) = fallback_param_to_point_at && self.point_at_args_if_possible(error, def_id, fallback_param_to_point_at, *call_hir_id, callee.span, args) { - return; + return true; } if let Some(self_param_to_point_at) = self_param_to_point_at && self.point_at_args_if_possible(error, def_id, self_param_to_point_at, *call_hir_id, callee.span, args) { - return; + return true; } if let hir::QPath::Resolved(_, path) = qpath @@ -1729,14 +1759,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && let Some(segment) = path.segments.last() && self.point_at_generics_if_possible(error, def_id, param_to_point_at, segment) { - return; + return true; } if let hir::QPath::TypeRelative(_, segment) = qpath && let Some(param_to_point_at) = param_to_point_at && self.point_at_generics_if_possible(error, def_id, param_to_point_at, segment) { - return; + return true; } } } @@ -1744,25 +1774,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let Some(param_to_point_at) = param_to_point_at && self.point_at_args_if_possible(error, def_id, param_to_point_at, hir_id, segment.ident.span, args) { - return; + return true; } if let Some(fallback_param_to_point_at) = fallback_param_to_point_at && self.point_at_args_if_possible(error, def_id, fallback_param_to_point_at, hir_id, segment.ident.span, args) { - return; + return true; } if let Some(self_param_to_point_at) = self_param_to_point_at && self.point_at_args_if_possible(error, def_id, self_param_to_point_at, hir_id, segment.ident.span, args) { - return; + return true; } if let Some(param_to_point_at) = param_to_point_at && self.point_at_generics_if_possible(error, def_id, param_to_point_at, segment) { - return; + return true; } } hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Struct(..), .. }) => { @@ -1770,6 +1800,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } _ => {} } + + false } fn find_ambiguous_parameter_in>( diff --git a/src/test/ui/iterators/issue-28098.stderr b/src/test/ui/iterators/issue-28098.stderr index 542807fb91c..53b610c1723 100644 --- a/src/test/ui/iterators/issue-28098.stderr +++ b/src/test/ui/iterators/issue-28098.stderr @@ -8,14 +8,6 @@ LL | let _ = Iterator::next(&mut ()); | = help: the trait `Iterator` is not implemented for `()` -error[E0277]: `()` is not an iterator - --> $DIR/issue-28098.rs:2:13 - | -LL | let _ = Iterator::next(&mut ()); - | ^^^^^^^^^^^^^^ `()` is not an iterator - | - = help: the trait `Iterator` is not implemented for `()` - error[E0277]: `bool` is not an iterator --> $DIR/issue-28098.rs:5:14 | @@ -35,14 +27,6 @@ LL | let _ = Iterator::next(&mut ()); | = help: the trait `Iterator` is not implemented for `()` -error[E0277]: `()` is not an iterator - --> $DIR/issue-28098.rs:8:13 - | -LL | let _ = Iterator::next(&mut ()); - | ^^^^^^^^^^^^^^ `()` is not an iterator - | - = help: the trait `Iterator` is not implemented for `()` - error[E0277]: `()` is not an iterator --> $DIR/issue-28098.rs:17:28 | @@ -53,14 +37,6 @@ LL | let _ = Iterator::next(&mut ()); | = help: the trait `Iterator` is not implemented for `()` -error[E0277]: `()` is not an iterator - --> $DIR/issue-28098.rs:17:13 - | -LL | let _ = Iterator::next(&mut ()); - | ^^^^^^^^^^^^^^ `()` is not an iterator - | - = help: the trait `Iterator` is not implemented for `()` - error[E0277]: `()` is not an iterator --> $DIR/issue-28098.rs:20:28 | @@ -71,14 +47,6 @@ LL | let _ = Iterator::next(&mut ()); | = help: the trait `Iterator` is not implemented for `()` -error[E0277]: `()` is not an iterator - --> $DIR/issue-28098.rs:20:13 - | -LL | let _ = Iterator::next(&mut ()); - | ^^^^^^^^^^^^^^ `()` is not an iterator - | - = help: the trait `Iterator` is not implemented for `()` - error[E0277]: `bool` is not an iterator --> $DIR/issue-28098.rs:23:14 | @@ -88,6 +56,6 @@ LL | for _ in false {} = help: the trait `Iterator` is not implemented for `bool` = note: required for `bool` to implement `IntoIterator` -error: aborting due to 10 previous errors +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/on-unimplemented/multiple-impls.stderr b/src/test/ui/on-unimplemented/multiple-impls.stderr index 8b94c8545ff..d47a398412f 100644 --- a/src/test/ui/on-unimplemented/multiple-impls.stderr +++ b/src/test/ui/on-unimplemented/multiple-impls.stderr @@ -11,17 +11,6 @@ LL | Index::index(&[] as &[i32], 2u32); <[i32] as Index>> <[i32] as Index>> -error[E0277]: the trait bound `[i32]: Index` is not satisfied - --> $DIR/multiple-impls.rs:33:5 - | -LL | Index::index(&[] as &[i32], 2u32); - | ^^^^^^^^^^^^ trait message - | - = help: the trait `Index` is not implemented for `[i32]` - = help: the following other types implement trait `Index`: - <[i32] as Index>> - <[i32] as Index>> - error[E0277]: the trait bound `[i32]: Index>` is not satisfied --> $DIR/multiple-impls.rs:35:33 | @@ -35,17 +24,6 @@ LL | Index::index(&[] as &[i32], Foo(2u32)); <[i32] as Index>> <[i32] as Index>> -error[E0277]: the trait bound `[i32]: Index>` is not satisfied - --> $DIR/multiple-impls.rs:35:5 - | -LL | Index::index(&[] as &[i32], Foo(2u32)); - | ^^^^^^^^^^^^ on impl for Foo - | - = help: the trait `Index>` is not implemented for `[i32]` - = help: the following other types implement trait `Index`: - <[i32] as Index>> - <[i32] as Index>> - error[E0277]: the trait bound `[i32]: Index>` is not satisfied --> $DIR/multiple-impls.rs:37:33 | @@ -59,17 +37,6 @@ LL | Index::index(&[] as &[i32], Bar(2u32)); <[i32] as Index>> <[i32] as Index>> -error[E0277]: the trait bound `[i32]: Index>` is not satisfied - --> $DIR/multiple-impls.rs:37:5 - | -LL | Index::index(&[] as &[i32], Bar(2u32)); - | ^^^^^^^^^^^^ on impl for Bar - | - = help: the trait `Index>` is not implemented for `[i32]` - = help: the following other types implement trait `Index`: - <[i32] as Index>> - <[i32] as Index>> - -error: aborting due to 6 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/on-unimplemented/on-impl.stderr b/src/test/ui/on-unimplemented/on-impl.stderr index 46902ad30a5..01315b85409 100644 --- a/src/test/ui/on-unimplemented/on-impl.stderr +++ b/src/test/ui/on-unimplemented/on-impl.stderr @@ -9,15 +9,6 @@ LL | Index::::index(&[1, 2, 3] as &[i32], 2u32); = help: the trait `Index` is not implemented for `[i32]` = help: the trait `Index` is implemented for `[i32]` -error[E0277]: the trait bound `[i32]: Index` is not satisfied - --> $DIR/on-impl.rs:22:5 - | -LL | Index::::index(&[1, 2, 3] as &[i32], 2u32); - | ^^^^^^^^^^^^^^^^^^^ a usize is required to index into a slice - | - = help: the trait `Index` is not implemented for `[i32]` - = help: the trait `Index` is implemented for `[i32]` - -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/str/str-idx.stderr b/src/test/ui/str/str-idx.stderr index 6daa74657bd..019305def29 100644 --- a/src/test/ui/str/str-idx.stderr +++ b/src/test/ui/str/str-idx.stderr @@ -28,17 +28,6 @@ note: required by a bound in `core::str::::get` LL | pub const fn get>(&self, i: I) -> Option<&I::Output> { | ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `core::str::::get` -error[E0277]: the type `str` cannot be indexed by `{integer}` - --> $DIR/str-idx.rs:4:15 - | -LL | let _ = s.get(4); - | ^^^ string indices are ranges of `usize` - | - = help: the trait `SliceIndex` is not implemented for `{integer}` - = note: you can use `.chars().nth()` or `.bytes().nth()` - for more information, see chapter 8 in The Book: - = help: the trait `SliceIndex<[T]>` is implemented for `usize` - error[E0277]: the type `str` cannot be indexed by `{integer}` --> $DIR/str-idx.rs:5:29 | @@ -57,17 +46,6 @@ note: required by a bound in `core::str::::get_unchecked` LL | pub const unsafe fn get_unchecked>(&self, i: I) -> &I::Output { | ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `core::str::::get_unchecked` -error[E0277]: the type `str` cannot be indexed by `{integer}` - --> $DIR/str-idx.rs:5:15 - | -LL | let _ = s.get_unchecked(4); - | ^^^^^^^^^^^^^ string indices are ranges of `usize` - | - = help: the trait `SliceIndex` is not implemented for `{integer}` - = note: you can use `.chars().nth()` or `.bytes().nth()` - for more information, see chapter 8 in The Book: - = help: the trait `SliceIndex<[T]>` is implemented for `usize` - error[E0277]: the type `str` cannot be indexed by `char` --> $DIR/str-idx.rs:6:19 | @@ -77,6 +55,6 @@ LL | let _: u8 = s['c']; = help: the trait `SliceIndex` is not implemented for `char` = note: required for `str` to implement `Index` -error: aborting due to 6 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/str/str-mut-idx.stderr b/src/test/ui/str/str-mut-idx.stderr index d063088aded..b165c482590 100644 --- a/src/test/ui/str/str-mut-idx.stderr +++ b/src/test/ui/str/str-mut-idx.stderr @@ -52,17 +52,6 @@ note: required by a bound in `core::str::::get_mut` LL | pub const fn get_mut>(&mut self, i: I) -> Option<&mut I::Output> { | ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `core::str::::get_mut` -error[E0277]: the type `str` cannot be indexed by `{integer}` - --> $DIR/str-mut-idx.rs:9:7 - | -LL | s.get_mut(1); - | ^^^^^^^ string indices are ranges of `usize` - | - = help: the trait `SliceIndex` is not implemented for `{integer}` - = note: you can use `.chars().nth()` or `.bytes().nth()` - for more information, see chapter 8 in The Book: - = help: the trait `SliceIndex<[T]>` is implemented for `usize` - error[E0277]: the type `str` cannot be indexed by `{integer}` --> $DIR/str-mut-idx.rs:11:25 | @@ -81,17 +70,6 @@ note: required by a bound in `core::str::::get_unchecked_mut` LL | pub const unsafe fn get_unchecked_mut>( | ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `core::str::::get_unchecked_mut` -error[E0277]: the type `str` cannot be indexed by `{integer}` - --> $DIR/str-mut-idx.rs:11:7 - | -LL | s.get_unchecked_mut(1); - | ^^^^^^^^^^^^^^^^^ string indices are ranges of `usize` - | - = help: the trait `SliceIndex` is not implemented for `{integer}` - = note: you can use `.chars().nth()` or `.bytes().nth()` - for more information, see chapter 8 in The Book: - = help: the trait `SliceIndex<[T]>` is implemented for `usize` - error[E0277]: the type `str` cannot be indexed by `char` --> $DIR/str-mut-idx.rs:13:7 | @@ -101,6 +79,6 @@ LL | s['c']; = help: the trait `SliceIndex` is not implemented for `char` = note: required for `str` to implement `Index` -error: aborting due to 8 previous errors +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/suggestions/mut-borrow-needed-by-trait.stderr b/src/test/ui/suggestions/mut-borrow-needed-by-trait.stderr index 0aa22f9fe8d..d121932c842 100644 --- a/src/test/ui/suggestions/mut-borrow-needed-by-trait.stderr +++ b/src/test/ui/suggestions/mut-borrow-needed-by-trait.stderr @@ -13,19 +13,6 @@ note: required by a bound in `BufWriter::::new` LL | impl BufWriter { | ^^^^^ required by this bound in `BufWriter::::new` -error[E0277]: the trait bound `&dyn std::io::Write: std::io::Write` is not satisfied - --> $DIR/mut-borrow-needed-by-trait.rs:17:14 - | -LL | let fp = BufWriter::new(fp); - | ^^^^^^^^^ the trait `std::io::Write` is not implemented for `&dyn std::io::Write` - | - = note: `std::io::Write` is implemented for `&mut dyn std::io::Write`, but not for `&dyn std::io::Write` -note: required by a bound in `BufWriter` - --> $SRC_DIR/std/src/io/buffered/bufwriter.rs:LL:COL - | -LL | pub struct BufWriter { - | ^^^^^ required by this bound in `BufWriter` - error[E0277]: the trait bound `&dyn std::io::Write: std::io::Write` is not satisfied --> $DIR/mut-borrow-needed-by-trait.rs:17:14 | @@ -55,7 +42,7 @@ LL | pub struct BufWriter { which is required by `BufWriter<&dyn std::io::Write>: std::io::Write` = note: this error originates in the macro `writeln` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors Some errors have detailed explanations: E0277, E0599. For more information about an error, try `rustc --explain E0277`.