#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub enum ObjectSafetyViolation {
/// `Self: Sized` declared on the trait.
- SizedSelf,
+ SizedSelf(Span),
/// Supertrait reference references `Self` an in illegal location
/// (e.g., `trait Foo : Bar<Self>`).
impl ObjectSafetyViolation {
pub fn error_msg(&self) -> Cow<'static, str> {
match *self {
- ObjectSafetyViolation::SizedSelf => {
+ ObjectSafetyViolation::SizedSelf(_) => {
"the trait cannot require that `Self : Sized`".into()
}
ObjectSafetyViolation::SupertraitSelf => {
// diagnostics use a `note` instead of a `span_label`.
match *self {
ObjectSafetyViolation::AssocConst(_, span)
+ | ObjectSafetyViolation::SizedSelf(span)
| ObjectSafetyViolation::Method(_, _, span)
if span != DUMMY_SP =>
{
{
// 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.
- tcx.struct_span_lint_hir(
+ let mut err = tcx.struct_span_lint_hir(
WHERE_CLAUSES_OBJECT_SAFETY,
hir::CRATE_HIR_ID,
*span,
"the trait `{}` cannot be made into an object",
tcx.def_path_str(trait_def_id)
),
- )
- .note(&violation.error_msg())
- .emit();
+ );
+ match violation.span() {
+ Some(span) => err.span_label(span, violation.error_msg()),
+ None => err.note(&violation.error_msg()),
+ };
+ err.emit();
false
} else {
true
// Check the trait itself.
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) {
violations.push(ObjectSafetyViolation::SupertraitSelf);
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 {
let trait_ref = ty::Binder::dummy(ty::TraitRef::identity(tcx, trait_def_id));
let predicates = if supertraits_only {
error[E0038]: the trait `NonObjectSafe1` cannot be made into an object
--> $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) {
| ^^^^^^^^^^^^^^^^^^^ 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
|
+LL | trait NonObjectSafe1: Sized {}
+ | ----- the trait cannot require that `Self : Sized`
+...
LL | impl Trait for dyn NonObjectSafe1 {}
| ^^^^^ the trait `NonObjectSafe1` cannot be made into an object
|
error[E0038]: the trait `Array` cannot be made into an object
--> $DIR/issue-20692.rs:7:5
|
+LL | trait Array: Sized {}
+ | ----- the trait cannot require that `Self : Sized`
+...
LL | &dyn Array;
| ^^^^^^^^^^ 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
|
+LL | trait Array: Sized {}
+ | ----- the trait cannot require that `Self : Sized`
+...
LL | let _ = x
| ^ the trait `Array` cannot be made into an object
|
--> $DIR/issue-50781.rs:6:8
|
LL | fn foo(&self) where Self: Trait;
- | ^^^
+ | ^^^ method `foo` references the `Self` type in where clauses
|
note: the lint level is defined here
--> $DIR/issue-50781.rs:1:9
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
= 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: method `foo` references the `Self` type in where clauses
error: aborting due to previous error
error[E0038]: the trait `Bar` cannot be made into an object
--> $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 {
| ^^^^^^^^ 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
|
+LL | trait Bar : Sized {
+ | ----- the trait cannot require that `Self : Sized`
+...
LL | t
| ^ the trait `Bar` 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
|
+LL | trait Trait: Sized {}
+ | ----- the trait cannot require that `Self : Sized`
+...
LL | let t_box: Box<dyn Trait> = Box::new(S);
| ^^^^^^^^^^^ 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
|
+LL | trait Trait: Sized {}
+ | ----- the trait cannot require that `Self : Sized`
+...
LL | takes_box(Box::new(S));
| ^^^^^^^^^^^ 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
|
+LL | trait Trait: Sized {}
+ | ----- the trait cannot require that `Self : Sized`
+...
LL | Box::new(S) as Box<dyn Trait>;
| ^^^^^^^^^^^ 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
|
+LL | trait Trait: Sized {}
+ | ----- the trait cannot require that `Self : Sized`
+...
LL | let t: &dyn Trait = &S;
| ^^ 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
|
+LL | trait Trait: Sized {}
+ | ----- the trait cannot require that `Self : Sized`
+...
LL | takes_trait(&S);
| ^^ 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
|
+LL | trait Trait: Sized {}
+ | ----- the trait cannot require that `Self : Sized`
+...
LL | &S as &dyn Trait;
| ^^ 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
|
+LL | trait Trait: Sized {}
+ | ----- the trait cannot require that `Self : Sized`
+...
LL | Some(()) => &S,
| ^^ 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
|
+LL | trait Trait: Sized {}
+ | ----- the trait cannot require that `Self : Sized`
+...
LL | let t: &dyn Trait = match opt() {
| ^^^^^^^^^^^ the trait `Trait` cannot be made into an object
|