Skip to content

Commit bd230c7

Browse files
Auto merge of #144818 - lichuang:fix_issue_144074, r=<try>
fix issue 144074, having so many same diagnostics makes it hard to re…
2 parents 6d091b2 + 080e25b commit bd230c7

File tree

7 files changed

+97
-13
lines changed

7 files changed

+97
-13
lines changed

compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -663,6 +663,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
663663
if !result.is_empty() {
664664
mutate_fulfillment_errors(&mut result);
665665
self.adjust_fulfillment_errors_for_expr_obligation(&mut result);
666+
result.retain(|error| !self.add_error(&error.obligation.cause));
667+
666668
self.err_ctxt().report_fulfillment_errors(result);
667669
}
668670
}

compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -403,14 +403,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
403403
// that are not closures, then we type-check the closures. This is so
404404
// that we have more information about the types of arguments when we
405405
// type-check the functions. This isn't really the right way to do this.
406+
self.select_obligations_where_possible(|_| {});
406407
for check_closures in [false, true] {
407408
// More awful hacks: before we check argument types, try to do
408409
// an "opportunistic" trait resolution of any trait bounds on
409410
// the call. This helps coercions.
410411
if check_closures {
411-
self.select_obligations_where_possible(|_| {})
412+
self.select_obligations_where_possible(|_| {});
412413
}
413-
414414
// Check each argument, to satisfy the input it was provided for
415415
// Visually, we're traveling down the diagonal of the compatibility matrix
416416
for (idx, arg) in provided_args.iter().enumerate() {

compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,15 @@ use std::cell::{Cell, RefCell};
99
use std::ops::Deref;
1010

1111
use hir::def_id::CRATE_DEF_ID;
12+
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
1213
use rustc_errors::DiagCtxtHandle;
1314
use rustc_hir::def_id::{DefId, LocalDefId};
1415
use rustc_hir::{self as hir, HirId, ItemLocalMap};
1516
use rustc_hir_analysis::hir_ty_lowering::{
1617
HirTyLowerer, InherentAssocCandidate, RegionInferReason,
1718
};
1819
use rustc_infer::infer::{self, RegionVariableOrigin};
19-
use rustc_infer::traits::{DynCompatibilityViolation, Obligation};
20+
use rustc_infer::traits::{DynCompatibilityViolation, Obligation, ObligationCauseCodeHandle};
2021
use rustc_middle::ty::{self, Const, Ty, TyCtxt, TypeVisitableExt};
2122
use rustc_session::Session;
2223
use rustc_span::{self, DUMMY_SP, ErrorGuaranteed, Ident, Span, sym};
@@ -126,6 +127,8 @@ pub(crate) struct FnCtxt<'a, 'tcx> {
126127
/// These are stored here so we may collect them when canonicalizing user
127128
/// type ascriptions later.
128129
pub(super) trait_ascriptions: RefCell<ItemLocalMap<Vec<ty::Clause<'tcx>>>>,
130+
131+
error_causes: RefCell<FxHashMap<LocalDefId, FxHashSet<ObligationCauseCodeHandle<'tcx>>>>,
129132
}
130133

131134
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
@@ -154,6 +157,27 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
154157
diverging_fallback_behavior,
155158
diverging_block_behavior,
156159
trait_ascriptions: Default::default(),
160+
error_causes: Default::default(),
161+
}
162+
}
163+
164+
pub(crate) fn add_error(&self, error: &ObligationCause<'tcx>) -> bool {
165+
let mut error_causes = self.error_causes.borrow_mut();
166+
let body_id = &error.body_id;
167+
let code = error.code_handle();
168+
169+
if let Some(s) = error_causes.get_mut(body_id) {
170+
if s.contains(code) {
171+
true
172+
} else {
173+
s.insert(code.clone());
174+
false
175+
}
176+
} else {
177+
let mut s = FxHashSet::default();
178+
s.insert(code.clone());
179+
error_causes.insert(body_id.clone(), s);
180+
false
157181
}
158182
}
159183

compiler/rustc_middle/src/traits/mod.rs

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,11 @@ impl<'tcx> ObligationCause<'tcx> {
9595
&self.code
9696
}
9797

