Skip to content

Commit

Permalink
Rollup merge of rust-lang#88892 - estebank:trait-objects, r=petrochenkov
Browse files Browse the repository at this point in the history
Move object safety suggestions to the end of the error
  • Loading branch information
GuillaumeGomez authored Sep 16, 2021
2 parents 33f1fde + 9762116 commit 21f0b13
Show file tree
Hide file tree
Showing 28 changed files with 50 additions and 46 deletions.
12 changes: 8 additions & 4 deletions compiler/rustc_infer/src/traits/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,6 @@ pub fn report_object_safety_error(
messages.push(msg.clone());
}
}
if trait_span.is_some() {
// Only provide the help if its a local trait, otherwise it's not actionable.
violation.solution(&mut err);
}
}
}
let has_multi_span = !multi_span.is_empty();
Expand All @@ -104,5 +100,13 @@ pub fn report_object_safety_error(
to be resolvable dynamically; for more information visit \
<https://doc.rust-lang.org/reference/items/traits.html#object-safety>",
);
if trait_span.is_some() {
let mut reported_violations: Vec<_> = reported_violations.into_iter().collect();
reported_violations.sort();
for violation in reported_violations {
// Only provide the help if its a local trait, otherwise it's not actionable.
violation.solution(&mut err);
}
}
err
}
4 changes: 2 additions & 2 deletions compiler/rustc_middle/src/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -730,7 +730,7 @@ pub struct ImplSourceTraitAliasData<'tcx, N> {
pub nested: Vec<N>,
}

