Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -2460,10 +2460,42 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
};
err.span_help(span, msg);
} else {
// When more than 5 tuples implement the same trait, the output might be very verbose
// Instead of displaying each of these, we sort the candidates by arity in ascending
// order, then we compute the min and the max arity, ensuring that the arities are
// consecutive (by step of one). If these conditions are met, then the output is shown
// as a range of tuples [tuple_min_arity:tuple_max_arity]
let mut tuple_min_arity = usize::MAX;
Comment thread
rperier marked this conversation as resolved.
let mut tuple_max_arity = 0_usize;
let mut last_arity = None;
let mut all_types_tuples_cont_arity = true;
candidates.sort_by(|(c1, _), (c2, _)| {
if let ty::Tuple(tys1) = c1.self_ty().kind()
&& let ty::Tuple(tys2) = c2.self_ty().kind()
{
tys1.len().cmp(&tys2.len())
} else {
std::cmp::Ordering::Equal
}
});
let candidate_names: Vec<String> = candidates
.iter()
.map(|(c, _)| {
if all_traits_equal {
if all_types_tuples_cont_arity
&& let ty::Tuple(tys) = c.self_ty().kind()
&& last_arity.map_or(1, |a: usize| a.abs_diff(tys.len())) == 1
{
last_arity = Some(tys.len());
if tys.len() > tuple_max_arity {
tuple_max_arity = tys.len();
}
if tys.len() < tuple_min_arity {
tuple_min_arity = tys.len();
}
} else {
all_types_tuples_cont_arity = false;
}
format!(
"\n {}",
self.tcx.short_string(c.self_ty(), err.long_ty_path())
Expand All @@ -2484,6 +2516,29 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
}
})
.collect();

let details = if all_traits_equal && all_types_tuples_cont_arity {
if tuple_min_arity == 0 {
format!("up to tuples of arity {tuple_max_arity}")
} else {
format!(
"for tuples of arity {tuple_min_arity} up to and including {tuple_max_arity}"
)
}
} else {
String::new()
};
let (candidate_names, end) = if all_traits_equal && all_types_tuples_cont_arity {
(
vec![
// (T₁, T₂, …, Tₙ)
format!("\n (T\u{2081}, T\u{2082}, …, T\u{2099}) {details}"),
],
1,
)
} else {
(candidate_names, end)
};
let msg = if all_types_equal {
format!(
"`{}` implements trait `{}`",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,14 @@ LL | help(1)?;
| ^^^^^^^ the trait `From<!>` is not implemented for `()`
|
= help: the following other types implement trait `From<T>`:
`(T,)` implements `From<[T; 1]>`
Comment thread
rperier marked this conversation as resolved.
`(T, T)` implements `From<[T; 2]>`
`(T, T, T)` implements `From<[T; 3]>`
`(T, T, T, T)` implements `From<[T; 4]>`
`(T, T, T, T, T)` implements `From<[T; 5]>`
`(T, T, T, T, T, T)` implements `From<[T; 6]>`
`(T, T, T, T, T, T, T)` implements `From<[T; 7]>`
`(T, T, T, T, T, T, T, T)` implements `From<[T; 8]>`
`(T, T, T, T, T, T, T, T, T)` implements `From<[T; 9]>`
and 4 others
= note: required for `!` to implement `Into<()>`
note: required by a bound in `help`
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
use std::fmt::Debug;

fn testing_debug<T: Debug>(t: T) {}
fn testing_mytrait<T: MyTrait>(t: T) {}

trait MyTrait {}

impl MyTrait for (i8,) {}
impl MyTrait for (i8,i8) {}
impl MyTrait for (i8,i8,i8) {}
impl MyTrait for (i8,i8,i8,i8) {}
impl MyTrait for (i8,i8,i8,i8,i8) {}

struct Foo;

fn main() {
testing_debug((1, Foo));
//~^ ERROR `Foo` doesn't implement `Debug` [E0277]
testing_mytrait((1, Foo));
//~^ ERROR the trait bound `({integer}, Foo): MyTrait` is not satisfied [E0277]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
error[E0277]: `Foo` doesn't implement `Debug`
--> $DIR/multiple_tuples_implement_same_trait_continuous_arities.rs:17:23
|
LL | testing_debug((1, Foo));
| ------------- ^^^ the trait `Debug` is not implemented for `Foo`
| |
| required by a bound introduced by this call
|
= help: the following other types implement trait `Debug`:
(T₁, T₂, …, Tₙ) up to tuples of arity 12
and 5 others
= note: required for `({integer}, Foo)` to implement `Debug`
note: required by a bound in `testing_debug`
--> $DIR/multiple_tuples_implement_same_trait_continuous_arities.rs:3:21
|
LL | fn testing_debug<T: Debug>(t: T) {}
| ^^^^^ required by this bound in `testing_debug`
help: consider annotating `Foo` with `#[derive(Debug)]`
|
LL + #[derive(Debug)]
LL | struct Foo;
|

error[E0277]: the trait bound `({integer}, Foo): MyTrait` is not satisfied
--> $DIR/multiple_tuples_implement_same_trait_continuous_arities.rs:19:21
|
LL | testing_mytrait((1, Foo));
| --------------- ^^^^^^^^ the trait `MyTrait` is not implemented for `({integer}, Foo)`
| |
| required by a bound introduced by this call
|
= help: the following other types implement trait `MyTrait`:
(T₁, T₂, …, Tₙ) for tuples of arity 1 up to and including 5
note: required by a bound in `testing_mytrait`
--> $DIR/multiple_tuples_implement_same_trait_continuous_arities.rs:4:23
|
LL | fn testing_mytrait<T: MyTrait>(t: T) {}
| ^^^^^^^ required by this bound in `testing_mytrait`

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0277`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
fn testing_mytrait<T: MyTrait>(t: T) {}
fn testing_anothertrait<T: AnotherTrait>(t: T) {}

trait MyTrait {}

impl MyTrait for (i8,) {}
impl MyTrait for (i8,i8,i8) {}
impl MyTrait for (i8,i8,i8,i8) {}
impl MyTrait for (i8,i8,i8,i8,i8) {}
impl MyTrait for (i8,i8,i8,i8,i8,i8) {}

trait AnotherTrait {}
impl AnotherTrait for (i8,) {}
impl AnotherTrait for (i8,i8) {}

struct Foo;

fn main() {
testing_mytrait((1, Foo));
//~^ ERROR the trait bound `({integer}, Foo): MyTrait` is not satisfied [E0277]
testing_anothertrait((1, Foo));
//~^ ERROR the trait bound `({integer}, Foo): AnotherTrait` is not satisfied [E0277]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
error[E0277]: the trait bound `({integer}, Foo): MyTrait` is not satisfied
--> $DIR/multiple_tuples_implement_same_trait_discontinuous_arities.rs:19:21
|
LL | testing_mytrait((1, Foo));
| --------------- ^^^^^^^^ the trait `MyTrait` is not implemented for `({integer}, Foo)`
| |
| required by a bound introduced by this call
|
= help: the following other types implement trait `MyTrait`:
(i8,)
(i8, i8, i8)
(i8, i8, i8, i8)
(i8, i8, i8, i8, i8)
(i8, i8, i8, i8, i8, i8)
note: required by a bound in `testing_mytrait`
--> $DIR/multiple_tuples_implement_same_trait_discontinuous_arities.rs:1:23
|
LL | fn testing_mytrait<T: MyTrait>(t: T) {}
| ^^^^^^^ required by this bound in `testing_mytrait`

error[E0277]: the trait bound `({integer}, Foo): AnotherTrait` is not satisfied
--> $DIR/multiple_tuples_implement_same_trait_discontinuous_arities.rs:21:26
|
LL | testing_anothertrait((1, Foo));
| -------------------- ^^^^^^^^ the trait `AnotherTrait` is not implemented for `({integer}, Foo)`
| |
| required by a bound introduced by this call
|
help: the following other types implement trait `AnotherTrait`
--> $DIR/multiple_tuples_implement_same_trait_discontinuous_arities.rs:13:1
|
LL | impl AnotherTrait for (i8,) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(i8,)`
LL | impl AnotherTrait for (i8,i8) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(i8, i8)`
note: required by a bound in `testing_anothertrait`
--> $DIR/multiple_tuples_implement_same_trait_discontinuous_arities.rs:2:28
|
LL | fn testing_anothertrait<T: AnotherTrait>(t: T) {}
| ^^^^^^^^^^^^ required by this bound in `testing_anothertrait`

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0277`.
2 changes: 1 addition & 1 deletion tests/ui/traits/const-traits/reservation-impl-ice.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ LL | impls_from::<()>();
| ^^ the trait `From<!>` is not implemented for `()`
|
= help: the following other types implement trait `From<T>`:
`(T,)` implements `From<[T; 1]>`
`(T, T)` implements `From<[T; 2]>`
`(T, T, T)` implements `From<[T; 3]>`
`(T, T, T, T)` implements `From<[T; 4]>`
`(T, T, T, T, T)` implements `From<[T; 5]>`
`(T, T, T, T, T, T)` implements `From<[T; 6]>`
`(T, T, T, T, T, T, T)` implements `From<[T; 7]>`
`(T, T, T, T, T, T, T, T)` implements `From<[T; 8]>`
`(T, T, T, T, T, T, T, T, T)` implements `From<[T; 9]>`
and 4 others
note: required by a bound in `impls_from`
--> $DIR/reservation-impl-ice.rs:4:24
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/try-trait/issue-32709.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ LL | Err(5)?;
|
= note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
= help: the following other types implement trait `From<T>`:
`(T,)` implements `From<[T; 1]>`
`(T, T)` implements `From<[T; 2]>`
`(T, T, T)` implements `From<[T; 3]>`
`(T, T, T, T)` implements `From<[T; 4]>`
`(T, T, T, T, T)` implements `From<[T; 5]>`
`(T, T, T, T, T, T)` implements `From<[T; 6]>`
`(T, T, T, T, T, T, T)` implements `From<[T; 7]>`
`(T, T, T, T, T, T, T, T)` implements `From<[T; 8]>`
`(T, T, T, T, T, T, T, T, T)` implements `From<[T; 9]>`
and 4 others

error: aborting due to 1 previous error
Expand Down
Loading