Point at Sized
bound
This commit is contained in:
parent
fca5c64abd
commit
1c9242f83f
@ -26,7 +26,7 @@ use std::iter::{self};
|
|||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||||
pub enum ObjectSafetyViolation {
|
pub enum ObjectSafetyViolation {
|
||||||
/// `Self: Sized` declared on the trait.
|
/// `Self: Sized` declared on the trait.
|
||||||
SizedSelf,
|
SizedSelf(Span),
|
||||||
|
|
||||||
/// Supertrait reference references `Self` an in illegal location
|
/// Supertrait reference references `Self` an in illegal location
|
||||||
/// (e.g., `trait Foo : Bar<Self>`).
|
/// (e.g., `trait Foo : Bar<Self>`).
|
||||||
@ -42,7 +42,7 @@ pub enum ObjectSafetyViolation {
|
|||||||
impl ObjectSafetyViolation {
|
impl ObjectSafetyViolation {
|
||||||
pub fn error_msg(&self) -> Cow<'static, str> {
|
pub fn error_msg(&self) -> Cow<'static, str> {
|
||||||
match *self {
|
match *self {
|
||||||
ObjectSafetyViolation::SizedSelf => {
|
ObjectSafetyViolation::SizedSelf(_) => {
|
||||||
"the trait cannot require that `Self : Sized`".into()
|
"the trait cannot require that `Self : Sized`".into()
|
||||||
}
|
}
|
||||||
ObjectSafetyViolation::SupertraitSelf => {
|
ObjectSafetyViolation::SupertraitSelf => {
|
||||||
@ -80,6 +80,7 @@ impl ObjectSafetyViolation {
|
|||||||
// diagnostics use a `note` instead of a `span_label`.
|
// diagnostics use a `note` instead of a `span_label`.
|
||||||
match *self {
|
match *self {
|
||||||
ObjectSafetyViolation::AssocConst(_, span)
|
ObjectSafetyViolation::AssocConst(_, span)
|
||||||
|
| ObjectSafetyViolation::SizedSelf(span)
|
||||||
| ObjectSafetyViolation::Method(_, _, span)
|
| ObjectSafetyViolation::Method(_, _, span)
|
||||||
if span != DUMMY_SP =>
|
if span != DUMMY_SP =>
|
||||||
{
|
{
|
||||||
@ -179,7 +180,7 @@ fn object_safety_violations_for_trait(
|
|||||||
{
|
{
|
||||||
// Using `CRATE_NODE_ID` is wrong, but it's hard to get a more precise id.
|
// Using `CRATE_NODE_ID` is wrong, but it's hard to get a more precise id.
|
||||||
// It's also hard to get a use site span, so we use the method definition span.
|
// It's also hard to get a use site span, so we use the method definition span.
|
||||||
tcx.struct_span_lint_hir(
|
let mut err = tcx.struct_span_lint_hir(
|
||||||
WHERE_CLAUSES_OBJECT_SAFETY,
|
WHERE_CLAUSES_OBJECT_SAFETY,
|
||||||
hir::CRATE_HIR_ID,
|
hir::CRATE_HIR_ID,
|
||||||
*span,
|
*span,
|
||||||
@ -187,9 +188,12 @@ fn object_safety_violations_for_trait(
|
|||||||
"the trait `{}` cannot be made into an object",
|
"the trait `{}` cannot be made into an object",
|
||||||
tcx.def_path_str(trait_def_id)
|
tcx.def_path_str(trait_def_id)
|
||||||
),
|
),
|
||||||
)
|
);
|
||||||
.note(&violation.error_msg())
|
match violation.span() {
|
||||||
.emit();
|
Some(span) => err.span_label(span, violation.error_msg()),
|
||||||
|
None => err.note(&violation.error_msg()),
|
||||||
|
};
|
||||||
|
err.emit();
|
||||||
false
|
false
|
||||||
} else {
|
} else {
|
||||||
true
|
true
|
||||||
@ -199,7 +203,8 @@ fn object_safety_violations_for_trait(
|
|||||||
|
|
||||||
// Check the trait itself.
|
// Check the trait itself.
|
||||||
if trait_has_sized_self(tcx, trait_def_id) {
|
if trait_has_sized_self(tcx, trait_def_id) {
|
||||||
violations.push(ObjectSafetyViolation::SizedSelf);
|
let span = get_sized_bound(tcx, trait_def_id);
|
||||||
|
violations.push(ObjectSafetyViolation::SizedSelf(span));
|
||||||
}
|
}
|
||||||
if predicates_reference_self(tcx, trait_def_id, false) {
|
if predicates_reference_self(tcx, trait_def_id, false) {
|
||||||
violations.push(ObjectSafetyViolation::SupertraitSelf);
|
violations.push(ObjectSafetyViolation::SupertraitSelf);
|
||||||
@ -219,6 +224,27 @@ fn object_safety_violations_for_trait(
|
|||||||
violations
|
violations
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_sized_bound(tcx: TyCtxt<'_>, trait_def_id: DefId) -> Span {
|
||||||
|
tcx.hir()
|
||||||
|
.get_if_local(trait_def_id)
|
||||||
|
.and_then(|node| match node {
|
||||||
|
hir::Node::Item(hir::Item { kind: hir::ItemKind::Trait(.., bounds, _), .. }) => bounds
|
||||||
|
.iter()
|
||||||
|
.filter_map(|b| match b {
|
||||||
|
hir::GenericBound::Trait(trait_ref, hir::TraitBoundModifier::None)
|
||||||
|
if Some(trait_ref.trait_ref.trait_def_id())
|
||||||
|
== tcx.lang_items().sized_trait() =>
|
||||||
|
{
|
||||||
|
Some(trait_ref.span)
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
|
.next(),
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
|
.unwrap_or(DUMMY_SP)
|
||||||
|
}
|
||||||
|
|
||||||
fn predicates_reference_self(tcx: TyCtxt<'_>, trait_def_id: DefId, supertraits_only: bool) -> bool {
|
fn predicates_reference_self(tcx: TyCtxt<'_>, trait_def_id: DefId, supertraits_only: bool) -> bool {
|
||||||
let trait_ref = ty::Binder::dummy(ty::TraitRef::identity(tcx, trait_def_id));
|
let trait_ref = ty::Binder::dummy(ty::TraitRef::identity(tcx, trait_def_id));
|
||||||
let predicates = if supertraits_only {
|
let predicates = if supertraits_only {
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
error[E0038]: the trait `NonObjectSafe1` cannot be made into an object
|
error[E0038]: the trait `NonObjectSafe1` cannot be made into an object
|
||||||
--> $DIR/feature-gate-object_safe_for_dispatch.rs:18:38
|
--> $DIR/feature-gate-object_safe_for_dispatch.rs:18:38
|
||||||
|
|
|
|
||||||
|
LL | trait NonObjectSafe1: Sized {}
|
||||||
|
| ----- the trait cannot require that `Self : Sized`
|
||||||
|
...
|
||||||
LL | fn takes_non_object_safe_ref<T>(obj: &dyn NonObjectSafe1) {
|
LL | fn takes_non_object_safe_ref<T>(obj: &dyn NonObjectSafe1) {
|
||||||
| ^^^^^^^^^^^^^^^^^^^ the trait `NonObjectSafe1` cannot be made into an object
|
| ^^^^^^^^^^^^^^^^^^^ the trait `NonObjectSafe1` cannot be made into an object
|
||||||
|
|
|
|
||||||
@ -36,6 +39,9 @@ LL | fn return_non_object_safe_rc() -> std::rc::Rc<dyn NonObjectSafe4> {
|
|||||||
error[E0038]: the trait `NonObjectSafe1` cannot be made into an object
|
error[E0038]: the trait `NonObjectSafe1` cannot be made into an object
|
||||||
--> $DIR/feature-gate-object_safe_for_dispatch.rs:38:6
|
--> $DIR/feature-gate-object_safe_for_dispatch.rs:38:6
|
||||||
|
|
|
|
||||||
|
LL | trait NonObjectSafe1: Sized {}
|
||||||
|
| ----- the trait cannot require that `Self : Sized`
|
||||||
|
...
|
||||||
LL | impl Trait for dyn NonObjectSafe1 {}
|
LL | impl Trait for dyn NonObjectSafe1 {}
|
||||||
| ^^^^^ the trait `NonObjectSafe1` cannot be made into an object
|
| ^^^^^ the trait `NonObjectSafe1` cannot be made into an object
|
||||||
|
|
|
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
error[E0038]: the trait `Array` cannot be made into an object
|
error[E0038]: the trait `Array` cannot be made into an object
|
||||||
--> $DIR/issue-20692.rs:7:5
|
--> $DIR/issue-20692.rs:7:5
|
||||||
|
|
|
|
||||||
|
LL | trait Array: Sized {}
|
||||||
|
| ----- the trait cannot require that `Self : Sized`
|
||||||
|
...
|
||||||
LL | &dyn Array;
|
LL | &dyn Array;
|
||||||
| ^^^^^^^^^^ the trait `Array` cannot be made into an object
|
| ^^^^^^^^^^ the trait `Array` cannot be made into an object
|
||||||
|
|
|
|
||||||
@ -9,6 +12,9 @@ LL | &dyn Array;
|
|||||||
error[E0038]: the trait `Array` cannot be made into an object
|
error[E0038]: the trait `Array` cannot be made into an object
|
||||||
--> $DIR/issue-20692.rs:4:13
|
--> $DIR/issue-20692.rs:4:13
|
||||||
|
|
|
|
||||||
|
LL | trait Array: Sized {}
|
||||||
|
| ----- the trait cannot require that `Self : Sized`
|
||||||
|
...
|
||||||
LL | let _ = x
|
LL | let _ = x
|
||||||
| ^ the trait `Array` cannot be made into an object
|
| ^ the trait `Array` cannot be made into an object
|
||||||
|
|
|
|
||||||
|
@ -2,7 +2,7 @@ error: the trait `X` cannot be made into an object
|
|||||||
--> $DIR/issue-50781.rs:6:8
|
--> $DIR/issue-50781.rs:6:8
|
||||||
|
|
|
|
||||||
LL | fn foo(&self) where Self: Trait;
|
LL | fn foo(&self) where Self: Trait;
|
||||||
| ^^^
|
| ^^^ method `foo` references the `Self` type in where clauses
|
||||||
|
|
|
|
||||||
note: the lint level is defined here
|
note: the lint level is defined here
|
||||||
--> $DIR/issue-50781.rs:1:9
|
--> $DIR/issue-50781.rs:1:9
|
||||||
@ -11,7 +11,6 @@ LL | #![deny(where_clauses_object_safety)]
|
|||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
= note: for more information, see issue #51443 <https://github.com/rust-lang/rust/issues/51443>
|
= note: for more information, see issue #51443 <https://github.com/rust-lang/rust/issues/51443>
|
||||||
= note: method `foo` references the `Self` type in where clauses
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
error[E0038]: the trait `Bar` cannot be made into an object
|
error[E0038]: the trait `Bar` cannot be made into an object
|
||||||
--> $DIR/object-safety-sized.rs:12:30
|
--> $DIR/object-safety-sized.rs:12:30
|
||||||
|
|
|
|
||||||
|
LL | trait Bar : Sized {
|
||||||
|
| ----- the trait cannot require that `Self : Sized`
|
||||||
|
...
|
||||||
LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
|
LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
|
||||||
| ^^^^^^^^ the trait `Bar` cannot be made into an object
|
| ^^^^^^^^ the trait `Bar` cannot be made into an object
|
||||||
|
|
|
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
error[E0038]: the trait `Bar` cannot be made into an object
|
error[E0038]: the trait `Bar` cannot be made into an object
|
||||||
--> $DIR/object-safety-sized.rs:14:5
|
--> $DIR/object-safety-sized.rs:14:5
|
||||||
|
|
|
|
||||||
|
LL | trait Bar : Sized {
|
||||||
|
| ----- the trait cannot require that `Self : Sized`
|
||||||
|
...
|
||||||
LL | t
|
LL | t
|
||||||
| ^ the trait `Bar` cannot be made into an object
|
| ^ the trait `Bar` cannot be made into an object
|
||||||
|
|
|
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
error[E0038]: the trait `Trait` cannot be made into an object
|
error[E0038]: the trait `Trait` cannot be made into an object
|
||||||
--> $DIR/wf-convert-unsafe-trait-obj-box.rs:16:33
|
--> $DIR/wf-convert-unsafe-trait-obj-box.rs:16:33
|
||||||
|
|
|
|
||||||
|
LL | trait Trait: Sized {}
|
||||||
|
| ----- the trait cannot require that `Self : Sized`
|
||||||
|
...
|
||||||
LL | let t_box: Box<dyn Trait> = Box::new(S);
|
LL | let t_box: Box<dyn Trait> = Box::new(S);
|
||||||
| ^^^^^^^^^^^ the trait `Trait` cannot be made into an object
|
| ^^^^^^^^^^^ the trait `Trait` cannot be made into an object
|
||||||
|
|
|
|
||||||
@ -11,6 +14,9 @@ LL | let t_box: Box<dyn Trait> = Box::new(S);
|
|||||||
error[E0038]: the trait `Trait` cannot be made into an object
|
error[E0038]: the trait `Trait` cannot be made into an object
|
||||||
--> $DIR/wf-convert-unsafe-trait-obj-box.rs:17:15
|
--> $DIR/wf-convert-unsafe-trait-obj-box.rs:17:15
|
||||||
|
|
|
|
||||||
|
LL | trait Trait: Sized {}
|
||||||
|
| ----- the trait cannot require that `Self : Sized`
|
||||||
|
...
|
||||||
LL | takes_box(Box::new(S));
|
LL | takes_box(Box::new(S));
|
||||||
| ^^^^^^^^^^^ the trait `Trait` cannot be made into an object
|
| ^^^^^^^^^^^ the trait `Trait` cannot be made into an object
|
||||||
|
|
|
|
||||||
@ -21,6 +27,9 @@ LL | takes_box(Box::new(S));
|
|||||||
error[E0038]: the trait `Trait` cannot be made into an object
|
error[E0038]: the trait `Trait` cannot be made into an object
|
||||||
--> $DIR/wf-convert-unsafe-trait-obj-box.rs:15:5
|
--> $DIR/wf-convert-unsafe-trait-obj-box.rs:15:5
|
||||||
|
|
|
|
||||||
|
LL | trait Trait: Sized {}
|
||||||
|
| ----- the trait cannot require that `Self : Sized`
|
||||||
|
...
|
||||||
LL | Box::new(S) as Box<dyn Trait>;
|
LL | Box::new(S) as Box<dyn Trait>;
|
||||||
| ^^^^^^^^^^^ the trait `Trait` cannot be made into an object
|
| ^^^^^^^^^^^ the trait `Trait` cannot be made into an object
|
||||||
|
|
|
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
error[E0038]: the trait `Trait` cannot be made into an object
|
error[E0038]: the trait `Trait` cannot be made into an object
|
||||||
--> $DIR/wf-convert-unsafe-trait-obj.rs:16:25
|
--> $DIR/wf-convert-unsafe-trait-obj.rs:16:25
|
||||||
|
|
|
|
||||||
|
LL | trait Trait: Sized {}
|
||||||
|
| ----- the trait cannot require that `Self : Sized`
|
||||||
|
...
|
||||||
LL | let t: &dyn Trait = &S;
|
LL | let t: &dyn Trait = &S;
|
||||||
| ^^ the trait `Trait` cannot be made into an object
|
| ^^ the trait `Trait` cannot be made into an object
|
||||||
|
|
|
|
||||||
@ -11,6 +14,9 @@ LL | let t: &dyn Trait = &S;
|
|||||||
error[E0038]: the trait `Trait` cannot be made into an object
|
error[E0038]: the trait `Trait` cannot be made into an object
|
||||||
--> $DIR/wf-convert-unsafe-trait-obj.rs:17:17
|
--> $DIR/wf-convert-unsafe-trait-obj.rs:17:17
|
||||||
|
|
|
|
||||||
|
LL | trait Trait: Sized {}
|
||||||
|
| ----- the trait cannot require that `Self : Sized`
|
||||||
|
...
|
||||||
LL | takes_trait(&S);
|
LL | takes_trait(&S);
|
||||||
| ^^ the trait `Trait` cannot be made into an object
|
| ^^ the trait `Trait` cannot be made into an object
|
||||||
|
|
|
|
||||||
@ -21,6 +27,9 @@ LL | takes_trait(&S);
|
|||||||
error[E0038]: the trait `Trait` cannot be made into an object
|
error[E0038]: the trait `Trait` cannot be made into an object
|
||||||
--> $DIR/wf-convert-unsafe-trait-obj.rs:15:5
|
--> $DIR/wf-convert-unsafe-trait-obj.rs:15:5
|
||||||
|
|
|
|
||||||
|
LL | trait Trait: Sized {}
|
||||||
|
| ----- the trait cannot require that `Self : Sized`
|
||||||
|
...
|
||||||
LL | &S as &dyn Trait;
|
LL | &S as &dyn Trait;
|
||||||
| ^^ the trait `Trait` cannot be made into an object
|
| ^^ the trait `Trait` cannot be made into an object
|
||||||
|
|
|
|
||||||
|
@ -15,6 +15,9 @@ LL | | }
|
|||||||
error[E0038]: the trait `Trait` cannot be made into an object
|
error[E0038]: the trait `Trait` cannot be made into an object
|
||||||
--> $DIR/wf-unsafe-trait-obj-match.rs:26:21
|
--> $DIR/wf-unsafe-trait-obj-match.rs:26:21
|
||||||
|
|
|
|
||||||
|
LL | trait Trait: Sized {}
|
||||||
|
| ----- the trait cannot require that `Self : Sized`
|
||||||
|
...
|
||||||
LL | Some(()) => &S,
|
LL | Some(()) => &S,
|
||||||
| ^^ the trait `Trait` cannot be made into an object
|
| ^^ the trait `Trait` cannot be made into an object
|
||||||
|
|
|
|
||||||
@ -25,6 +28,9 @@ LL | Some(()) => &S,
|
|||||||
error[E0038]: the trait `Trait` cannot be made into an object
|
error[E0038]: the trait `Trait` cannot be made into an object
|
||||||
--> $DIR/wf-unsafe-trait-obj-match.rs:25:25
|
--> $DIR/wf-unsafe-trait-obj-match.rs:25:25
|
||||||
|
|
|
|
||||||
|
LL | trait Trait: Sized {}
|
||||||
|
| ----- the trait cannot require that `Self : Sized`
|
||||||
|
...
|
||||||
LL | let t: &dyn Trait = match opt() {
|
LL | let t: &dyn Trait = match opt() {
|
||||||
| ^^^^^^^^^^^ the trait `Trait` cannot be made into an object
|
| ^^^^^^^^^^^ the trait `Trait` cannot be made into an object
|
||||||
|
|
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user