Skip to content

Commit c0c6603

Browse files
Deduplicate errors that come from places like normalization, sized
1 parent 24559ce commit c0c6603

File tree

7 files changed

+53
-152
lines changed

7 files changed

+53
-152
lines changed

compiler/rustc_typeck/src/check/fn_ctxt/checks.rs

Lines changed: 47 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use crate::check::{
1515
use crate::structured_errors::StructuredDiagnostic;
1616

1717
use rustc_ast as ast;
18+
use rustc_data_structures::fx::FxHashSet;
1819
use rustc_errors::{pluralize, Applicability, Diagnostic, DiagnosticId, MultiSpan};
1920
use rustc_hir as hir;
2021
use rustc_hir::def::{CtorOf, DefKind, Res};
@@ -1612,24 +1613,52 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
16121613
&self,
16131614
errors: &mut Vec<traits::FulfillmentError<'tcx>>,
16141615
) {
1616+
let mut remap_cause = FxHashSet::default();
1617+
let mut not_adjusted = vec![];
1618+
16151619
for error in errors {
1616-
self.adjust_fulfillment_error_for_expr_obligation(error);
1620+
let before_span = error.obligation.cause.span;
1621+
if self.adjust_fulfillment_error_for_expr_obligation(error) {
1622+
remap_cause.insert((
1623+
before_span,
1624+
error.obligation.predicate,
1625+
error.obligation.cause.clone(),
1626+
));
1627+
remap_cause.insert((
1628+
before_span,
1629+
error.obligation.predicate.without_const(self.tcx),
1630+
error.obligation.cause.clone(),
1631+
));
1632+
} else {
1633+
not_adjusted.push(error);
1634+
}
1635+
}
1636+
1637+
for error in not_adjusted {
1638+
for (span, predicate, cause) in &remap_cause {
1639+
if *predicate == error.obligation.predicate
1640+
&& span.contains(error.obligation.cause.span)
1641+
{
1642+
error.obligation.cause = cause.clone();
1643+
continue;
1644+
}
1645+
}
16171646
}
16181647
}
16191648

16201649
fn adjust_fulfillment_error_for_expr_obligation(
16211650
&self,
16221651
error: &mut traits::FulfillmentError<'tcx>,
1623-
) {
1652+
) -> bool {
16241653
let (traits::ExprItemObligation(def_id, hir_id, idx) | traits::ExprBindingObligation(def_id, _, hir_id, idx))
1625-
= *error.obligation.cause.code().peel_derives() else { return; };
1654+
= *error.obligation.cause.code().peel_derives() else { return false; };
16261655

16271656
// Skip over mentioning async lang item
16281657
if Some(def_id) == self.tcx.lang_items().from_generator_fn()
16291658
&& error.obligation.cause.span.desugaring_kind()
16301659
== Some(rustc_span::DesugaringKind::Async)
16311660
{
1632-
return;
1661+
return false;
16331662
}
16341663
// Skip over closure arg mismatch, which has a better heuristic
16351664
// to determine what span to point at.
@@ -1638,11 +1667,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
16381667
) = error.code
16391668
&& let ty::Closure(..) | ty::Generator(..) = expected.skip_binder().self_ty().kind()
16401669
{
1641-
return;
1670+
return false;
16421671
}
16431672

16441673
let Some(unsubstituted_pred) =
1645-
self.tcx.predicates_of(def_id).instantiate_identity(self.tcx).predicates.into_iter().nth(idx) else { return; };
1674+
self.tcx.predicates_of(def_id).instantiate_identity(self.tcx).predicates.into_iter().nth(idx)
1675+
else { return false; };
16461676

