Skip to content

Commit 1c9242f

Browse files
committed
Point at Sized bound
1 parent fca5c64 commit 1c9242f

9 files changed

+76
-9
lines changed

src/librustc/traits/object_safety.rs

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use std::iter::{self};
2626
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
2727
pub enum ObjectSafetyViolation {
2828
/// `Self: Sized` declared on the trait.
29-
SizedSelf,
29+
SizedSelf(Span),
3030

3131
/// Supertrait reference references `Self` an in illegal location
3232
/// (e.g., `trait Foo : Bar<Self>`).
@@ -42,7 +42,7 @@ pub enum ObjectSafetyViolation {
4242
impl ObjectSafetyViolation {
4343
pub fn error_msg(&self) -> Cow<'static, str> {
4444
match *self {
45-
ObjectSafetyViolation::SizedSelf => {
45+
ObjectSafetyViolation::SizedSelf(_) => {
4646
"the trait cannot require that `Self : Sized`".into()
4747
}
4848
ObjectSafetyViolation::SupertraitSelf => {
@@ -80,6 +80,7 @@ impl ObjectSafetyViolation {
8080
// diagnostics use a `note` instead of a `span_label`.
8181
match *self {
8282
ObjectSafetyViolation::AssocConst(_, span)
83+
| ObjectSafetyViolation::SizedSelf(span)
8384
| ObjectSafetyViolation::Method(_, _, span)
8485
if span != DUMMY_SP =>
8586
{
@@ -179,17 +180,20 @@ fn object_safety_violations_for_trait(
179180
{
180181
// Using `CRATE_NODE_ID` is wrong, but it's hard to get a more precise id.
181182
// It's also hard to get a use site span, so we use the method definition span.
182-
tcx.struct_span_lint_hir(
183+
let mut err = tcx.struct_span_lint_hir(
183184
WHERE_CLAUSES_OBJECT_SAFETY,
184185
hir::CRATE_HIR_ID,
185186
*span,
186187
&format!(
187188
"the trait `{}` cannot be made into an object",
188189
tcx.def_path_str(trait_def_id)
189190
),
190-
)
191-
.note(&violation.error_msg())
192-
.emit();
191+
);
192+
match violation.span() {
193+
Some(span) => err.span_label(span, violation.error_msg()),
194+
None => err.note(&violation.error_msg()),
195+
};
196+
err.emit();
193197
false
194198
} else {
195199
true
@@ -199,7 +203,8 @@ fn object_safety_violations_for_trait(
199203

200204
// Check the trait itself.
201205
if trait_has_sized_self(tcx, trait_def_id) {
202-
violations.push(ObjectSafetyViolation::SizedSelf);
206+
let span = get_sized_bound(tcx, trait_def_id);
207+
violations.push(ObjectSafetyViolation::SizedSelf(span));
203208
}
204209
if predicates_reference_self(tcx, trait_def_id, false) {
205210
violations.push(ObjectSafetyViolation::SupertraitSelf);
@@ -219,6 +224,27 @@ fn object_safety_violations_for_trait(
219224
violations
220225
}
221226

227+
fn get_sized_bound(tcx: TyCtxt<'_>, trait_def_id: DefId) -> Span {
228+
tcx.hir()
229+
.get_if_local(trait_def_id)
230+
.and_then(|node| match node {
231+
hir::Node::Item(hir::Item { kind: hir::ItemKind::Trait(.., bounds, _), .. }) => bounds
232+
.iter()
233+
.filter_map(|b| match b {
234+
hir::GenericBound::Trait(trait_ref, hir::TraitBoundModifier::None)
235+
if Some(trait_ref.trait_ref.trait_def_id())
236+
== tcx.lang_items().sized_trait() =>
237+
{
238+
Some(trait_ref.span)
239+
}
240+
_ => None,
241+
})
242+
.next(),
243+
_ => None,
244+
})
245+
.unwrap_or(DUMMY_SP)
246+
}
247+
222248
fn predicates_reference_self(tcx: TyCtxt<'_>, trait_def_id: DefId, supertraits_only: bool) -> bool {
223249
let trait_ref = ty::Binder::dummy(ty::TraitRef::identity(tcx, trait_def_id));
224250
let predicates = if supertraits_only {

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
error[E0038]: the trait `NonObjectSafe1` cannot be made into an object
22
--> $DIR/feature-gate-object_safe_for_dispatch.rs:18:38
33
|
4+
LL | trait NonObjectSafe1: Sized {}
5+
| ----- the trait cannot require that `Self : Sized`
6+
...
47
LL | fn takes_non_object_safe_ref<T>(obj: &dyn NonObjectSafe1) {
58
| ^^^^^^^^^^^^^^^^^^^ the trait `NonObjectSafe1` cannot be made into an object
69
|
@@ -36,6 +39,9 @@ LL | fn return_non_object_safe_rc() -> std::rc::Rc<dyn NonObjectSafe4> {
3639
error[E0038]: the trait `NonObjectSafe1` cannot be made into an object
3740
--> $DIR/feature-gate-object_safe_for_dispatch.rs:38:6
3841
|
42+
LL | trait NonObjectSafe1: Sized {}
43+
| ----- the trait cannot require that `Self : Sized`
44+
...
3945
LL | impl Trait for dyn NonObjectSafe1 {}
4046
| ^^^^^ the trait `NonObjectSafe1` cannot be made into an object
4147
|

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
error[E0038]: the trait `Array` cannot be made into an object
22
--> $DIR/issue-20692.rs:7:5
33
|
4+
LL | trait Array: Sized {}
5+
| ----- the trait cannot require that `Self : Sized`
6+
...
47
LL | &dyn Array;
58
| ^^^^^^^^^^ the trait `Array` cannot be made into an object
69
|
@@ -9,6 +12,9 @@ LL | &dyn Array;
912
error[E0038]: the trait `Array` cannot be made into an object
1013
--> $DIR/issue-20692.rs:4:13
1114
|
15+
LL | trait Array: Sized {}
16+
| ----- the trait cannot require that `Self : Sized`
17+
...
1218
LL | let _ = x
1319
| ^ the trait `Array` cannot be made into an object
1420
|

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error: the trait `X` cannot be made into an object
22
--> $DIR/issue-50781.rs:6:8
33
|
44
LL | fn foo(&self) where Self: Trait;
5-
| ^^^
5+
| ^^^ method `foo` references the `Self` type in where clauses
66
|
77
note: the lint level is defined here
88
--> $DIR/issue-50781.rs:1:9
@@ -11,7 +11,6 @@ LL | #![deny(where_clauses_object_safety)]
1111
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
1212
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
1313
= note: for more information, see issue #51443 <https://github.com/rust-lang/rust/issues/51443>
14-
= note: method `foo` references the `Self` type in where clauses
1514

1615
error: aborting due to previous error
1716

src/test/ui/object-safety/object-safety-sized.curr.stderr

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
error[E0038]: the trait `Bar` cannot be made into an object
22
--> $DIR/object-safety-sized.rs:12:30
33
|
4+
LL | trait Bar : Sized {
5+
| ----- the trait cannot require that `Self : Sized`
6+
...
47
LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
58
| ^^^^^^^^ the trait `Bar` cannot be made into an object
69
|

src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
error[E0038]: the trait `Bar` cannot be made into an object
22
--> $DIR/object-safety-sized.rs:14:5
33
|
4+
LL | trait Bar : Sized {
5+
| ----- the trait cannot require that `Self : Sized`
6+
...
47
LL | t
58
| ^ the trait `Bar` cannot be made into an object
69
|

src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
error[E0038]: the trait `Trait` cannot be made into an object
22
--> $DIR/wf-convert-unsafe-trait-obj-box.rs:16:33
33
|
4+
LL | trait Trait: Sized {}
5+
| ----- the trait cannot require that `Self : Sized`
6+
...
47
LL | let t_box: Box<dyn Trait> = Box::new(S);
58
| ^^^^^^^^^^^ the trait `Trait` cannot be made into an object
69
|
@@ -11,6 +14,9 @@ LL | let t_box: Box<dyn Trait> = Box::new(S);
1114
error[E0038]: the trait `Trait` cannot be made into an object
1215
--> $DIR/wf-convert-unsafe-trait-obj-box.rs:17:15
1316
|
17+
LL | trait Trait: Sized {}
18+
| ----- the trait cannot require that `Self : Sized`
19+
...
1420
LL | takes_box(Box::new(S));
1521
| ^^^^^^^^^^^ the trait `Trait` cannot be made into an object
1622
|
@@ -21,6 +27,9 @@ LL | takes_box(Box::new(S));
2127
error[E0038]: the trait `Trait` cannot be made into an object
2228
--> $DIR/wf-convert-unsafe-trait-obj-box.rs:15:5
2329
|
30+
LL | trait Trait: Sized {}
31+
| ----- the trait cannot require that `Self : Sized`
32+
...
2433
LL | Box::new(S) as Box<dyn Trait>;
2534
| ^^^^^^^^^^^ the trait `Trait` cannot be made into an object
2635
|

src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
error[E0038]: the trait `Trait` cannot be made into an object
22
--> $DIR/wf-convert-unsafe-trait-obj.rs:16:25
33
|
4+
LL | trait Trait: Sized {}
5+
| ----- the trait cannot require that `Self : Sized`
6+
...
47
LL | let t: &dyn Trait = &S;
58
| ^^ the trait `Trait` cannot be made into an object
69
|
@@ -11,6 +14,9 @@ LL | let t: &dyn Trait = &S;
1114
error[E0038]: the trait `Trait` cannot be made into an object
1215
--> $DIR/wf-convert-unsafe-trait-obj.rs:17:17
1316
|
17+
LL | trait Trait: Sized {}
18+
| ----- the trait cannot require that `Self : Sized`
19+
...
1420
LL | takes_trait(&S);
1521
| ^^ the trait `Trait` cannot be made into an object
1622
|
@@ -21,6 +27,9 @@ LL | takes_trait(&S);
2127
error[E0038]: the trait `Trait` cannot be made into an object
2228
--> $DIR/wf-convert-unsafe-trait-obj.rs:15:5
2329
|
30+
LL | trait Trait: Sized {}
31+
| ----- the trait cannot require that `Self : Sized`
32+
...
2433
LL | &S as &dyn Trait;
2534
| ^^ the trait `Trait` cannot be made into an object
2635
|

src/test/ui/wf/wf-unsafe-trait-obj-match.stderr

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ LL | | }
1515
error[E0038]: the trait `Trait` cannot be made into an object
1616
--> $DIR/wf-unsafe-trait-obj-match.rs:26:21
1717
|
18+
LL | trait Trait: Sized {}
19+
| ----- the trait cannot require that `Self : Sized`
20+
...
1821
LL | Some(()) => &S,
1922
| ^^ the trait `Trait` cannot be made into an object
2023
|
@@ -25,6 +28,9 @@ LL | Some(()) => &S,
2528
error[E0038]: the trait `Trait` cannot be made into an object
2629
--> $DIR/wf-unsafe-trait-obj-match.rs:25:25
2730
|
31+
LL | trait Trait: Sized {}
32+
| ----- the trait cannot require that `Self : Sized`
33+
...
2834
LL | let t: &dyn Trait = match opt() {
2935
| ^^^^^^^^^^^ the trait `Trait` cannot be made into an object
3036
|

0 commit comments

Comments
 (0)