Skip to content

Commit

Permalink
Deduplicate implied supertraits for pretty printing
Browse files Browse the repository at this point in the history
  • Loading branch information
compiler-errors committed Jan 10, 2024
1 parent 32a2569 commit 468280f
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 32 deletions.
13 changes: 13 additions & 0 deletions compiler/rustc_middle/src/ty/print/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1293,6 +1293,19 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
// FIXME(eddyb) avoid printing twice (needed to ensure
// that the auto traits are sorted *and* printed via cx).
let mut auto_traits: Vec<_> = predicates.auto_traits().collect();
let principal_super_traits: FxHashSet<_> = predicates
.principal()
.into_iter()
.flat_map(|principal| {
supertraits_for_pretty_printing(
self.tcx(),
principal.with_self_ty(self.tcx(), self.tcx().types.trait_object_dummy_self),
)
.map(|trait_ref| trait_ref.def_id())
})
.collect();

auto_traits.retain(|def_id| !principal_super_traits.contains(def_id));

// The auto traits come ordered by `DefPathHash`. While
// `DefPathHash` is *stable* in the sense that it depends on
Expand Down
Original file line number Diff line number Diff line change
@@ -1,40 +1,40 @@
error[E0371]: the object type `(dyn Object + Marker1 + Marker2 + 'static)` automatically implements the trait `Marker1`
error[E0371]: the object type `(dyn Object + Marker2 + 'static)` automatically implements the trait `Marker1`
--> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:15:1
|
LL | impl !Marker1 for dyn Object + Marker2 {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Object + Marker1 + Marker2 + 'static)` automatically implements trait `Marker1`
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Object + Marker2 + 'static)` automatically implements trait `Marker1`

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

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

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

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

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

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

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)`
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)`
--> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:31:1
|
LL | impl !Send for dyn Object + Marker2 {}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,40 +1,40 @@
error[E0371]: the object type `(dyn Object + Marker1 + Marker2 + 'static)` automatically implements the trait `Marker1`
error[E0371]: the object type `(dyn Object + Marker2 + 'static)` automatically implements the trait `Marker1`
--> $DIR/coherence-impl-trait-for-marker-trait-positive.rs:15:1
|
LL | impl Marker1 for dyn Object + Marker2 {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Object + Marker1 + Marker2 + 'static)` automatically implements trait `Marker1`
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Object + Marker2 + 'static)` automatically implements trait `Marker1`

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

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

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

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

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

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

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)`
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)`
--> $DIR/coherence-impl-trait-for-marker-trait-positive.rs:30:1
|
LL | unsafe impl Send for dyn Object + Marker2 {}
Expand Down
10 changes: 5 additions & 5 deletions tests/ui/traits/trait-upcasting/subtrait-method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,17 +51,17 @@ fn main() {

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

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

let foo: &dyn Foo = bar;
foo.b();
//~^ ERROR no method named `b` found for reference `&dyn Foo + Send + Sync` in the current scope [E0599]
//~^ ERROR no method named `b` found for reference `&dyn Foo` in the current scope [E0599]
foo.c();
//~^ ERROR no method named `c` found for reference `&dyn Foo + Send + Sync` in the current scope [E0599]
//~^ ERROR no method named `c` found for reference `&dyn Foo` in the current scope [E0599]
}
10 changes: 5 additions & 5 deletions tests/ui/traits/trait-upcasting/subtrait-method.stderr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error[E0599]: no method named `c` found for reference `&dyn Bar + Send + Sync` in the current scope
error[E0599]: no method named `c` found for reference `&dyn Bar` in the current scope
--> $DIR/subtrait-method.rs:53:9
|
LL | bar.c();
Expand All @@ -11,7 +11,7 @@ note: `Baz` defines an item `c`, perhaps you need to implement it
LL | trait Baz: Bar {
| ^^^^^^^^^^^^^^

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

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

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

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

0 comments on commit 468280f

Please sign in to comment.