Skip to content

Commit 97ba0c7

Browse files
committed
Auto merge of rust-lang#75536 - estebank:e0255-suggestion, r=varkor
Tweak output of E0225 When encountering multiple non-auto trait bounds suggest creating a new trait and explain what auto-traits are. _Inspired by https://fasterthanli.me/articles/frustrated-its-not-you-its-rust_
2 parents de32266 + 0afb9c2 commit 97ba0c7

File tree

11 files changed

+295
-139
lines changed

11 files changed

+295
-139
lines changed

src/librustc_trait_selection/traits/util.rs

+8-4
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,14 @@ impl<'tcx> TraitAliasExpansionInfo<'tcx> {
5353
diag.span_label(*sp, format!("referenced here ({})", use_desc));
5454
}
5555
}
56-
diag.span_label(
57-
self.bottom().1,
58-
format!("trait alias used in trait object type ({})", use_desc),
59-
);
56+
if self.top().1 != self.bottom().1 {
57+
// When the trait object is in a return type these two spans match, we don't want
58+
// redundant labels.
59+
diag.span_label(
60+
self.bottom().1,
61+
format!("trait alias used in trait object type ({})", use_desc),
62+
);
63+
}
6064
}
6165

6266
pub fn trait_ref(&self) -> ty::PolyTraitRef<'tcx> {

src/librustc_typeck/astconv.rs

+14
Original file line numberDiff line numberDiff line change
@@ -1666,6 +1666,20 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
16661666
"additional use",
16671667
);
16681668
first_trait.label_with_exp_info(&mut err, "first non-auto trait", "first use");
1669+
err.help(&format!(
1670+
"consider creating a new trait with all of these as super-traits and using that \
1671+
trait here instead: `trait NewTrait: {} {{}}`",
1672+
regular_traits
1673+
.iter()
1674+
.map(|t| t.trait_ref().print_only_trait_path().to_string())
1675+
.collect::<Vec<_>>()
1676+
.join(" + "),
1677+
));
1678+
err.note(
1679+
"auto-traits like `Send` and `Sync` are traits that have special properties; \
1680+
for more information on them, visit \
1681+
<https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>",
1682+
);
16691683
err.emit();
16701684
}
16711685

src/test/ui/associated-types/missing-associated-types.stderr

+20-20
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@ error[E0225]: only auto traits can be used as additional traits in a trait objec
22
--> $DIR/missing-associated-types.rs:12:32
33
|
44
LL | type Foo<Rhs> = dyn Add<Rhs> + Sub<Rhs> + X<Rhs> + Y<Rhs>;
5-
| -------- ^^^^^^^^
6-
| | |
7-
| | additional non-auto trait
8-
| | trait alias used in trait object type (additional use)
5+
| -------- ^^^^^^^^ additional non-auto trait
6+
| |
97
| first non-auto trait
10-
| trait alias used in trait object type (first use)
8+
|
9+
= help: consider creating a new trait with all of these as super-traits and using that trait here instead: `trait NewTrait: std::ops::Add<Rhs> + std::ops::Sub<Rhs> + X<Rhs> + Y<Rhs> {}`
10+
= note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
1111

1212
error[E0191]: the value of the associated types `A` (from trait `Y`), `Output` (from trait `std::ops::Add`), `Output` (from trait `std::ops::Mul`), `Output` (from trait `std::ops::Sub`) must be specified
1313
--> $DIR/missing-associated-types.rs:12:21
@@ -31,12 +31,12 @@ error[E0225]: only auto traits can be used as additional traits in a trait objec
3131
--> $DIR/missing-associated-types.rs:15:32
3232
|
3333
LL | type Bar<Rhs> = dyn Add<Rhs> + Sub<Rhs> + X<Rhs> + Z<Rhs>;
34-
| -------- ^^^^^^^^
35-
| | |
36-
| | additional non-auto trait
37-
| | trait alias used in trait object type (additional use)
34+
| -------- ^^^^^^^^ additional non-auto trait
35+
| |
3836
| first non-auto trait
39-
| trait alias used in trait object type (first use)
37+
|
38+
= help: consider creating a new trait with all of these as super-traits and using that trait here instead: `trait NewTrait: std::ops::Add<Rhs> + std::ops::Sub<Rhs> + X<Rhs> + Z<Rhs> {}`
39+
= note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
4040