#[derive(Clone, Debug, PartialEq, Eq, Hash, HashStable)]
#[derive(Clone, Debug, PartialEq, Eq, Hash, HashStable, PartialOrd, Ord)]
pub enum ObjectSafetyViolation {
/// `Self: Sized` declared on the trait.
SizedSelf(SmallVec<[Span; 1]>),
Expand Down Expand Up @@ -879,7 +879,7 @@ impl ObjectSafetyViolation {
}

/// Reasons a method might not be object-safe.
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable)]
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable, PartialOrd, Ord)]
pub enum MethodViolationCode {
/// e.g., `fn foo()`
StaticMethod(Option<(&'static str, Span)>, Span, bool /* has args */),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ error[E0038]: the trait `Trait` cannot be made into an object
LL | impl dyn Trait {
| ^^^^^^^^^ `Trait` cannot be made into an object
|
= help: consider moving `N` to another trait
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> $DIR/associated-const-in-trait.rs:6:11
|
LL | trait Trait {
| ----- this trait cannot be made into an object...
LL | const N: usize;
| ^ ...because it contains this associated `const`
= help: consider moving `N` to another trait

error: aborting due to previous error

Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/associated-item/issue-48027.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,14 @@ error[E0038]: the trait `Bar` cannot be made into an object
LL | impl dyn Bar {}
| ^^^^^^^ `Bar` cannot be made into an object
|
= help: consider moving `X` to another trait
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> $DIR/issue-48027.rs:2:11
|
LL | trait Bar {
| --- this trait cannot be made into an object...
LL | const X: usize;
| ^ ...because it contains this associated `const`
= help: consider moving `X` to another trait

error: aborting due to 2 previous errors

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ error[E0038]: the trait `NotObjectSafe` cannot be made into an object
LL | impl NotObjectSafe for dyn NotObjectSafe { }
| ^^^^^^^^^^^^^^^^^ `NotObjectSafe` cannot be made into an object
|
= help: consider moving `eq` to another trait
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> $DIR/coherence-impl-trait-for-trait-object-safe.rs:6:43
|
LL | trait NotObjectSafe { fn eq(&self, other: Self); }
| ------------- ^^^^ ...because method `eq` references the `Self` type in this parameter
| |
| this trait cannot be made into an object...
= help: consider moving `eq` to another trait

error: aborting due to previous error

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ error[E0038]: the trait `Foo` cannot be made into an object
LL | fn use_dyn(v: &dyn Foo) {
| ^^^^^^^ `Foo` cannot be made into an object
|
= help: consider moving `test` to another trait
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> $DIR/object-safety-err-ret.rs:8:23
|
LL | trait Foo {
| --- this trait cannot be made into an object...
LL | fn test(&self) -> [u8; bar::<Self>()];
| ^^^^^^^^^^^^^^^^^^^ ...because method `test` references the `Self` type in its return type
= help: consider moving `test` to another trait

error: aborting due to previous error

Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/error-codes/E0038.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ error[E0038]: the trait `Trait` cannot be made into an object
LL | fn call_foo(x: Box<dyn Trait>) {
| ^^^^^^^^^ `Trait` cannot be made into an object
|
= help: consider moving `foo` to another trait
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> $DIR/E0038.rs:2:22
|
LL | trait Trait {
| ----- this trait cannot be made into an object...
LL | fn foo(&self) -> Self;
| ^^^^ ...because method `foo` references the `Self` type in its return type
= help: consider moving `foo` to another trait

error: aborting due to previous error

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,29 +40,29 @@ error[E0038]: the trait `NonObjectSafe3` cannot be made into an object
LL | fn takes_non_object_safe_box(obj: Box<dyn NonObjectSafe3>) {
| ^^^^^^^^^^^^^^^^^^ `NonObjectSafe3` cannot be made into an object
|
= help: consider moving `foo` to another trait
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> $DIR/feature-gate-object_safe_for_dispatch.rs:11:8
|
LL | trait NonObjectSafe3 {
| -------------- this trait cannot be made into an object...
LL | fn foo<T>(&self);
| ^^^ ...because method `foo` has generic type parameters
= help: consider moving `foo` to another trait

error[E0038]: the trait `NonObjectSafe4` cannot be made into an object
--> $DIR/feature-gate-object_safe_for_dispatch.rs:31:35
|
LL | fn return_non_object_safe_rc() -> std::rc::Rc<dyn NonObjectSafe4> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `NonObjectSafe4` cannot be made into an object
|
= help: consider moving `foo` to another trait
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> $DIR/feature-gate-object_safe_for_dispatch.rs:15:22
|
LL | trait NonObjectSafe4 {
| -------------- this trait cannot be made into an object...
LL | fn foo(&self, s: &Self);
| ^^^^^ ...because method `foo` references the `Self` type in this parameter
= help: consider moving `foo` to another trait

error[E0038]: the trait `NonObjectSafe1` cannot be made into an object
--> $DIR/feature-gate-object_safe_for_dispatch.rs:38:16
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ error[E0038]: the trait `Foo` cannot be made into an object
LL | fn f(_arg : Box<dyn for<'a> Foo<A<'a> = &'a ()>>) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Foo` cannot be made into an object
|
= help: consider moving `A` to another trait
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> $DIR/gat-in-trait-path.rs:5:10
|
LL | trait Foo {
| --- this trait cannot be made into an object...
LL | type A<'a> where Self: 'a;
| ^ ...because it contains the generic associated type `A`
= help: consider moving `A` to another trait

error: aborting due to previous error

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ error[E0038]: the trait `X` cannot be made into an object
LL | fn _func1<'a>(_x: Box<dyn X<Y<'a>=&'a ()>>) {}
| ^^^^^^^^^^^^^^^^^^^ `X` cannot be made into an object
|
= help: consider moving `Y` to another trait
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> $DIR/issue-67510-pass.rs:4:10
|
LL | trait X {
| - this trait cannot be made into an object...
LL | type Y<'a>;
| ^ ...because it contains the generic associated type `Y`
= help: consider moving `Y` to another trait

error: aborting due to previous error

Expand Down
4 changes: 2 additions & 2 deletions src/test/ui/generic-associated-types/issue-76535.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -20,29 +20,29 @@ error[E0038]: the trait `SuperTrait` cannot be made into an object
LL | let sub: Box<dyn SuperTrait<SubType = SubStruct>> = Box::new(SuperStruct::new(0));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `SuperTrait` cannot be made into an object
|
= help: consider moving `SubType` to another trait
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> $DIR/issue-76535.rs:6:10
|
LL | pub trait SuperTrait {
| ---------- this trait cannot be made into an object...
LL | type SubType<'a>: SubTrait;
| ^^^^^^^ ...because it contains the generic associated type `SubType`
= help: consider moving `SubType` to another trait

error[E0038]: the trait `SuperTrait` cannot be made into an object
--> $DIR/issue-76535.rs:36:57
|
LL | let sub: Box<dyn SuperTrait<SubType = SubStruct>> = Box::new(SuperStruct::new(0));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `SuperTrait` cannot be made into an object
|
= help: consider moving `SubType` to another trait
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> $DIR/issue-76535.rs:6:10
|
LL | pub trait SuperTrait {
| ---------- this trait cannot be made into an object...
LL | type SubType<'a>: SubTrait;
| ^^^^^^^ ...because it contains the generic associated type `SubType`
= help: consider moving `SubType` to another trait
= note: required because of the requirements on the impl of `CoerceUnsized<Box<dyn SuperTrait<SubType = SubStruct<'_>>>>` for `Box<SuperStruct>`
= note: required by cast to type `Box<dyn SuperTrait<SubType = SubStruct<'_>>>`

Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/generic-associated-types/issue-78671.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@ error[E0038]: the trait `CollectionFamily` cannot be made into an object
LL | Box::new(Family) as &dyn CollectionFamily<Member=usize>
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `CollectionFamily` cannot be made into an object
|
= help: consider moving `Member` to another trait
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> $DIR/issue-78671.rs:4:10
|
LL | trait CollectionFamily {
| ---------------- this trait cannot be made into an object...
LL | type Member<T>;
| ^^^^^^ ...because it contains the generic associated type `Member`
= help: consider moving `Member` to another trait

error: aborting due to 2 previous errors

Expand Down
4 changes: 2 additions & 2 deletions src/test/ui/generic-associated-types/issue-79422.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -20,29 +20,29 @@ error[E0038]: the trait `MapLike` cannot be made into an object
LL | as Box<dyn MapLike<u8, u8, VRefCont = dyn RefCont<'_, u8>>>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `MapLike` cannot be made into an object
|
= help: consider moving `VRefCont` to another trait
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> $DIR/issue-79422.rs:20:10
|
LL | trait MapLike<K, V> {
| ------- this trait cannot be made into an object...
LL | type VRefCont<'a>: RefCont<'a, V>;
| ^^^^^^^^ ...because it contains the generic associated type `VRefCont`
= help: consider moving `VRefCont` to another trait

error[E0038]: the trait `MapLike` cannot be made into an object
--> $DIR/issue-79422.rs:41:13
|
LL | let m = Box::new(std::collections::BTreeMap::<u8, u8>::new())
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `MapLike` cannot be made into an object
|
= help: consider moving `VRefCont` to another trait
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> $DIR/issue-79422.rs:20:10
|
LL | trait MapLike<K, V> {
| ------- this trait cannot be made into an object...
LL | type VRefCont<'a>: RefCont<'a, V>;
| ^^^^^^^^ ...because it contains the generic associated type `VRefCont`
= help: consider moving `VRefCont` to another trait
= note: required because of the requirements on the impl of `CoerceUnsized<Box<dyn MapLike<u8, u8, VRefCont = (dyn RefCont<'_, u8> + 'static)>>>` for `Box<BTreeMap<u8, u8>>`
= note: required by cast to type `Box<dyn MapLike<u8, u8, VRefCont = (dyn RefCont<'_, u8> + 'static)>>`

Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/generic-associated-types/trait-objects.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ error[E0038]: the trait `StreamingIterator` cannot be made into an object
LL | fn min_size(x: &mut dyn for<'a> StreamingIterator<Item<'a> = &'a i32>) -> usize {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `StreamingIterator` cannot be made into an object
|
= help: consider moving `Item` to another trait
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> $DIR/trait-objects.rs:4:10
|
LL | trait StreamingIterator {
| ----------------- this trait cannot be made into an object...
LL | type Item<'a> where Self: 'a;
| ^^^^ ...because it contains the generic associated type `Item`
= help: consider moving `Item` to another trait

error: aborting due to previous error

Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/issues/issue-18959.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ error[E0038]: the trait `Bar` cannot be made into an object
LL | fn foo(b: &dyn Bar) {
| ^^^^^^^ `Bar` cannot be made into an object
|
= help: consider moving `foo` to another trait
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> $DIR/issue-18959.rs:1:20
|
LL | pub trait Foo { fn foo<T>(&self, ext_thing: &T); }
| ^^^ ...because method `foo` has generic type parameters
LL | pub trait Bar: Foo { }
| --- this trait cannot be made into an object...
= help: consider moving `foo` to another trait

error: aborting due to previous error

Expand Down
4 changes: 2 additions & 2 deletions src/test/ui/issues/issue-19538.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ error[E0038]: the trait `Bar` cannot be made into an object
LL | let test: &mut dyn Bar = &mut thing;
| ^^^^^^^^^^^^ `Bar` cannot be made into an object
|
= help: consider moving `foo` to another trait
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> $DIR/issue-19538.rs:2:8
|
Expand All @@ -13,14 +12,14 @@ LL | fn foo<T>(&self, val: T);
...
LL | trait Bar: Foo { }
| --- this trait cannot be made into an object...
= help: consider moving `foo` to another trait

error[E0038]: the trait `Bar` cannot be made into an object
--> $DIR/issue-19538.rs:17:30
|
LL | let test: &mut dyn Bar = &mut thing;
| ^^^^^^^^^^ `Bar` cannot be made into an object
|
= help: consider moving `foo` to another trait
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> $DIR/issue-19538.rs:2:8
|
Expand All @@ -29,6 +28,7 @@ LL | fn foo<T>(&self, val: T);
...
LL | trait Bar: Foo { }
| --- this trait cannot be made into an object...
= help: consider moving `foo` to another trait
= note: required because of the requirements on the impl of `CoerceUnsized<&mut dyn Bar>` for `&mut Thing`
= note: required by cast to type `&mut dyn Bar`

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ error[E0038]: the trait `Bar` cannot be made into an object
LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
| ^^^^^^^^ `Bar` cannot be made into an object
|
= help: consider moving `X` to another trait
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> $DIR/object-safety-associated-consts.rs:9:11
|
LL | trait Bar {
| --- this trait cannot be made into an object...
LL | const X: usize;
| ^ ...because it contains this associated `const`
= help: consider moving `X` to another trait

error: aborting due to previous error

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ error[E0038]: the trait `Bar` cannot be made into an object
LL | t
| ^ `Bar` cannot be made into an object
|
= help: consider moving `X` to another trait
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> $DIR/object-safety-associated-consts.rs:9:11
|
LL | trait Bar {
| --- this trait cannot be made into an object...
LL | const X: usize;
| ^ ...because it contains this associated `const`
= help: consider moving `X` to another trait
= note: required because of the requirements on the impl of `CoerceUnsized<&dyn Bar>` for `&T`
= note: required by cast to type `&dyn Bar`

Expand Down
Loading

0 comments on commit 21f0b13

Please sign in to comment.