Skip to content

Commit caeda85

Browse files
Deduplicate implied supertraits for pretty printing
1 parent a74b042 commit caeda85

File tree

5 files changed

+45
-32
lines changed

5 files changed

+45
-32
lines changed

compiler/rustc_middle/src/ty/print/pretty.rs

+13
Original file line numberDiff line numberDiff line change
@@ -1293,6 +1293,19 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
12931293
// FIXME(eddyb) avoid printing twice (needed to ensure
12941294
// that the auto traits are sorted *and* printed via cx).
12951295
let mut auto_traits: Vec<_> = predicates.auto_traits().collect();
1296+
let principal_super_traits: FxHashSet<_> = predicates
1297+
.principal()
1298+
.into_iter()
1299+
.flat_map(|principal| {
1300+
supertraits_for_pretty_printing(
1301+
self.tcx(),
1302+
principal.with_self_ty(self.tcx(), self.tcx().types.trait_object_dummy_self),
1303+
)
1304+
.map(|trait_ref| trait_ref.def_id())
1305+
})
1306+
.collect();
1307+
1308+
auto_traits.retain(|def_id| !principal_super_traits.contains(def_id));
12961309

12971310
// The auto traits come ordered by `DefPathHash`. While
12981311
// `DefPathHash` is *stable* in the sense that it depends on

tests/ui/coherence/coherence-impl-trait-for-marker-trait-negative.stderr

+11-11
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,40 @@
1-
error[E0371]: the object type `(dyn Object + Marker1 + Marker2 + 'static)` automatically implements the trait `Marker1`
1+
error[E0371]: the object type `(dyn Object + Marker2 + 'static)` automatically implements the trait `Marker1`
22
--> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:15:1
33
|
44
LL | impl !Marker1 for dyn Object + Marker2 {}
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Object + Marker1 + Marker2 + 'static)` automatically implements trait `Marker1`
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Object + Marker2 + 'static)` automatically implements trait `Marker1`
66

7-
error[E0371]: the object type `(dyn Object + Marker1 + Marker2 + 'static)` automatically implements the trait `Marker1`
7+
error[E0371]: the object type `(dyn Object + Marker2 + 'static)` automatically implements the trait `Marker1`
88
--> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:15:1
99
|
1010
LL | impl !Marker1 for dyn Object + Marker2 {}
11-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Object + Marker1 + Marker2 + 'static)` automatically implements trait `Marker1`
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Object + Marker2 + 'static)` automatically implements trait `Marker1`
1212
|
1313
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
1414

15-
error[E0321]: traits with a default impl, like `Marker1`, cannot be implemented for trait object `(dyn Object + Marker1 + Marker2 + 'static)`
15+
error[E0321]: traits with a default impl, like `Marker1`, cannot be implemented for trait object `(dyn Object + Marker2 + 'static)`
1616
--> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:15:1
1717
|
1818
LL | impl !Marker1 for dyn Object + Marker2 {}
1919
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2020
|
2121
= note: a trait object implements `Marker1` if and only if `Marker1` is one of the trait object's trait bounds
2222

23-
error[E0371]: the object type `(dyn Object + Marker1 + Marker2 + 'static)` automatically implements the trait `Marker2`
23+
error[E0371]: the object type `(dyn Object + Marker2 + 'static)` automatically implements the trait `Marker2`
2424
--> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:21:1
2525
|
2626
LL | impl !Marker2 for dyn Object + Marker2 {}
27-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Object + Marker1 + Marker2 + 'static)` automatically implements trait `Marker2`
27+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Object + Marker2 + 'static)` automatically implements trait `Marker2`
2828

29-
error[E0321]: traits with a default impl, like `Marker2`, cannot be implemented for trait object `(dyn Object + Marker1 + Marker2 + 'static)`
29+
error[E0321]: traits with a default impl, like `Marker2`, cannot be implemented for trait object `(dyn Object + Marker2 + 'static)`
3030
--> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:21:1
3131
|
3232
LL | impl !Marker2 for dyn Object + Marker2 {}
3333
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3434
|
3535
= note: a trait object implements `Marker2` if and only if `Marker2` is one of the trait object's trait bounds
3636

37-
error[E0321]: traits with a default impl, like `Marker2`, cannot be implemented for trait object `(dyn Object + Marker1 + 'static)`
37+
error[E0321]: traits with a default impl, like `Marker2`, cannot be implemented for trait object `(dyn Object + 'static)`
3838
--> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:29:1
3939
|
4040
LL | impl !Marker2 for dyn Object {}
@@ -53,13 +53,13 @@ LL | impl !Send for dyn Marker2 {}
5353
|
5454
= note: define and implement a trait or new type instead
5555