16471677
let generics = self.tcx.generics_of(def_id);
16481678
let predicate_substs = match unsubstituted_pred.kind().skip_binder() {
@@ -1709,67 +1739,69 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
17091739
{
17101740
if let Some(param_to_point_at) = param_to_point_at
17111741
&& self.point_at_args_if_possible(error, def_id, param_to_point_at, *call_hir_id, callee.span, args) {
1712-
return;
1742+
return true;
17131743
}
17141744

17151745
if let Some(fallback_param_to_point_at) = fallback_param_to_point_at
17161746
&& self.point_at_args_if_possible(error, def_id, fallback_param_to_point_at, *call_hir_id, callee.span, args)
17171747
{
1718-
return;
1748+
return true;
17191749
}
17201750

17211751
if let Some(self_param_to_point_at) = self_param_to_point_at
17221752
&& self.point_at_args_if_possible(error, def_id, self_param_to_point_at, *call_hir_id, callee.span, args)
17231753
{
1724-
return;
1754+
return true;
17251755
}
17261756

17271757
if let hir::QPath::Resolved(_, path) = qpath
17281758
&& let Some(param_to_point_at) = param_to_point_at
17291759
&& let Some(segment) = path.segments.last()
17301760
&& self.point_at_generics_if_possible(error, def_id, param_to_point_at, segment)
17311761
{
1732-
return;
1762+
return true;
17331763
}
17341764

17351765
if let hir::QPath::TypeRelative(_, segment) = qpath
17361766
&& let Some(param_to_point_at) = param_to_point_at
17371767
&& self.point_at_generics_if_possible(error, def_id, param_to_point_at, segment)
17381768
{
1739-
return;
1769+
return true;
17401770
}
17411771
}
17421772
}
17431773
hir::Node::Expr(hir::Expr { kind: hir::ExprKind::MethodCall(segment, args, ..), .. }) => {
17441774
if let Some(param_to_point_at) = param_to_point_at
17451775
&& self.point_at_args_if_possible(error, def_id, param_to_point_at, hir_id, segment.ident.span, args)
17461776
{
1747-
return;
1777+
return true;
17481778
}
17491779

17501780
if let Some(fallback_param_to_point_at) = fallback_param_to_point_at
17511781
&& self.point_at_args_if_possible(error, def_id, fallback_param_to_point_at, hir_id, segment.ident.span, args)
17521782
{
1753-
return;
1783+
return true;
17541784
}
17551785

17561786
if let Some(self_param_to_point_at) = self_param_to_point_at
17571787
&& self.point_at_args_if_possible(error, def_id, self_param_to_point_at, hir_id, segment.ident.span, args)
17581788
{
1759-
return;
1789+
return true;
17601790
}
17611791

17621792
if let Some(param_to_point_at) = param_to_point_at
17631793
&& self.point_at_generics_if_possible(error, def_id, param_to_point_at, segment)
17641794
{
1765-
return;
1795+
return true;
17661796
}
17671797
}
17681798
hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Struct(..), .. }) => {
17691799
// fixme
17701800
}
17711801
_ => {}
17721802
}
1803+
1804+
false
17731805
}
17741806

17751807
fn find_ambiguous_parameter_in<T: TypeVisitable<'tcx>>(

src/test/ui/iterators/issue-28098.stderr

Lines changed: 1 addition & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,6 @@ LL | let _ = Iterator::next(&mut ());
88
|
99
= help: the trait `Iterator` is not implemented for `()`
1010

11-
error[E0277]: `()` is not an iterator
12-
--> $DIR/issue-28098.rs:2:13
13-
|
14-
LL | let _ = Iterator::next(&mut ());
15-
| ^^^^^^^^^^^^^^ `()` is not an iterator
16-
|
17-
= help: the trait `Iterator` is not implemented for `()`
18-
1911
error[E0277]: `bool` is not an iterator
2012
--> $DIR/issue-28098.rs:5:14
2113
|
@@ -35,14 +27,6 @@ LL | let _ = Iterator::next(&mut ());
3527
|
3628
= help: the trait `Iterator` is not implemented for `()`
3729

38-
error[E0277]: `()` is not an iterator
39-
--> $DIR/issue-28098.rs:8:13
40-
|
41-
LL | let _ = Iterator::next(&mut ());
42-
| ^^^^^^^^^^^^^^ `()` is not an iterator
43-
|
44-
= help: the trait `Iterator` is not implemented for `()`
45-
4630
error[E0277]: `()` is not an iterator
4731
--> $DIR/issue-28098.rs:17:28
4832
|
@@ -53,14 +37,6 @@ LL | let _ = Iterator::next(&mut ());
5337
|
5438
= help: the trait `Iterator` is not implemented for `()`
5539

56-
error[E0277]: `()` is not an iterator
57-
--> $DIR/issue-28098.rs:17:13
58-
|
59-
LL | let _ = Iterator::next(&mut ());
60-
| ^^^^^^^^^^^^^^ `()` is not an iterator
61-
|
62-
= help: the trait `Iterator` is not implemented for `()`
63-
6440
error[E0277]: `()` is not an iterator
6541
--> $DIR/issue-28098.rs:20:28
6642
|
@@ -71,14 +47,6 @@ LL | let _ = Iterator::next(&mut ());
7147
|
7248
= help: the trait `Iterator` is not implemented for `()`
7349

