Skip to content

Commit 9762116

Browse files
committed
Move object safety suggestions to the end of the error
1 parent e846f9c commit 9762116

28 files changed

+50
-46
lines changed

compiler/rustc_infer/src/traits/error_reporting/mod.rs

+8-4
Original file line numberDiff line numberDiff line change
@@ -83,10 +83,6 @@ pub fn report_object_safety_error(
8383
messages.push(msg.clone());
8484
}
8585
}
86-
if trait_span.is_some() {
87-
// Only provide the help if its a local trait, otherwise it's not actionable.
88-
violation.solution(&mut err);
89-
}
9086
}
9187
}
9288
let has_multi_span = !multi_span.is_empty();
@@ -104,5 +100,13 @@ pub fn report_object_safety_error(
104100
to be resolvable dynamically; for more information visit \
105101
<https://doc.rust-lang.org/reference/items/traits.html#object-safety>",
106102
);
103+
if trait_span.is_some() {
104+
let mut reported_violations: Vec<_> = reported_violations.into_iter().collect();
105+
reported_violations.sort();
106+
for violation in reported_violations {
107+
// Only provide the help if its a local trait, otherwise it's not actionable.
108+
violation.solution(&mut err);
109+
}
110+
}
107111
err
108112
}

compiler/rustc_middle/src/traits/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -730,7 +730,7 @@ pub struct ImplSourceTraitAliasData<'tcx, N> {
730730
pub nested: Vec<N>,
731731
}
732732

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

