Use only one label for multiple unsatisfied bounds on type (typeck)
This commit is contained in:
parent
3691ab8e7a
commit
757b726f86
@ -9,7 +9,7 @@
|
||||
use crate::FnCtxt;
|
||||
use rustc_ast::ast::Mutability;
|
||||
use rustc_attr::parse_confusables;
|
||||
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
|
||||
use rustc_data_structures::fx::{FxHashMap, FxIndexMap, FxIndexSet};
|
||||
use rustc_data_structures::unord::UnordSet;
|
||||
use rustc_errors::StashKey;
|
||||
use rustc_errors::{
|
||||
@ -547,7 +547,7 @@ pub fn report_no_match_method_error(
|
||||
);
|
||||
}
|
||||
|
||||
let mut bound_spans = vec![];
|
||||
let mut bound_spans: FxHashMap<Span, Vec<String>> = Default::default();
|
||||
let mut restrict_type_params = false;
|
||||
let mut unsatisfied_bounds = false;
|
||||
if item_name.name == sym::count && self.is_slice_ty(rcvr_ty, span) {
|
||||
@ -642,19 +642,21 @@ pub fn report_no_match_method_error(
|
||||
false
|
||||
};
|
||||
let mut bound_span_label = |self_ty: Ty<'_>, obligation: &str, quiet: &str| {
|
||||
let msg = format!(
|
||||
"doesn't satisfy `{}`",
|
||||
if obligation.len() > 50 { quiet } else { obligation }
|
||||
);
|
||||
let msg = format!("`{}`", if obligation.len() > 50 { quiet } else { obligation });
|
||||
match &self_ty.kind() {
|
||||
// Point at the type that couldn't satisfy the bound.
|
||||
ty::Adt(def, _) => bound_spans.push((self.tcx.def_span(def.did()), msg)),
|
||||
ty::Adt(def, _) => {
|
||||
bound_spans.entry(tcx.def_span(def.did())).or_default().push(msg)
|
||||
}
|
||||
// Point at the trait object that couldn't satisfy the bound.
|
||||
ty::Dynamic(preds, _, _) => {
|
||||
for pred in preds.iter() {
|
||||
match pred.skip_binder() {
|
||||
ty::ExistentialPredicate::Trait(tr) => {
|
||||
bound_spans.push((self.tcx.def_span(tr.def_id), msg.clone()))
|
||||
bound_spans
|
||||
.entry(tcx.def_span(tr.def_id))
|
||||
.or_default()
|
||||
.push(msg.clone());
|
||||
}
|
||||
ty::ExistentialPredicate::Projection(_)
|
||||
| ty::ExistentialPredicate::AutoTrait(_) => {}
|
||||
@ -662,8 +664,12 @@ pub fn report_no_match_method_error(
|
||||
}
|
||||
}
|
||||
// Point at the closure that couldn't satisfy the bound.
|
||||
ty::Closure(def_id, _) => bound_spans
|
||||
.push((tcx.def_span(*def_id), format!("doesn't satisfy `{quiet}`"))),
|
||||
ty::Closure(def_id, _) => {
|
||||
bound_spans
|
||||
.entry(tcx.def_span(*def_id))
|
||||
.or_default()
|
||||
.push(format!("`{quiet}`"));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
};
|
||||
@ -1170,9 +1176,25 @@ trait bound{s}",
|
||||
|
||||
self.suggest_unwrapping_inner_self(&mut err, source, rcvr_ty, item_name);
|
||||
|
||||
bound_spans.sort();
|
||||
bound_spans.dedup();
|
||||
for (span, msg) in bound_spans.into_iter() {
|
||||
#[allow(rustc::potential_query_instability)] // We immediately sort the resulting Vec.
|
||||
let mut bound_spans: Vec<(Span, Vec<String>)> = bound_spans
|
||||
.into_iter()
|
||||
.map(|(span, mut bounds)| {
|
||||
bounds.sort();
|
||||
bounds.dedup();
|
||||
(span, bounds)
|
||||
})
|
||||
.collect();
|
||||
bound_spans.sort_by_key(|(span, _)| *span);
|
||||
for (span, bounds) in bound_spans {
|
||||
if !tcx.sess.source_map().is_span_accessible(span) {
|
||||
continue;
|
||||
}
|
||||
let msg = match &bounds[..] {
|
||||
[bound] => format!("doesn't satisfy {bound}"),
|
||||
[bounds @ .., last] => format!("doesn't satisfy {} or {last}", bounds.join(", ")),
|
||||
[] => unreachable!(),
|
||||
};
|
||||
err.span_label(span, msg);
|
||||
}
|
||||
|
||||
|
@ -1,18 +1,11 @@
|
||||
error[E0599]: the method `clone` exists for struct `Box<dyn Foo>`, but its trait bounds were not satisfied
|
||||
--> $DIR/unique-object-noncopyable.rs:24:16
|
||||
|
|
||||
LL | trait Foo {
|
||||
| ---------
|
||||
| |
|
||||
| doesn't satisfy `dyn Foo: Clone`
|
||||
| doesn't satisfy `dyn Foo: Sized`
|
||||
LL | trait Foo {
|
||||
| --------- doesn't satisfy `dyn Foo: Clone` or `dyn Foo: Sized`
|
||||
...
|
||||
LL | let _z = y.clone();
|
||||
| ^^^^^ method cannot be called on `Box<dyn Foo>` due to unsatisfied trait bounds
|
||||
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL
|
||||
::: $SRC_DIR/alloc/src/boxed.rs:LL:COL
|
||||
|
|
||||
= note: doesn't satisfy `Box<dyn Foo>: Clone`
|
||||
LL | let _z = y.clone();
|
||||
| ^^^^^ method cannot be called on `Box<dyn Foo>` due to unsatisfied trait bounds
|
||||
|
|
||||
= note: the following trait bounds were not satisfied:
|
||||
`dyn Foo: Sized`
|
||||
|
@ -1,15 +1,11 @@
|
||||
error[E0599]: the method `clone` exists for struct `Box<R>`, but its trait bounds were not satisfied
|
||||
--> $DIR/unique-pinned-nocopy.rs:12:16
|
||||
|
|
||||
LL | struct R {
|
||||
| -------- doesn't satisfy `R: Clone`
|
||||
LL | struct R {
|
||||
| -------- doesn't satisfy `R: Clone`
|
||||
...
|
||||
LL | let _j = i.clone();
|
||||
| ^^^^^ method cannot be called on `Box<R>` due to unsatisfied trait bounds
|
||||
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL
|
||||
::: $SRC_DIR/alloc/src/boxed.rs:LL:COL
|
||||
|
|
||||
= note: doesn't satisfy `Box<R>: Clone`
|
||||
LL | let _j = i.clone();
|
||||
| ^^^^^ method cannot be called on `Box<R>` due to unsatisfied trait bounds
|
||||
|
|
||||
= note: the following trait bounds were not satisfied:
|
||||
`R: Clone`
|
||||
|
@ -8,10 +8,7 @@ LL | pub struct Foo<T>(T, T, T);
|
||||
| doesn't satisfy `Foo<NonCopy>: Clone`
|
||||
LL |
|
||||
LL | struct NonCopy;
|
||||
| --------------
|
||||
| |
|
||||
| doesn't satisfy `NonCopy: Clone`
|
||||
| doesn't satisfy `NonCopy: Copy`
|
||||
| -------------- doesn't satisfy `NonCopy: Clone` or `NonCopy: Copy`
|
||||
...
|
||||
LL | _ = x.clone();
|
||||
| ^^^^^ method cannot be called on `Foo<NonCopy>` due to unsatisfied trait bounds
|
||||
|
@ -2,11 +2,7 @@ error[E0599]: the method `insert` exists for struct `HashSet<Value>`, but its tr
|
||||
--> $DIR/issue-91550.rs:8:8
|
||||
|
|
||||
LL | struct Value(u32);
|
||||
| ------------
|
||||
| |
|
||||
| doesn't satisfy `Value: Eq`
|
||||
| doesn't satisfy `Value: Hash`
|
||||
| doesn't satisfy `Value: PartialEq`
|
||||
| ------------ doesn't satisfy `Value: Eq`, `Value: Hash` or `Value: PartialEq`
|
||||
...
|
||||
LL | hs.insert(Value(0));
|
||||
| ^^^^^^
|
||||
@ -26,10 +22,7 @@ error[E0599]: the method `use_eq` exists for struct `Object<NoDerives>`, but its
|
||||
--> $DIR/issue-91550.rs:26:9
|
||||
|
|
||||
LL | pub struct NoDerives;
|
||||
| --------------------
|
||||
| |
|
||||
| doesn't satisfy `NoDerives: Eq`
|
||||
| doesn't satisfy `NoDerives: PartialEq`
|
||||
| -------------------- doesn't satisfy `NoDerives: Eq` or `NoDerives: PartialEq`
|
||||
LL |
|
||||
LL | struct Object<T>(T);
|
||||
| ---------------- method `use_eq` not found for this struct
|
||||
@ -57,12 +50,7 @@ error[E0599]: the method `use_ord` exists for struct `Object<NoDerives>`, but it
|
||||
--> $DIR/issue-91550.rs:27:9
|
||||
|
|
||||
LL | pub struct NoDerives;
|
||||
| --------------------
|
||||
| |
|
||||
| doesn't satisfy `NoDerives: Eq`
|
||||
| doesn't satisfy `NoDerives: Ord`
|
||||
| doesn't satisfy `NoDerives: PartialEq`
|
||||
| doesn't satisfy `NoDerives: PartialOrd`
|
||||
| -------------------- doesn't satisfy `NoDerives: Eq`, `NoDerives: Ord`, `NoDerives: PartialEq` or `NoDerives: PartialOrd`
|
||||
LL |
|
||||
LL | struct Object<T>(T);
|
||||
| ---------------- method `use_ord` not found for this struct
|
||||
@ -94,12 +82,7 @@ error[E0599]: the method `use_ord_and_partial_ord` exists for struct `Object<NoD
|
||||
--> $DIR/issue-91550.rs:28:9
|
||||
|
|
||||
LL | pub struct NoDerives;
|
||||
| --------------------
|
||||
| |
|
||||
| doesn't satisfy `NoDerives: Eq`
|
||||
| doesn't satisfy `NoDerives: Ord`
|
||||
| doesn't satisfy `NoDerives: PartialEq`
|
||||
| doesn't satisfy `NoDerives: PartialOrd`
|
||||
| -------------------- doesn't satisfy `NoDerives: Eq`, `NoDerives: Ord`, `NoDerives: PartialEq` or `NoDerives: PartialOrd`
|
||||
LL |
|
||||
LL | struct Object<T>(T);
|
||||
| ---------------- method `use_ord_and_partial_ord` not found for this struct
|
||||
|
@ -26,9 +26,6 @@ LL | enum Node<T, P: PointerFamily> {
|
||||
...
|
||||
LL | let mut list = RcNode::<i32>::new();
|
||||
| ^^^ doesn't have a size known at compile-time
|
||||
--> $SRC_DIR/core/src/ops/deref.rs:LL:COL
|
||||
|
|
||||
= note: doesn't satisfy `_: Sized`
|
||||
|
|
||||
note: trait bound `Node<i32, RcFamily>: Sized` was not satisfied
|
||||
--> $DIR/issue-119942-unsatisified-gat-bound-during-assoc-ty-selection.rs:4:18
|
||||
|
@ -17,8 +17,7 @@ impl<T: X<Y<i32> = i32>> M for T {}
|
||||
|
||||
struct S;
|
||||
//~^ NOTE method `f` not found for this
|
||||
//~| NOTE doesn't satisfy `<S as X>::Y<i32> = i32`
|
||||
//~| NOTE doesn't satisfy `S: M`
|
||||
//~| NOTE doesn't satisfy `<S as X>::Y<i32> = i32` or `S: M`
|
||||
|
||||
impl X for S {
|
||||
type Y<T> = bool;
|
||||
|
@ -1,12 +1,11 @@
|
||||
error[E0599]: the method `f` exists for struct `S`, but its trait bounds were not satisfied
|
||||
--> $DIR/method-unsatisfied-assoc-type-predicate.rs:28:7
|
||||
--> $DIR/method-unsatisfied-assoc-type-predicate.rs:27:7
|
||||
|
|
||||
LL | struct S;
|
||||
| --------
|
||||
| |
|
||||
| method `f` not found for this struct
|
||||
| doesn't satisfy `<S as X>::Y<i32> = i32`
|
||||
| doesn't satisfy `S: M`
|
||||
| doesn't satisfy `<S as X>::Y<i32> = i32` or `S: M`
|
||||
...
|
||||
LL | a.f();
|
||||
| ^ method cannot be called on `S` due to unsatisfied trait bounds
|
||||
|
@ -3,9 +3,6 @@ error[E0599]: `Vec<bool>` is not an iterator
|
||||
|
|
||||
LL | vec![true, false].map(|v| !v).collect::<Vec<_>>();
|
||||
| ^^^ `Vec<bool>` is not an iterator; try calling `.into_iter()` or `.iter()`
|
||||
--> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
|
||||
|
|
||||
= note: doesn't satisfy `Vec<bool>: Iterator`
|
||||
|
|
||||
= note: the following trait bounds were not satisfied:
|
||||
`Vec<bool>: Iterator`
|
||||
|
@ -21,11 +21,7 @@ error[E0599]: the method `count` exists for struct `Filter<Fuse<Once<&str>>, {cl
|
||||
LL | once::<&str>("str").fuse().filter(|a: &str| true).count();
|
||||
| --------- ^^^^^ method cannot be called due to unsatisfied trait bounds
|
||||
| |
|
||||
| doesn't satisfy `<_ as FnOnce<(&&str,)>>::Output = bool`
|
||||
| doesn't satisfy `_: FnMut<(&&str,)>`
|
||||
--> $SRC_DIR/core/src/iter/adapters/filter.rs:LL:COL
|
||||
|
|
||||
= note: doesn't satisfy `_: Iterator`
|
||||
| doesn't satisfy `<_ as FnOnce<(&&str,)>>::Output = bool` or `_: FnMut<(&&str,)>`
|
||||
|
|
||||
= note: the following trait bounds were not satisfied:
|
||||
`<{closure@$DIR/issue-36053-2.rs:7:39: 7:48} as FnOnce<(&&str,)>>::Output = bool`
|
||||
|
@ -2,10 +2,7 @@ error[E0599]: the method `test` exists for struct `Foo<Enum, CloneEnum>`, but it
|
||||
--> $DIR/derive-trait-for-method-call.rs:28:15
|
||||
|
|
||||
LL | enum Enum {
|
||||
| ---------
|
||||
| |
|
||||
| doesn't satisfy `Enum: Clone`
|
||||
| doesn't satisfy `Enum: Default`
|
||||
| --------- doesn't satisfy `Enum: Clone` or `Enum: Default`
|
||||
...
|
||||
LL | enum CloneEnum {
|
||||
| -------------- doesn't satisfy `CloneEnum: Default`
|
||||
@ -40,10 +37,7 @@ error[E0599]: the method `test` exists for struct `Foo<Struct, CloneStruct>`, bu
|
||||
--> $DIR/derive-trait-for-method-call.rs:34:15
|
||||
|
|
||||
LL | struct Struct {
|
||||
| -------------
|
||||
| |
|
||||
| doesn't satisfy `Struct: Clone`
|
||||
| doesn't satisfy `Struct: Default`
|
||||
| ------------- doesn't satisfy `Struct: Clone` or `Struct: Default`
|
||||
...
|
||||
LL | struct CloneStruct {
|
||||
| ------------------ doesn't satisfy `CloneStruct: Default`
|
||||
@ -85,12 +79,6 @@ LL | struct Foo<X, Y> (X, Y);
|
||||
...
|
||||
LL | let y = x.test();
|
||||
| ^^^^ method cannot be called on `Foo<Vec<Enum>, Instant>` due to unsatisfied trait bounds
|
||||
--> $SRC_DIR/std/src/time.rs:LL:COL
|
||||
|
|
||||
= note: doesn't satisfy `Instant: Default`
|
||||
--> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
|
||||
|
|
||||
= note: doesn't satisfy `Vec<Enum>: Clone`
|
||||
|
|
||||
note: the following trait bounds were not satisfied:
|
||||
`Instant: Default`
|
||||
|
@ -25,9 +25,6 @@ error[E0599]: the method `write_fmt` exists for struct `BufWriter<&dyn Write>`,
|
||||
|
|
||||
LL | writeln!(fp, "hello world").unwrap();
|
||||
| ---------^^---------------- method cannot be called on `BufWriter<&dyn Write>` due to unsatisfied trait bounds
|
||||
--> $SRC_DIR/std/src/io/buffered/bufwriter.rs:LL:COL
|
||||
|
|
||||
= note: doesn't satisfy `BufWriter<&dyn std::io::Write>: std::io::Write`
|
||||
|
|
||||
note: must implement `io::Write`, `fmt::Write`, or have a `write_fmt` method
|
||||
--> $DIR/mut-borrow-needed-by-trait.rs:21:14
|
||||
|
@ -27,9 +27,6 @@ error[E0599]: the method `read_until` exists for struct `BufReader<&T>`, but its
|
||||
|
|
||||
LL | stream_reader.read_until(b'\n', &mut buffer).expect("Reading into buffer failed");
|
||||
| ^^^^^^^^^^ method cannot be called on `BufReader<&T>` due to unsatisfied trait bounds
|
||||
--> $SRC_DIR/std/src/io/buffered/bufreader.rs:LL:COL
|
||||
|
|
||||
= note: doesn't satisfy `BufReader<&T>: BufRead`
|
||||
|
|
||||
= note: the following trait bounds were not satisfied:
|
||||
`&T: std::io::Read`
|
||||
|
@ -2,10 +2,7 @@ error[E0599]: the method `check` exists for struct `Client<()>`, but its trait b
|
||||
--> $DIR/track-obligations.rs:83:16
|
||||
|
|
||||
LL | struct ALayer<C>(C);
|
||||
| ----------------
|
||||
| |
|
||||
| doesn't satisfy `<_ as Layer<()>>::Service = <ALayer<()> as ParticularServiceLayer<()>>::Service`
|
||||
| doesn't satisfy `ALayer<()>: ParticularServiceLayer<()>`
|
||||
| ---------------- doesn't satisfy `<_ as Layer<()>>::Service = <ALayer<()> as ParticularServiceLayer<()>>::Service` or `ALayer<()>: ParticularServiceLayer<()>`
|
||||
...
|
||||
LL | struct Client<C>(C);
|
||||
| ---------------- method `check` not found for this struct
|
||||
|
@ -5,8 +5,7 @@ LL | pub struct A;
|
||||
| ------------
|
||||
| |
|
||||
| function or associated item `partial_cmp` not found for this struct
|
||||
| doesn't satisfy `A: Iterator`
|
||||
| doesn't satisfy `A: PartialOrd<_>`
|
||||
| doesn't satisfy `A: Iterator` or `A: PartialOrd<_>`
|
||||
...
|
||||
LL | _ => match A::partial_cmp() {},
|
||||
| ^^^^^^^^^^^ function or associated item cannot be called on `A` due to unsatisfied trait bounds
|
||||
|
@ -35,12 +35,6 @@ LL | | .collect();
|
||||
| | -^^^^^^^ method cannot be called due to unsatisfied trait bounds
|
||||
| |_________|
|
||||
|
|
||||
--> $SRC_DIR/core/src/iter/adapters/take_while.rs:LL:COL
|
||||
|
|
||||
= note: doesn't satisfy `<_ as Iterator>::Item = &_`
|
||||
--> $SRC_DIR/core/src/iter/adapters/cloned.rs:LL:COL
|
||||
|
|
||||
= note: doesn't satisfy `_: Iterator`
|
||||
|
|
||||
= note: the following trait bounds were not satisfied:
|
||||
`<TakeWhile<&mut std::vec::IntoIter<u8>, {closure@$DIR/issue-31173.rs:7:21: 7:25}> as Iterator>::Item = &_`
|
||||
|
Loading…
Reference in New Issue
Block a user