74-
error[E0277]: `()` is not an iterator
75-
--> $DIR/issue-28098.rs:20:13
76-
|
77-
LL | let _ = Iterator::next(&mut ());
78-
| ^^^^^^^^^^^^^^ `()` is not an iterator
79-
|
80-
= help: the trait `Iterator` is not implemented for `()`
81-
8250
error[E0277]: `bool` is not an iterator
8351
--> $DIR/issue-28098.rs:23:14
8452
|
@@ -88,6 +56,6 @@ LL | for _ in false {}
8856
= help: the trait `Iterator` is not implemented for `bool`
8957
= note: required for `bool` to implement `IntoIterator`
9058

91-
error: aborting due to 10 previous errors
59+
error: aborting due to 6 previous errors
9260

9361
For more information about this error, try `rustc --explain E0277`.

src/test/ui/on-unimplemented/multiple-impls.stderr

Lines changed: 1 addition & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,6 @@ LL | Index::index(&[] as &[i32], 2u32);
1111
<[i32] as Index<Bar<usize>>>
1212
<[i32] as Index<Foo<usize>>>
1313

14-
error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied
15-
--> $DIR/multiple-impls.rs:33:5
16-
|
17-
LL | Index::index(&[] as &[i32], 2u32);
18-
| ^^^^^^^^^^^^ trait message
19-
|
20-
= help: the trait `Index<u32>` is not implemented for `[i32]`
21-
= help: the following other types implement trait `Index<Idx>`:
22-
<[i32] as Index<Bar<usize>>>
23-
<[i32] as Index<Foo<usize>>>
24-
2514
error[E0277]: the trait bound `[i32]: Index<Foo<u32>>` is not satisfied
2615
--> $DIR/multiple-impls.rs:35:33
2716
|
@@ -35,17 +24,6 @@ LL | Index::index(&[] as &[i32], Foo(2u32));
3524
<[i32] as Index<Bar<usize>>>
3625
<[i32] as Index<Foo<usize>>>
3726

38-
error[E0277]: the trait bound `[i32]: Index<Foo<u32>>` is not satisfied
39-
--> $DIR/multiple-impls.rs:35:5
40-
|
41-
LL | Index::index(&[] as &[i32], Foo(2u32));
42-
| ^^^^^^^^^^^^ on impl for Foo
43-
|
44-
= help: the trait `Index<Foo<u32>>` is not implemented for `[i32]`
45-
= help: the following other types implement trait `Index<Idx>`:
46-
<[i32] as Index<Bar<usize>>>
47-
<[i32] as Index<Foo<usize>>>
48-
4927
error[E0277]: the trait bound `[i32]: Index<Bar<u32>>` is not satisfied
5028
--> $DIR/multiple-impls.rs:37:33
5129
|
@@ -59,17 +37,6 @@ LL | Index::index(&[] as &[i32], Bar(2u32));
5937
<[i32] as Index<Bar<usize>>>
6038
<[i32] as Index<Foo<usize>>>
6139

62-
error[E0277]: the trait bound `[i32]: Index<Bar<u32>>` is not satisfied
63-
--> $DIR/multiple-impls.rs:37:5
64-
|
65-
LL | Index::index(&[] as &[i32], Bar(2u32));
66-
| ^^^^^^^^^^^^ on impl for Bar
67-
|
68-
= help: the trait `Index<Bar<u32>>` is not implemented for `[i32]`
69-
= help: the following other types implement trait `Index<Idx>`:
70-
<[i32] as Index<Bar<usize>>>
71-
<[i32] as Index<Foo<usize>>>
72-
73-
error: aborting due to 6 previous errors
40+
error: aborting due to 3 previous errors
7441

7542
For more information about this error, try `rustc --explain E0277`.

src/test/ui/on-unimplemented/on-impl.stderr

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,6 @@ LL | Index::<u32>::index(&[1, 2, 3] as &[i32], 2u32);
99
= help: the trait `Index<u32>` is not implemented for `[i32]`
1010
= help: the trait `Index<usize>` is implemented for `[i32]`
1111

12-
error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied
13-
--> $DIR/on-impl.rs:22:5
14-
|
15-
LL | Index::<u32>::index(&[1, 2, 3] as &[i32], 2u32);
16-
| ^^^^^^^^^^^^^^^^^^^ a usize is required to index into a slice
17-
|
18-
= help: the trait `Index<u32>` is not implemented for `[i32]`
19-
= help: the trait `Index<usize>` is implemented for `[i32]`
20-
21-
error: aborting due to 2 previous errors
12+
error: aborting due to previous error
2213

2314
For more information about this error, try `rustc --explain E0277`.