4141
error[E0191]: the value of the associated types `A` (from trait `Z`), `B` (from trait `Z`), `Output` (from trait `std::ops::Add`), `Output` (from trait `std::ops::Div`), `Output` (from trait `std::ops::Div`), `Output` (from trait `std::ops::Mul`), `Output` (from trait `std::ops::Sub`) must be specified
4242
--> $DIR/missing-associated-types.rs:15:21
@@ -67,12 +67,12 @@ error[E0225]: only auto traits can be used as additional traits in a trait objec
6767
--> $DIR/missing-associated-types.rs:18:32
6868
|
6969
LL | type Baz<Rhs> = dyn Add<Rhs> + Sub<Rhs> + Y<Rhs>;
70-
| -------- ^^^^^^^^
71-
| | |
72-
| | additional non-auto trait
73-
| | trait alias used in trait object type (additional use)
70+
| -------- ^^^^^^^^ additional non-auto trait
71+
| |
7472
| first non-auto trait
75-
| trait alias used in trait object type (first use)
73+
|
74+
= help: consider creating a new trait with all of these as super-traits and using that trait here instead: `trait NewTrait: std::ops::Add<Rhs> + std::ops::Sub<Rhs> + Y<Rhs> {}`
75+
= note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
7676

7777
error[E0191]: the value of the associated types `A` (from trait `Y`), `Output` (from trait `std::ops::Add`), `Output` (from trait `std::ops::Sub`) must be specified
7878
--> $DIR/missing-associated-types.rs:18:21
@@ -95,12 +95,12 @@ error[E0225]: only auto traits can be used as additional traits in a trait objec
9595
--> $DIR/missing-associated-types.rs:21:32
9696
|
9797
LL | type Bat<Rhs> = dyn Add<Rhs> + Sub<Rhs> + Fine<Rhs>;
98-
| -------- ^^^^^^^^
99-
| | |
100-
| | additional non-auto trait
101-
| | trait alias used in trait object type (additional use)
98+
| -------- ^^^^^^^^ additional non-auto trait
99+
| |
102100
| first non-auto trait
103-
| trait alias used in trait object type (first use)
101+
|
102+
= help: consider creating a new trait with all of these as super-traits and using that trait here instead: `trait NewTrait: std::ops::Add<Rhs> + std::ops::Sub<Rhs> + Fine<Rhs> {}`
103+
= note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
104104

105105
error[E0191]: the value of the associated types `Output` (from trait `std::ops::Add`), `Output` (from trait `std::ops::Sub`) must be specified
106106
--> $DIR/missing-associated-types.rs:21:21

src/test/ui/bad/bad-sized.stderr

+5-5
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@ error[E0225]: only auto traits can be used as additional traits in a trait objec
22
--> $DIR/bad-sized.rs:4:28
33
|
44
LL | let x: Vec<dyn Trait + Sized> = Vec::new();
5-
| ----- ^^^^^
6-
| | |
7-
| | additional non-auto trait
8-
| | trait alias used in trait object type (additional use)
5+
| ----- ^^^^^ additional non-auto trait
6+
| |
97
| first non-auto trait
10-
| trait alias used in trait object type (first use)
8+
|
9+
= help: consider creating a new trait with all of these as super-traits and using that trait here instead: `trait NewTrait: Trait + std::marker::Sized {}`
10+
= note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
1111

1212
error[E0277]: the size for values of type `dyn Trait` cannot be known at compilation time
1313
--> $DIR/bad-sized.rs:4:12

src/test/ui/error-codes/E0225.stderr

+8-5
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@ error[E0225]: only auto traits can be used as additional traits in a trait objec
22
--> $DIR/E0225.rs:6:36
33
|
44
LL | let _: Box<dyn std::io::Read + std::io::Write>;
5-
| ------------- ^^^^^^^^^^^^^^
6-
| | |
7-
| | additional non-auto trait
8-
| | trait alias used in trait object type (additional use)
5+
| ------------- ^^^^^^^^^^^^^^ additional non-auto trait
6+
| |
97
| first non-auto trait
10-
| trait alias used in trait object type (first use)
8+
|
9+
= help: consider creating a new trait with all of these as super-traits and using that trait here instead: `trait NewTrait: std::io::Read + std::io::Write {}`
10+
= note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
1111

1212
error[E0225]: only auto traits can be used as additional traits in a trait object
1313
--> $DIR/E0225.rs:8:20
@@ -22,6 +22,9 @@ LL | let _: Box<dyn Foo>;
2222
| |
2323
| trait alias used in trait object type (additional use)
2424
| trait alias used in trait object type (first use)
25+
|
26+
= help: consider creating a new trait with all of these as super-traits and using that trait here instead: `trait NewTrait: std::io::Read + std::io::Write {}`
27+
= note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
2528

2629
error: aborting due to 2 previous errors
2730

src/test/ui/issues/issue-22560.stderr