98+
#[inline]
99+
pub fn code_handle(&self) -> &ObligationCauseCodeHandle<'tcx> {
100+
&self.code
101+
}
102+
98103
pub fn map_code(
99104
&mut self,
100105
f: impl FnOnce(ObligationCauseCodeHandle<'tcx>) -> ObligationCauseCode<'tcx>,
@@ -145,7 +150,7 @@ impl<'tcx> ObligationCause<'tcx> {
145150
}
146151

147152
/// A compact form of `ObligationCauseCode`.
148-
#[derive(Clone, PartialEq, Eq, Default, HashStable)]
153+
#[derive(Clone, PartialEq, Eq, Default, HashStable, Hash)]
149154
#[derive(TypeVisitable, TypeFoldable, TyEncodable, TyDecodable)]
150155
pub struct ObligationCauseCodeHandle<'tcx> {
151156
/// `None` for `ObligationCauseCode::Misc` (a common case, occurs ~60% of
@@ -177,7 +182,7 @@ impl<'tcx> std::ops::Deref for ObligationCauseCodeHandle<'tcx> {
177182
}
178183
}
179184

180-
#[derive(Clone, Debug, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
185+
#[derive(Clone, Debug, PartialEq, Eq, HashStable, TyEncodable, TyDecodable, Hash)]
181186
#[derive(TypeVisitable, TypeFoldable)]
182187
pub enum ObligationCauseCode<'tcx> {
183188
/// Not well classified or should be obvious from the span.
@@ -420,7 +425,7 @@ pub enum ObligationCauseCode<'tcx> {
420425

421426
/// Whether a value can be extracted into a const.
422427
/// Used for diagnostics around array repeat expressions.
423-
#[derive(Copy, Clone, Debug, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
428+
#[derive(Copy, Clone, Debug, PartialEq, Eq, HashStable, Hash, TyEncodable, TyDecodable)]
424429
pub enum IsConstable {
425430
No,
426431
/// Call to a const fn
@@ -516,7 +521,7 @@ impl<'tcx> ObligationCauseCode<'tcx> {
516521
#[cfg(target_pointer_width = "64")]
517522
rustc_data_structures::static_assert_size!(ObligationCauseCode<'_>, 48);
518523

519-
#[derive(Clone, Debug, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
524+
#[derive(Clone, Debug, PartialEq, Eq, HashStable, Hash, TyEncodable, TyDecodable)]
520525
#[derive(TypeVisitable, TypeFoldable)]
521526
pub struct MatchExpressionArmCause<'tcx> {
522527
pub arm_block_id: Option<HirId>,
@@ -543,7 +548,7 @@ pub struct MatchExpressionArmCause<'tcx> {
543548
/// Fields here refer to the scrutinee of a pattern.
544549
/// If the scrutinee isn't given in the diagnostic, then this won't exist.
545550
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
546-
#[derive(TypeFoldable, TypeVisitable, HashStable, TyEncodable, TyDecodable)]
551+
#[derive(TypeFoldable, TypeVisitable, HashStable, Hash, TyEncodable, TyDecodable)]
547552
pub struct PatternOriginExpr {
548553
/// A span representing the scrutinee expression, with all leading references
549554
/// peeled from the expression.
@@ -558,7 +563,7 @@ pub struct PatternOriginExpr {
558563
pub peeled_prefix_suggestion_parentheses: bool,
559564
}
560565

561-
#[derive(Clone, Debug, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
566+
#[derive(Clone, Debug, PartialEq, Eq, HashStable, Hash, TyEncodable, TyDecodable)]
562567
#[derive(TypeVisitable, TypeFoldable)]
563568
pub struct DerivedCause<'tcx> {
564569
/// The trait predicate of the parent obligation that led to the
@@ -571,7 +576,7 @@ pub struct DerivedCause<'tcx> {
571576
pub parent_code: ObligationCauseCodeHandle<'tcx>,
572577
}
573578

574-
#[derive(Clone, Debug, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
579+
#[derive(Clone, Debug, PartialEq, Eq, HashStable, Hash, TyEncodable, TyDecodable)]
575580
#[derive(TypeVisitable, TypeFoldable)]
576581
pub struct ImplDerivedCause<'tcx> {
577582
pub derived: DerivedCause<'tcx>,
@@ -585,7 +590,7 @@ pub struct ImplDerivedCause<'tcx> {
585590
pub span: Span,
586591
}
587592

588-
#[derive(Clone, Debug, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
593+
#[derive(Clone, Debug, PartialEq, Eq, HashStable, Hash, TyEncodable, TyDecodable)]
589594
#[derive(TypeVisitable, TypeFoldable)]
590595
pub struct DerivedHostCause<'tcx> {
591596
/// The trait predicate of the parent obligation that led to the
@@ -598,7 +603,7 @@ pub struct DerivedHostCause<'tcx> {
598603
pub parent_code: ObligationCauseCodeHandle<'tcx>,
599604
}
600605

601-
#[derive(Clone, Debug, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
606+
#[derive(Clone, Debug, PartialEq, Eq, Hash, HashStable, TyEncodable, TyDecodable)]
602607
#[derive(TypeVisitable, TypeFoldable)]
603608
pub struct ImplDerivedHostCause<'tcx> {
604609
pub derived: DerivedHostCause<'tcx>,

compiler/rustc_middle/src/ty/adt.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ impl<'tcx> rustc_type_ir::inherent::AdtDef<TyCtxt<'tcx>> for AdtDef<'tcx> {
249249
}
250250
}
251251