src/test/ui/str/str-idx.stderr

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -28,17 +28,6 @@ note: required by a bound in `core::str::<impl str>::get`
2828
LL | pub const fn get<I: ~const SliceIndex<str>>(&self, i: I) -> Option<&I::Output> {
2929
| ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `core::str::<impl str>::get`
3030

31-
error[E0277]: the type `str` cannot be indexed by `{integer}`
32-
--> $DIR/str-idx.rs:4:15
33-
|
34-
LL | let _ = s.get(4);
35-
| ^^^ string indices are ranges of `usize`
36-
|
37-
= help: the trait `SliceIndex<str>` is not implemented for `{integer}`
38-
= note: you can use `.chars().nth()` or `.bytes().nth()`
39-
for more information, see chapter 8 in The Book: <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>
40-
= help: the trait `SliceIndex<[T]>` is implemented for `usize`
41-
4231
error[E0277]: the type `str` cannot be indexed by `{integer}`
4332
--> $DIR/str-idx.rs:5:29
4433
|
@@ -57,17 +46,6 @@ note: required by a bound in `core::str::<impl str>::get_unchecked`
5746
LL | pub const unsafe fn get_unchecked<I: ~const SliceIndex<str>>(&self, i: I) -> &I::Output {
5847
| ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `core::str::<impl str>::get_unchecked`
5948

60-
error[E0277]: the type `str` cannot be indexed by `{integer}`
61-
--> $DIR/str-idx.rs:5:15
62-
|
63-
LL | let _ = s.get_unchecked(4);
64-
| ^^^^^^^^^^^^^ string indices are ranges of `usize`
65-
|
66-
= help: the trait `SliceIndex<str>` is not implemented for `{integer}`
67-
= note: you can use `.chars().nth()` or `.bytes().nth()`
68-
for more information, see chapter 8 in The Book: <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>
69-
= help: the trait `SliceIndex<[T]>` is implemented for `usize`
70-
7149
error[E0277]: the type `str` cannot be indexed by `char`
7250
--> $DIR/str-idx.rs:6:19
7351
|
@@ -77,6 +55,6 @@ LL | let _: u8 = s['c'];
7755
= help: the trait `SliceIndex<str>` is not implemented for `char`
7856
= note: required for `str` to implement `Index<char>`
7957

80-
error: aborting due to 6 previous errors
58+
error: aborting due to 4 previous errors
8159

8260
For more information about this error, try `rustc --explain E0277`.

src/test/ui/str/str-mut-idx.stderr

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -52,17 +52,6 @@ note: required by a bound in `core::str::<impl str>::get_mut`
5252
LL | pub const fn get_mut<I: ~const SliceIndex<str>>(&mut self, i: I) -> Option<&mut I::Output> {
5353
| ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `core::str::<impl str>::get_mut`
5454

55-
error[E0277]: the type `str` cannot be indexed by `{integer}`
56-
--> $DIR/str-mut-idx.rs:9:7
57-
|
58-
LL | s.get_mut(1);
59-
| ^^^^^^^ string indices are ranges of `usize`
60-
|
61-
= help: the trait `SliceIndex<str>` is not implemented for `{integer}`
62-
= note: you can use `.chars().nth()` or `.bytes().nth()`
63-
for more information, see chapter 8 in The Book: <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>
64-
= help: the trait `SliceIndex<[T]>` is implemented for `usize`
65-
6655
error[E0277]: the type `str` cannot be indexed by `{integer}`
6756
--> $DIR/str-mut-idx.rs:11:25
6857
|
@@ -81,17 +70,6 @@ note: required by a bound in `core::str::<impl str>::get_unchecked_mut`
8170
LL | pub const unsafe fn get_unchecked_mut<I: ~const SliceIndex<str>>(
8271
| ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `core::str::<impl str>::get_unchecked_mut`
8372

84-
error[E0277]: the type `str` cannot be indexed by `{integer}`
85-
--> $DIR/str-mut-idx.rs:11:7
86-
|
87-
LL | s.get_unchecked_mut(1);
88-
| ^^^^^^^^^^^^^^^^^ string indices are ranges of `usize`
89-
|
90-
= help: the trait `SliceIndex<str>` is not implemented for `{integer}`
91-
= note: you can use `.chars().nth()` or `.bytes().nth()`
92-
for more information, see chapter 8 in The Book: <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>
93-
= help: the trait `SliceIndex<[T]>` is implemented for `usize`
94-
9573
error[E0277]: the type `str` cannot be indexed by `char`
9674
--> $DIR/str-mut-idx.rs:13:7
9775
|
@@ -101,6 +79,6 @@ LL | s['c'];
10179
= help: the trait `SliceIndex<str>` is not implemented for `char`
10280
= note: required for `str` to implement `Index<char>`
10381

104-
error: aborting due to 8 previous errors
82+
error: aborting due to 6 previous errors
10583

10684
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)