56-
error[E0321]: cross-crate traits with a default impl, like `Send`, can only be implemented for a struct/enum type, not `(dyn Object + Marker1 + 'static)`
56+
error[E0321]: cross-crate traits with a default impl, like `Send`, can only be implemented for a struct/enum type, not `(dyn Object + 'static)`
5757
--> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:30:1
5858
|
5959
LL | impl !Send for dyn Object {}
6060
| ^^^^^^^^^^^^^^^^^^^^^^^^^ can't implement cross-crate trait with a default impl for non-struct/enum type
6161

62-
error[E0321]: cross-crate traits with a default impl, like `Send`, can only be implemented for a struct/enum type, not `(dyn Object + Marker1 + Marker2 + 'static)`
62+
error[E0321]: cross-crate traits with a default impl, like `Send`, can only be implemented for a struct/enum type, not `(dyn Object + Marker2 + 'static)`
6363
--> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:31:1
6464
|
6565
LL | impl !Send for dyn Object + Marker2 {}

tests/ui/coherence/coherence-impl-trait-for-marker-trait-positive.stderr

+11-11
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,40 @@
1-
error[E0371]: the object type `(dyn Object + Marker1 + Marker2 + 'static)` automatically implements the trait `Marker1`
1+
error[E0371]: the object type `(dyn Object + Marker2 + 'static)` automatically implements the trait `Marker1`
22
--> $DIR/coherence-impl-trait-for-marker-trait-positive.rs:15:1
33
|
44
LL | impl Marker1 for dyn Object + Marker2 {}
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Object + Marker1 + Marker2 + 'static)` automatically implements trait `Marker1`
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Object + Marker2 + 'static)` automatically implements trait `Marker1`
66

7-
error[E0371]: the object type `(dyn Object + Marker1 + Marker2 + 'static)` automatically implements the trait `Marker1`
7+
error[E0371]: the object type `(dyn Object + Marker2 + 'static)` automatically implements the trait `Marker1`
88
--> $DIR/coherence-impl-trait-for-marker-trait-positive.rs:15:1
99
|
1010
LL | impl Marker1 for dyn Object + Marker2 {}
11-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Object + Marker1 + Marker2 + 'static)` automatically implements trait `Marker1`
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Object + Marker2 + 'static)` automatically implements trait `Marker1`
1212
|
1313
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
1414

15-
error[E0321]: traits with a default impl, like `Marker1`, cannot be implemented for trait object `(dyn Object + Marker1 + Marker2 + 'static)`
15+
error[E0321]: traits with a default impl, like `Marker1`, cannot be implemented for trait object `(dyn Object + Marker2 + 'static)`
1616
--> $DIR/coherence-impl-trait-for-marker-trait-positive.rs:15:1
1717
|
1818
LL | impl Marker1 for dyn Object + Marker2 {}
1919
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2020
|
2121
= note: a trait object implements `Marker1` if and only if `Marker1` is one of the trait object's trait bounds
2222

23-
error[E0371]: the object type `(dyn Object + Marker1 + Marker2 + 'static)` automatically implements the trait `Marker2`
23+
error[E0371]: the object type `(dyn Object + Marker2 + 'static)` automatically implements the trait `Marker2`
2424
--> $DIR/coherence-impl-trait-for-marker-trait-positive.rs:20:1
2525
|
2626
LL | impl Marker2 for dyn Object + Marker2 {}
27-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Object + Marker1 + Marker2 + 'static)` automatically implements trait `Marker2`
27+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Object + Marker2 + 'static)` automatically implements trait `Marker2`
2828

29-
error[E0321]: traits with a default impl, like `Marker2`, cannot be implemented for trait object `(dyn Object + Marker1 + Marker2 + 'static)`
29+
error[E0321]: traits with a default impl, like `Marker2`, cannot be implemented for trait object `(dyn Object + Marker2 + 'static)`
3030
--> $DIR/coherence-impl-trait-for-marker-trait-positive.rs:20:1
3131
|
3232
LL | impl Marker2 for dyn Object + Marker2 {}
3333
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3434
|
3535
= note: a trait object implements `Marker2` if and only if `Marker2` is one of the trait object's trait bounds
3636

37-
error[E0321]: traits with a default impl, like `Marker2`, cannot be implemented for trait object `(dyn Object + Marker1 + 'static)`
37+
error[E0321]: traits with a default impl, like `Marker2`, cannot be implemented for trait object `(dyn Object + 'static)`
3838
--> $DIR/coherence-impl-trait-for-marker-trait-positive.rs:28:1
3939
|
4040
LL | impl Marker2 for dyn Object {}
@@ -53,13 +53,13 @@ LL | unsafe impl Send for dyn Marker2 {}
5353
|
5454
= note: define and implement a trait or new type instead
5555