881881
/// Reasons a method might not be object-safe.
882-
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable)]
882+
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable, PartialOrd, Ord)]
883883
pub enum MethodViolationCode {
884884
/// e.g., `fn foo()`
885885
StaticMethod(Option<(&'static str, Span)>, Span, bool /* has args */),

src/test/ui/associated-consts/associated-const-in-trait.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@ error[E0038]: the trait `Trait` cannot be made into an object
44
LL | impl dyn Trait {
55
| ^^^^^^^^^ `Trait` cannot be made into an object
66
|
7-
= help: consider moving `N` to another trait
87
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>
98
--> $DIR/associated-const-in-trait.rs:6:11
109
|
1110
LL | trait Trait {
1211
| ----- this trait cannot be made into an object...
1312
LL | const N: usize;
1413
| ^ ...because it contains this associated `const`
14+
= help: consider moving `N` to another trait
1515

1616
error: aborting due to previous error
1717

src/test/ui/associated-item/issue-48027.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,14 @@ error[E0038]: the trait `Bar` cannot be made into an object
2121
LL | impl dyn Bar {}
2222
| ^^^^^^^ `Bar` cannot be made into an object
2323
|
24-
= help: consider moving `X` to another trait
2524
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>
2625
--> $DIR/issue-48027.rs:2:11
2726
|
2827
LL | trait Bar {
2928
| --- this trait cannot be made into an object...
3029
LL | const X: usize;
3130
| ^ ...because it contains this associated `const`
31+
= help: consider moving `X` to another trait
3232

3333
error: aborting due to 2 previous errors
3434

src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@ error[E0038]: the trait `NotObjectSafe` cannot be made into an object
44
LL | impl NotObjectSafe for dyn NotObjectSafe { }
55
| ^^^^^^^^^^^^^^^^^ `NotObjectSafe` cannot be made into an object
66
|
7-
= help: consider moving `eq` to another trait
87
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>
98
--> $DIR/coherence-impl-trait-for-trait-object-safe.rs:6:43
109
|
1110
LL | trait NotObjectSafe { fn eq(&self, other: Self); }
1211
| ------------- ^^^^ ...because method `eq` references the `Self` type in this parameter
1312
| |
1413
| this trait cannot be made into an object...
14+
= help: consider moving `eq` to another trait
1515

1616
error: aborting due to previous error
1717

src/test/ui/const-generics/generic_const_exprs/object-safety-err-ret.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@ error[E0038]: the trait `Foo` cannot be made into an object
44
LL | fn use_dyn(v: &dyn Foo) {
55
| ^^^^^^^ `Foo` cannot be made into an object
66
|
7-
= help: consider moving `test` to another trait
87
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>
98
--> $DIR/object-safety-err-ret.rs:8:23
109
|
1110
LL | trait Foo {
1211
| --- this trait cannot be made into an object...
1312
LL | fn test(&self) -> [u8; bar::<Self>()];
1413
| ^^^^^^^^^^^^^^^^^^^ ...because method `test` references the `Self` type in its return type
14+
= help: consider moving `test` to another trait
1515

1616
error: aborting due to previous error
1717

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@ error[E0038]: the trait `Trait` cannot be made into an object
44
LL | fn call_foo(x: Box<dyn Trait>) {
55
| ^^^^^^^^^ `Trait` cannot be made into an object
66
|
7-
= help: consider moving `foo` to another trait
87
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>
98
--> $DIR/E0038.rs:2:22
109
|
1110
LL | trait Trait {
1211
| ----- this trait cannot be made into an object...
1312
LL | fn foo(&self) -> Self;
1413
| ^^^^ ...because method `foo` references the `Self` type in its return type
14+
= help: consider moving `foo` to another trait
1515

1616
error: aborting due to previous error
1717

src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -40,29 +40,29 @@ error[E0038]: the trait `NonObjectSafe3` cannot be made into an object
4040
LL | fn takes_non_object_safe_box(obj: Box<dyn NonObjectSafe3>) {
4141
| ^^^^^^^^^^^^^^^^^^ `NonObjectSafe3` cannot be made into an object
4242
|
43-
= help: consider moving `foo` to another trait
4443
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>
4544
--> $DIR/feature-gate-object_safe_for_dispatch.rs:11:8
4645
|
4746
LL | trait NonObjectSafe3 {
4847
| -------------- this trait cannot be made into an object...
4948
LL | fn foo<T>(&self);
5049
| ^^^ ...because method `foo` has generic type parameters
50+
= help: consider moving `foo` to another trait
5151

5252
error[E0038]: the trait `NonObjectSafe4` cannot be made into an object
5353
--> $DIR/feature-gate-object_safe_for_dispatch.rs:31:35
5454
|
5555
LL | fn return_non_object_safe_rc() -> std::rc::Rc<dyn NonObjectSafe4> {
5656
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `NonObjectSafe4` cannot be made into an object
5757
|
58-
= help: consider moving `foo` to another trait
5958
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>
6059
--> $DIR/feature-gate-object_safe_for_dispatch.rs:15:22
6160
|
6261
LL | trait NonObjectSafe4 {
6362
| -------------- this trait cannot be made into an object...
6463
LL | fn foo(&self, s: &Self);
6564
| ^^^^^ ...because method `foo` references the `Self` type in this parameter
65+
= help: consider moving `foo` to another trait
6666

6767
error[E0038]: the trait `NonObjectSafe1` cannot be made into an object
6868
--> $DIR/feature-gate-object_safe_for_dispatch.rs:38:16

src/test/ui/generic-associated-types/gat-in-trait-path.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@ error[E0038]: the trait `Foo` cannot be made into an object
44
LL | fn f(_arg : Box<dyn for<'a> Foo<A<'a> = &'a ()>>) {}
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Foo` cannot be made into an object
66
|
7-
= help: consider moving `A` to another trait
87
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>
98
--> $DIR/gat-in-trait-path.rs:5:10
109
|
1110
LL | trait Foo {
1211
| --- this trait cannot be made into an object...
1312
LL | type A<'a> where Self: 'a;
1413
| ^ ...because it contains the generic associated type `A`
14+
= help: consider moving `A` to another trait
1515

1616
error: aborting due to previous error
1717

src/test/ui/generic-associated-types/issue-67510-pass.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@ error[E0038]: the trait `X` cannot be made into an object
44
LL | fn _func1<'a>(_x: Box<dyn X<Y<'a>=&'a ()>>) {}
55
| ^^^^^^^^^^^^^^^^^^^ `X` cannot be made into an object
66
|
7-
= help: consider moving `Y` to another trait
87
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>
98
--> $DIR/issue-67510-pass.rs:4:10
109
|
1110
LL | trait X {
1211
| - this trait cannot be made into an object...
1312
LL | type Y<'a>;
1413
| ^ ...because it contains the generic associated type `Y`
14+
= help: consider moving `Y` to another trait
1515

1616
error: aborting due to previous error
1717

src/test/ui/generic-associated-types/issue-76535.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,29 +20,29 @@ error[E0038]: the trait `SuperTrait` cannot be made into an object
2020
LL | let sub: Box<dyn SuperTrait<SubType = SubStruct>> = Box::new(SuperStruct::new(0));
2121
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `SuperTrait` cannot be made into an object
2222
|
23-
= help: consider moving `SubType` to another trait
2423
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>
2524
--> $DIR/issue-76535.rs:6:10
2625
|
2726
LL | pub trait SuperTrait {
2827
| ---------- this trait cannot be made into an object...
2928
LL | type SubType<'a>: SubTrait;
3029
| ^^^^^^^ ...because it contains the generic associated type `SubType`
30+
= help: consider moving `SubType` to another trait
3131

3232
error[E0038]: the trait `SuperTrait` cannot be made into an object
3333
--> $DIR/issue-76535.rs:36:57
3434
|
3535
LL | let sub: Box<dyn SuperTrait<SubType = SubStruct>> = Box::new(SuperStruct::new(0));
3636
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `SuperTrait` cannot be made into an object
3737
|
38-
= help: consider moving `SubType` to another trait
3938
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>
4039
--> $DIR/issue-76535.rs:6:10
4140
|
4241
LL | pub trait SuperTrait {
4342
| ---------- this trait cannot be made into an object...
4443
LL | type SubType<'a>: SubTrait;
4544
| ^^^^^^^ ...because it contains the generic associated type `SubType`
45+
= help: consider moving `SubType` to another trait
4646
= note: required because of the requirements on the impl of `CoerceUnsized<Box<dyn SuperTrait<SubType = SubStruct<'_>>>>` for `Box<SuperStruct>`
4747
= note: required by cast to type `Box<dyn SuperTrait<SubType = SubStruct<'_>>>`
4848

src/test/ui/generic-associated-types/issue-78671.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,14 @@ error[E0038]: the trait `CollectionFamily` cannot be made into an object
2020
LL | Box::new(Family) as &dyn CollectionFamily<Member=usize>
2121
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `CollectionFamily` cannot be made into an object
2222
|
23-
= help: consider moving `Member` to another trait
2423
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>
2524
--> $DIR/issue-78671.rs:4:10
2625
|
2726
LL | trait CollectionFamily {
2827
| ---------------- this trait cannot be made into an object...
2928
LL | type Member<T>;
3029
| ^^^^^^ ...because it contains the generic associated type `Member`
30+
= help: consider moving `Member` to another trait
3131

3232
error: aborting due to 2 previous errors
3333

src/test/ui/generic-associated-types/issue-79422.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,29 +20,29 @@ error[E0038]: the trait `MapLike` cannot be made into an object
2020
LL | as Box<dyn MapLike<u8, u8, VRefCont = dyn RefCont<'_, u8>>>;
2121
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `MapLike` cannot be made into an object
2222
|
23-
= help: consider moving `VRefCont` to another trait
2423
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>
2524
--> $DIR/issue-79422.rs:20:10
2625
|
2726
LL | trait MapLike<K, V> {
2827
| ------- this trait cannot be made into an object...
2928
LL | type VRefCont<'a>: RefCont<'a, V>;
3029
| ^^^^^^^^ ...because it contains the generic associated type `VRefCont`
30+
= help: consider moving `VRefCont` to another trait
3131

3232
error[E0038]: the trait `MapLike` cannot be made into an object
3333
--> $DIR/issue-79422.rs:41:13
3434
|
3535
LL | let m = Box::new(std::collections::BTreeMap::<u8, u8>::new())
3636
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `MapLike` cannot be made into an object
3737
|
38-
= help: consider moving `VRefCont` to another trait
3938
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>
4039
--> $DIR/issue-79422.rs:20:10
4140
|
4241
LL | trait MapLike<K, V> {
4342
| ------- this trait cannot be made into an object...
4443
LL | type VRefCont<'a>: RefCont<'a, V>;
4544
| ^^^^^^^^ ...because it contains the generic associated type `VRefCont`
45+
= help: consider moving `VRefCont` to another trait
4646
= 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>>`
4747
= note: required by cast to type `Box<dyn MapLike<u8, u8, VRefCont = (dyn RefCont<'_, u8> + 'static)>>`
4848

src/test/ui/generic-associated-types/trait-objects.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@ error[E0038]: the trait `StreamingIterator` cannot be made into an object
44
LL | fn min_size(x: &mut dyn for<'a> StreamingIterator<Item<'a> = &'a i32>) -> usize {
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `StreamingIterator` cannot be made into an object
66
|
7-
= help: consider moving `Item` to another trait
87
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>
98
--> $DIR/trait-objects.rs:4:10
109
|
1110
LL | trait StreamingIterator {
1211
| ----------------- this trait cannot be made into an object...
1312
LL | type Item<'a> where Self: 'a;
1413
| ^^^^ ...because it contains the generic associated type `Item`
14+
= help: consider moving `Item` to another trait
1515

1616
error: aborting due to previous error
1717

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@ error[E0038]: the trait `Bar` cannot be made into an object
44
LL | fn foo(b: &dyn Bar) {
55
| ^^^^^^^ `Bar` cannot be made into an object
66
|
7-
= help: consider moving `foo` to another trait
87
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>
98
--> $DIR/issue-18959.rs:1:20
109
|
1110
LL | pub trait Foo { fn foo<T>(&self, ext_thing: &T); }
1211
| ^^^ ...because method `foo` has generic type parameters
1312
LL | pub trait Bar: Foo { }
1413
| --- this trait cannot be made into an object...
14+
= help: consider moving `foo` to another trait
1515

1616
error: aborting due to previous error
1717

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ error[E0038]: the trait `Bar` cannot be made into an object
44
LL | let test: &mut dyn Bar = &mut thing;
55
| ^^^^^^^^^^^^ `Bar` cannot be made into an object
66
|
7-
= help: consider moving `foo` to another trait
87
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>
98
--> $DIR/issue-19538.rs:2:8
109
|
@@ -13,14 +12,14 @@ LL | fn foo<T>(&self, val: T);
1312
...
1413
LL | trait Bar: Foo { }
1514
| --- this trait cannot be made into an object...
15+
= help: consider moving `foo` to another trait
1616

1717
error[E0038]: the trait `Bar` cannot be made into an object
1818
--> $DIR/issue-19538.rs:17:30
1919
|
2020
LL | let test: &mut dyn Bar = &mut thing;
2121
| ^^^^^^^^^^ `Bar` cannot be made into an object
2222
|
23-
= help: consider moving `foo` to another trait
2423
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>
2524
--> $DIR/issue-19538.rs:2:8
2625
|
@@ -29,6 +28,7 @@ LL | fn foo<T>(&self, val: T);
2928
...
3029
LL | trait Bar: Foo { }
3130
| --- this trait cannot be made into an object...
31+
= help: consider moving `foo` to another trait
3232
= note: required because of the requirements on the impl of `CoerceUnsized<&mut dyn Bar>` for `&mut Thing`
3333
= note: required by cast to type `&mut dyn Bar`
3434

src/test/ui/object-safety/object-safety-associated-consts.curr.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@ error[E0038]: the trait `Bar` cannot be made into an object
44
LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
55
| ^^^^^^^^ `Bar` cannot be made into an object
66
|
7-
= help: consider moving `X` to another trait
87
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>
98
--> $DIR/object-safety-associated-consts.rs:9:11
109
|
1110
LL | trait Bar {
1211
| --- this trait cannot be made into an object...
1312
LL | const X: usize;
1413
| ^ ...because it contains this associated `const`
14+
= help: consider moving `X` to another trait
1515

1616
error: aborting due to previous error
1717

src/test/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@ error[E0038]: the trait `Bar` cannot be made into an object
44
LL | t
55
| ^ `Bar` cannot be made into an object
66
|
7-
= help: consider moving `X` to another trait
87
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>
98
--> $DIR/object-safety-associated-consts.rs:9:11
109
|
1110
LL | trait Bar {
1211
| --- this trait cannot be made into an object...
1312
LL | const X: usize;
1413
| ^ ...because it contains this associated `const`
14+
= help: consider moving `X` to another trait
1515
= note: required because of the requirements on the impl of `CoerceUnsized<&dyn Bar>` for `&T`
1616
= note: required by cast to type `&dyn Bar`
1717

0 commit comments

Comments
 (0)