Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -663,6 +663,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
if !result.is_empty() {
mutate_fulfillment_errors(&mut result);
self.adjust_fulfillment_errors_for_expr_obligation(&mut result);
result.retain(|error| !self.add_error(&error.obligation.cause));

self.err_ctxt().report_fulfillment_errors(result);
}
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -403,14 +403,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// that are not closures, then we type-check the closures. This is so
// that we have more information about the types of arguments when we
// type-check the functions. This isn't really the right way to do this.
self.select_obligations_where_possible(|_| {});
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this new call to select for? It may affect inference and also performance 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this new call to select for? It may affect inference and also performance 🤔

sorry, commit the debug code, will be fix in next pr.

for check_closures in [false, true] {
// More awful hacks: before we check argument types, try to do
// an "opportunistic" trait resolution of any trait bounds on
// the call. This helps coercions.
if check_closures {
self.select_obligations_where_possible(|_| {})
self.select_obligations_where_possible(|_| {});
}

// Check each argument, to satisfy the input it was provided for
// Visually, we're traveling down the diagonal of the compatibility matrix
for (idx, arg) in provided_args.iter().enumerate() {
Expand Down
26 changes: 25 additions & 1 deletion compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,15 @@ use std::cell::{Cell, RefCell};
use std::ops::Deref;

use hir::def_id::CRATE_DEF_ID;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_errors::DiagCtxtHandle;
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::{self as hir, HirId, ItemLocalMap};
use rustc_hir_analysis::hir_ty_lowering::{
HirTyLowerer, InherentAssocCandidate, RegionInferReason,
};
use rustc_infer::infer::{self, RegionVariableOrigin};
use rustc_infer::traits::{DynCompatibilityViolation, Obligation};
use rustc_infer::traits::{DynCompatibilityViolation, Obligation, ObligationCauseCodeHandle};
use rustc_middle::ty::{self, Const, Ty, TyCtxt, TypeVisitableExt};
use rustc_session::Session;
use rustc_span::{self, DUMMY_SP, ErrorGuaranteed, Ident, Span, sym};
Expand Down Expand Up @@ -126,6 +127,8 @@ pub(crate) struct FnCtxt<'a, 'tcx> {
/// These are stored here so we may collect them when canonicalizing user
/// type ascriptions later.
pub(super) trait_ascriptions: RefCell<ItemLocalMap<Vec<ty::Clause<'tcx>>>>,

error_causes: RefCell<FxHashMap<LocalDefId, FxHashSet<ObligationCauseCodeHandle<'tcx>>>>,
}

impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
Expand Down Expand Up @@ -154,6 +157,27 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
diverging_fallback_behavior,
diverging_block_behavior,
trait_ascriptions: Default::default(),
error_causes: Default::default(),
}
}

pub(crate) fn add_error(&self, error: &ObligationCause<'tcx>) -> bool {
let mut error_causes = self.error_causes.borrow_mut();
let body_id = &error.body_id;
let code = error.code_handle();

if let Some(s) = error_causes.get_mut(body_id) {
if s.contains(code) {
true
} else {
s.insert(code.clone());
false
}
} else {
let mut s = FxHashSet::default();
s.insert(code.clone());
error_causes.insert(body_id.clone(), s);
false
}
}

Expand Down
23 changes: 14 additions & 9 deletions compiler/rustc_middle/src/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,11 @@ impl<'tcx> ObligationCause<'tcx> {
&self.code
}

#[inline]
pub fn code_handle(&self) -> &ObligationCauseCodeHandle<'tcx> {
&self.code
}

pub fn map_code(
&mut self,
f: impl FnOnce(ObligationCauseCodeHandle<'tcx>) -> ObligationCauseCode<'tcx>,
Expand Down Expand Up @@ -145,7 +150,7 @@ impl<'tcx> ObligationCause<'tcx> {
}

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

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

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

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

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

#[derive(Clone, Debug, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
#[derive(Clone, Debug, PartialEq, Eq, HashStable, Hash, TyEncodable, TyDecodable)]
#[derive(TypeVisitable, TypeFoldable)]
pub struct ImplDerivedCause<'tcx> {
pub derived: DerivedCause<'tcx>,
Expand All @@ -585,7 +590,7 @@ pub struct ImplDerivedCause<'tcx> {
pub span: Span,
}

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

#[derive(Clone, Debug, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
#[derive(Clone, Debug, PartialEq, Eq, Hash, HashStable, TyEncodable, TyDecodable)]
#[derive(TypeVisitable, TypeFoldable)]
pub struct ImplDerivedHostCause<'tcx> {
pub derived: DerivedHostCause<'tcx>,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/adt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ impl<'tcx> rustc_type_ir::inherent::AdtDef<TyCtxt<'tcx>> for AdtDef<'tcx> {
}
}

#[derive(Copy, Clone, Debug, Eq, PartialEq, HashStable, TyEncodable, TyDecodable)]
#[derive(Copy, Clone, Debug, Eq, PartialEq, HashStable, Hash, TyEncodable, TyDecodable)]
pub enum AdtKind {
Struct,
Union,
Expand Down
10 changes: 10 additions & 0 deletions tests/ui/suggestions/duplcate-diagnostics-issue-144074.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
struct Struct<T>(T);
fn assert_sized(_x: impl Sized) {}
fn f() {
assert_sized(Struct(*"")); //~ ERROR: the size for values of type `str` cannot be known at compilation time
//~^ ERROR: the size for values of type `str` cannot be known at compilation time
}

fn main() {
f();
}
43 changes: 43 additions & 0 deletions tests/ui/suggestions/duplcate-diagnostics-issue-144074.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
error[E0277]: the size for values of type `str` cannot be known at compilation time
--> $DIR/duplcate-diagnostics-issue-144074.rs:4:25
|
LL | assert_sized(Struct(*""));
| ------ ^^^ doesn't have a size known at compile-time
| |
| required by a bound introduced by this call
|
= help: the trait `Sized` is not implemented for `str`
note: required by a bound in `Struct`
--> $DIR/duplcate-diagnostics-issue-144074.rs:1:15
|
LL | struct Struct<T>(T);
| ^ required by this bound in `Struct`
help: references are always `Sized`, even if they point to unsized data; consider not dereferencing the expression
|
LL - assert_sized(Struct(*""));
LL + assert_sized(Struct(""));
|

error[E0277]: the size for values of type `str` cannot be known at compilation time
--> $DIR/duplcate-diagnostics-issue-144074.rs:4:18
|
LL | assert_sized(Struct(*""));
| ^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `str`
note: required by an implicit `Sized` bound in `Struct`
--> $DIR/duplcate-diagnostics-issue-144074.rs:1:15
|
LL | struct Struct<T>(T);
| ^ required by the implicit `Sized` requirement on this type parameter in `Struct`
help: you could relax the implicit `Sized` bound on `T` if it were used through indirection like `&T` or `Box<T>`
--> $DIR/duplcate-diagnostics-issue-144074.rs:1:15
|
LL | struct Struct<T>(T);
| ^ - ...if indirection were used here: `Box<T>`
| |
| this could be changed to `T: ?Sized`...

error: aborting due to 2 previous errors

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