+5-5
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,12 @@ error[E0225]: only auto traits can be used as additional traits in a trait objec
2828
--> $DIR/issue-22560.rs:9:23
2929
|
3030
LL | type Test = dyn Add + Sub;
31-
| --- ^^^
32-
| | |
33-
| | additional non-auto trait
34-
| | trait alias used in trait object type (additional use)
31+
| --- ^^^ additional non-auto trait
32+
| |
3533
| first non-auto trait
36-
| trait alias used in trait object type (first use)
34+
|
35+
= help: consider creating a new trait with all of these as super-traits and using that trait here instead: `trait NewTrait: Add<[type error]> + Sub<[type error]> {}`
36+
= note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
3737

3838
error[E0191]: the value of the associated types `Output` (from trait `Add`), `Output` (from trait `Sub`) must be specified
3939
--> $DIR/issue-22560.rs:9:17

src/test/ui/issues/issue-32963.stderr

+10-10
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,23 @@ error[E0225]: only auto traits can be used as additional traits in a trait objec
22
--> $DIR/issue-32963.rs:8:31
33
|
44
LL | size_of_copy::<dyn Misc + Copy>();
5-
| ---- ^^^^
6-
| | |
7-
| | additional non-auto trait
8-
| | trait alias used in trait object type (additional use)
5+
| ---- ^^^^ additional non-auto trait
6+
| |
97
| first non-auto trait
10-
| trait alias used in trait object type (first use)
8+
|
9+
= help: consider creating a new trait with all of these as super-traits and using that trait here instead: `trait NewTrait: Misc + std::marker::Copy {}`
10+
= note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
1111

1212
error[E0225]: only auto traits can be used as additional traits in a trait object
1313
--> $DIR/issue-32963.rs:8:31
1414
|
1515
LL | size_of_copy::<dyn Misc + Copy>();
16-
| ---- ^^^^
17-
| | |
18-
| | additional non-auto trait
19-
| | trait alias used in trait object type (additional use)
16+
| ---- ^^^^ additional non-auto trait
17+
| |
2018
| first non-auto trait
21-
| trait alias used in trait object type (first use)
19+
|
20+
= help: consider creating a new trait with all of these as super-traits and using that trait here instead: `trait NewTrait: Misc + std::marker::Copy {}`
21+
= note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
2222

2323
error[E0277]: the trait bound `dyn Misc: std::marker::Copy` is not satisfied
2424
--> $DIR/issue-32963.rs:8:5

src/test/ui/parser/trait-object-trait-parens.stderr

+15-15
Original file line numberDiff line numberDiff line change
@@ -40,34 +40,34 @@ error[E0225]: only auto traits can be used as additional traits in a trait objec
4040
--> $DIR/trait-object-trait-parens.rs:8:35
4141
|
4242
LL | let _: Box<(Obj) + (?Sized) + (for<'a> Trait<'a>)>;
43-
| ----- ^^^^^^^^^^^^^^^^^^^
44-
| | |
45-
| | additional non-auto trait
46-
| | trait alias used in trait object type (additional use)
43+
| ----- ^^^^^^^^^^^^^^^^^^^ additional non-auto trait
44+
| |
4745
| first non-auto trait
48-
| trait alias used in trait object type (first use)
46+
|
47+
= help: consider creating a new trait with all of these as super-traits and using that trait here instead: `trait NewTrait: Obj + for<'a> Trait<'a> {}`
48+
= note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
4949

5050
error[E0225]: only auto traits can be used as additional traits in a trait object
5151
--> $DIR/trait-object-trait-parens.rs:12:49
5252
|
5353
LL | let _: Box<(?Sized) + (for<'a> Trait<'a>) + (Obj)>;
54-
| ------------------- ^^^^^
55-
| | |
56-
| | additional non-auto trait
57-
| | trait alias used in trait object type (additional use)
54+
| ------------------- ^^^^^ additional non-auto trait
55+
| |
5856
| first non-auto trait
59-
| trait alias used in trait object type (first use)
57+
|
58+
= help: consider creating a new trait with all of these as super-traits and using that trait here instead: `trait NewTrait: for<'a> Trait<'a> + Obj {}`
59+
= note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
6060

6161
error[E0225]: only auto traits can be used as additional traits in a trait object
6262
--> $DIR/trait-object-trait-parens.rs:16:38
6363
|
6464
LL | let _: Box<(for<'a> Trait<'a>) + (Obj) + (?Sized)>;
65-
| ----------------- ^^^^^
66-
| | |
67-
| | additional non-auto trait
68-
| | trait alias used in trait object type (additional use)
65+
| ----------------- ^^^^^ additional non-auto trait
66+
| |
6967
| first non-auto trait
70-
| trait alias used in trait object type (first use)
68+
|
69+
= help: consider creating a new trait with all of these as super-traits and using that trait here instead: `trait NewTrait: for<'a> Trait<'a> + Obj {}`
70+
= note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
7171

7272
error: aborting due to 6 previous errors; 3 warnings emitted
7373

0 commit comments

Comments
 (0)