56-
error[E0321]: cross-crate traits with a default impl, like `Send`, can only be implemented for a struct/enum type, not `(dyn Object + Marker1 + 'static)`
56+
error[E0321]: cross-crate traits with a default impl, like `Send`, can only be implemented for a struct/enum type, not `(dyn Object + 'static)`
5757
--> $DIR/coherence-impl-trait-for-marker-trait-positive.rs:29:1
5858
|
5959
LL | unsafe impl Send for dyn Object {}
6060
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't implement cross-crate trait with a default impl for non-struct/enum type
6161

62-
error[E0321]: cross-crate traits with a default impl, like `Send`, can only be implemented for a struct/enum type, not `(dyn Object + Marker1 + Marker2 + 'static)`
62+
error[E0321]: cross-crate traits with a default impl, like `Send`, can only be implemented for a struct/enum type, not `(dyn Object + Marker2 + 'static)`
6363
--> $DIR/coherence-impl-trait-for-marker-trait-positive.rs:30:1
6464
|
6565
LL | unsafe impl Send for dyn Object + Marker2 {}

tests/ui/traits/trait-upcasting/subtrait-method.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -51,17 +51,17 @@ fn main() {
5151

5252
let bar: &dyn Bar = baz;
5353
bar.c();
54-
//~^ ERROR no method named `c` found for reference `&dyn Bar + Send + Sync` in the current scope [E0599]
54+
//~^ ERROR no method named `c` found for reference `&dyn Bar` in the current scope [E0599]
5555

5656
let foo: &dyn Foo = baz;
5757
foo.b();
58-
//~^ ERROR no method named `b` found for reference `&dyn Foo + Send + Sync` in the current scope [E0599]
58+
//~^ ERROR no method named `b` found for reference `&dyn Foo` in the current scope [E0599]
5959
foo.c();
60-
//~^ ERROR no method named `c` found for reference `&dyn Foo + Send + Sync` in the current scope [E0599]
60+
//~^ ERROR no method named `c` found for reference `&dyn Foo` in the current scope [E0599]
6161

6262
let foo: &dyn Foo = bar;
6363
foo.b();
64-
//~^ ERROR no method named `b` found for reference `&dyn Foo + Send + Sync` in the current scope [E0599]
64+
//~^ ERROR no method named `b` found for reference `&dyn Foo` in the current scope [E0599]
6565
foo.c();
66-
//~^ ERROR no method named `c` found for reference `&dyn Foo + Send + Sync` in the current scope [E0599]
66+
//~^ ERROR no method named `c` found for reference `&dyn Foo` in the current scope [E0599]
6767
}

tests/ui/traits/trait-upcasting/subtrait-method.stderr

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error[E0599]: no method named `c` found for reference `&dyn Bar + Send + Sync` in the current scope
1+
error[E0599]: no method named `c` found for reference `&dyn Bar` in the current scope
22
--> $DIR/subtrait-method.rs:53:9
33
|
44
LL | bar.c();
@@ -11,7 +11,7 @@ note: `Baz` defines an item `c`, perhaps you need to implement it
1111
LL | trait Baz: Bar {
1212
| ^^^^^^^^^^^^^^
1313

14-
error[E0599]: no method named `b` found for reference `&dyn Foo + Send + Sync` in the current scope
14+
error[E0599]: no method named `b` found for reference `&dyn Foo` in the current scope
1515
--> $DIR/subtrait-method.rs:57:9
1616
|
1717
LL | foo.b();
@@ -24,7 +24,7 @@ note: `Bar` defines an item `b`, perhaps you need to implement it
2424
LL | trait Bar: Foo {
2525
| ^^^^^^^^^^^^^^
2626

27-
error[E0599]: no method named `c` found for reference `&dyn Foo + Send + Sync` in the current scope
27+
error[E0599]: no method named `c` found for reference `&dyn Foo` in the current scope
2828
--> $DIR/subtrait-method.rs:59:9
2929
|
3030
LL | foo.c();
@@ -37,7 +37,7 @@ note: `Baz` defines an item `c`, perhaps you need to implement it
3737
LL | trait Baz: Bar {
3838
| ^^^^^^^^^^^^^^
3939

40-
error[E0599]: no method named `b` found for reference `&dyn Foo + Send + Sync` in the current scope
40+
error[E0599]: no method named `b` found for reference `&dyn Foo` in the current scope
4141
--> $DIR/subtrait-method.rs:63:9
4242
|
4343
LL | foo.b();
@@ -50,7 +50,7 @@ note: `Bar` defines an item `b`, perhaps you need to implement it
5050
LL | trait Bar: Foo {
5151
| ^^^^^^^^^^^^^^
5252

53-
error[E0599]: no method named `c` found for reference `&dyn Foo + Send + Sync` in the current scope
53+
error[E0599]: no method named `c` found for reference `&dyn Foo` in the current scope
5454
--> $DIR/subtrait-method.rs:65:9
5555
|
5656
LL | foo.c();

0 commit comments

Comments
 (0)