252-
#[derive(Copy, Clone, Debug, Eq, PartialEq, HashStable, TyEncodable, TyDecodable)]
252+
#[derive(Copy, Clone, Debug, Eq, PartialEq, HashStable, Hash, TyEncodable, TyDecodable)]
253253
pub enum AdtKind {
254254
Struct,
255255
Union,
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
struct Struct<T>(T);
2+
fn assert_sized(_x: impl Sized) {}
3+
fn f() {
4+
assert_sized(Struct(*"")); //~ ERROR: the size for values of type `str` cannot be known at compilation time
5+
//~^ ERROR: the size for values of type `str` cannot be known at compilation time
6+
}
7+
8+
fn main() {
9+
f();
10+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
error[E0277]: the size for values of type `str` cannot be known at compilation time
2+
--> $DIR/duplcate-diagnostics-issue-144074.rs:4:25
3+
|
4+
LL | assert_sized(Struct(*""));
5+
| ------ ^^^ doesn't have a size known at compile-time
6+
| |
7+
| required by a bound introduced by this call
8+
|
9+
= help: the trait `Sized` is not implemented for `str`
10+
note: required by a bound in `Struct`
11+
--> $DIR/duplcate-diagnostics-issue-144074.rs:1:15
12+
|
13+
LL | struct Struct<T>(T);
14+
| ^ required by this bound in `Struct`
15+
help: references are always `Sized`, even if they point to unsized data; consider not dereferencing the expression
16+
|
17+
LL - assert_sized(Struct(*""));
18+
LL + assert_sized(Struct(""));
19+
|
20+
21+
error[E0277]: the size for values of type `str` cannot be known at compilation time
22+
--> $DIR/duplcate-diagnostics-issue-144074.rs:4:18
23+
|
24+
LL | assert_sized(Struct(*""));
25+
| ^^^^^^^^^^^ doesn't have a size known at compile-time
26+
|
27+
= help: the trait `Sized` is not implemented for `str`
28+
note: required by an implicit `Sized` bound in `Struct`
29+
--> $DIR/duplcate-diagnostics-issue-144074.rs:1:15
30+
|
31+
LL | struct Struct<T>(T);
32+
| ^ required by the implicit `Sized` requirement on this type parameter in `Struct`
33+
help: you could relax the implicit `Sized` bound on `T` if it were used through indirection like `&T` or `Box<T>`
34+
--> $DIR/duplcate-diagnostics-issue-144074.rs:1:15
35+
|
36+
LL | struct Struct<T>(T);
37+
| ^ - ...if indirection were used here: `Box<T>`
38+
| |
39+
| this could be changed to `T: ?Sized`...
40+
41+
error: aborting due to 2 previous errors
42+
43+
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)