let mut reported_violations = FxHashSet::default();
for violation in violations {
if reported_violations.insert(violation.clone()) {
- err.note(&violation.error_msg());
+ match violation.span() {
+ Some(span) => err.span_label(span, violation.error_msg()),
+ None => err.note(&violation.error_msg()),
+ };
}
}
Some(err)
SupertraitSelf,
/// Method has something illegal.
- Method(ast::Name, MethodViolationCode),
+ Method(ast::Name, MethodViolationCode, Span),
/// Associated const.
- AssocConst(ast::Name),
+ AssocConst(ast::Name, Span),
}
impl ObjectSafetyViolation {
ObjectSafetyViolation::SupertraitSelf =>
"the trait cannot use `Self` as a type parameter \
in the supertraits or where-clauses".into(),
- ObjectSafetyViolation::Method(name, MethodViolationCode::StaticMethod) =>
+ ObjectSafetyViolation::Method(name, MethodViolationCode::StaticMethod, _) =>
format!("associated function `{}` has no `self` parameter", name).into(),
- ObjectSafetyViolation::Method(name, MethodViolationCode::ReferencesSelf) => format!(
+ ObjectSafetyViolation::Method(name, MethodViolationCode::ReferencesSelf, _) => format!(
"method `{}` references the `Self` type in its arguments or return type",
name,
).into(),
ObjectSafetyViolation::Method(
name,
- MethodViolationCode::WhereClauseReferencesSelf(_),
+ MethodViolationCode::WhereClauseReferencesSelf,
+ _,
) => format!("method `{}` references the `Self` type in where clauses", name).into(),
- ObjectSafetyViolation::Method(name, MethodViolationCode::Generic) =>
+ ObjectSafetyViolation::Method(name, MethodViolationCode::Generic, _) =>
format!("method `{}` has generic type parameters", name).into(),
- ObjectSafetyViolation::Method(name, MethodViolationCode::UndispatchableReceiver) =>
+ ObjectSafetyViolation::Method(name, MethodViolationCode::UndispatchableReceiver, _) =>
format!("method `{}`'s receiver cannot be dispatched on", name).into(),
- ObjectSafetyViolation::AssocConst(name) =>
+ ObjectSafetyViolation::AssocConst(name, _) =>
format!("the trait cannot contain associated consts like `{}`", name).into(),
}
}
+
+ pub fn span(&self) -> Option<Span> {
+ match self {
+ ObjectSafetyViolation::AssocConst(_, span) |
+ ObjectSafetyViolation::Method(_, _, span) => Some(*span),
+ _ => None,
+ }
+ }
}
/// Reasons a method might not be object-safe.
ReferencesSelf,
/// e.g., `fn foo(&self) where Self: Clone`
- WhereClauseReferencesSelf(Span),
+ WhereClauseReferencesSelf,
/// e.g., `fn foo<A>()`
Generic,
/// astconv -- currently, `Self` in supertraits. This is needed
/// because `object_safety_violations` can't be used during
/// type collection.
- pub fn astconv_object_safety_violations(self, trait_def_id: DefId)
- -> Vec<ObjectSafetyViolation>
- {
+ pub fn astconv_object_safety_violations(
+ self,
+ trait_def_id: DefId,
+ ) -> Vec<ObjectSafetyViolation> {
debug_assert!(self.generics_of(trait_def_id).has_self);
let violations = traits::supertrait_def_ids(self, trait_def_id)
.filter(|&def_id| self.predicates_reference_self(def_id, true))
}
match self.virtual_call_violation_for_method(trait_def_id, method) {
- None | Some(MethodViolationCode::WhereClauseReferencesSelf(_)) => true,
+ None | Some(MethodViolationCode::WhereClauseReferencesSelf) => true,
Some(_) => false,
}
}
let mut violations: Vec<_> = self.associated_items(trait_def_id)
.filter(|item| item.kind == ty::AssocKind::Method)
.filter_map(|item|
- self.object_safety_violation_for_method(trait_def_id, &item)
- .map(|code| ObjectSafetyViolation::Method(item.ident.name, code))
+ self.object_safety_violation_for_method(trait_def_id, &item).map(|code| {
+ ObjectSafetyViolation::Method(item.ident.name, code, item.ident.span)
+ })
).filter(|violation| {
- if let ObjectSafetyViolation::Method(_,
- MethodViolationCode::WhereClauseReferencesSelf(span)) = violation
- {
+ if let ObjectSafetyViolation::Method(
+ _,
+ MethodViolationCode::WhereClauseReferencesSelf,
+ span,
+ ) = violation {
// 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.
self.lint_node_note(
violations.extend(self.associated_items(trait_def_id)
.filter(|item| item.kind == ty::AssocKind::Const)
- .map(|item| ObjectSafetyViolation::AssocConst(item.ident.name)));
+ .map(|item| ObjectSafetyViolation::AssocConst(item.ident.name, item.ident.span)));
debug!("object_safety_violations_for_trait(trait_def_id={:?}) = {:?}",
trait_def_id,
.visit_tys_shallow(|t| {
self.contains_illegal_self_type_reference(trait_def_id, t)
}) {
- let span = self.def_span(method.def_id);
- return Some(MethodViolationCode::WhereClauseReferencesSelf(span));
+ return Some(MethodViolationCode::WhereClauseReferencesSelf);
}
let receiver_ty = self.liberate_late_bound_regions(
error[E0038]: the trait `Trait` cannot be made into an object
--> $DIR/associated-const-in-trait.rs:9:6
|
+LL | const N: usize;
+ | - the trait cannot contain associated consts like `N`
+...
LL | impl dyn Trait {
| ^^^^^^^^^ the trait `Trait` cannot be made into an object
- |
- = note: the trait cannot contain associated consts like `N`
error: aborting due to previous error
error[E0038]: the trait `NotObjectSafe` cannot be made into an object
--> $DIR/coherence-impl-trait-for-trait-object-safe.rs:11:6
|
+LL | trait NotObjectSafe { fn eq(&self, other: Self); }
+ | -- method `eq` references the `Self` type in its arguments or return type
LL | impl NotObjectSafe for dyn NotObjectSafe { }
| ^^^^^^^^^^^^^ the trait `NotObjectSafe` cannot be made into an object
- |
- = note: method `eq` references the `Self` type in its arguments or return type
error: aborting due to previous error
error[E0038]: the trait `NotObjectSafe` cannot be made into an object
--> $DIR/coherence-impl-trait-for-trait-object-safe.rs:11:6
|
+LL | trait NotObjectSafe { fn eq(&self, other: Self); }
+ | -- method `eq` references the `Self` type in its arguments or return type
LL | impl NotObjectSafe for dyn NotObjectSafe { }
| ^^^^^^^^^^^^^ the trait `NotObjectSafe` cannot be made into an object
- |
- = note: method `eq` references the `Self` type in its arguments or return type
error: aborting due to previous error
|
LL | impl dyn X {
| ^^^^^ the trait `X` cannot be made into an object
- |
- = note: associated function `xxx` has no `self` parameter
+...
+LL | fn xxx() { ### }
+ | --- associated function `xxx` has no `self` parameter
error: aborting due to 9 previous errors
// compile-flags: -Z teach
trait SomeTrait {
- fn foo();
+ fn foo(); //~ associated function `foo` has no `self` parameter
}
fn main() {
let trait_obj: &dyn SomeTrait = SomeTrait;
//~^ ERROR expected value, found trait `SomeTrait`
//~| ERROR E0038
- //~| associated function `foo` has no `self` parameter
let &invalid = trait_obj;
//~^ ERROR E0033
error[E0038]: the trait `SomeTrait` cannot be made into an object
--> $DIR/E0033-teach.rs:8:20
|
+LL | fn foo();
+ | --- associated function `foo` has no `self` parameter
+...
LL | let trait_obj: &dyn SomeTrait = SomeTrait;
| ^^^^^^^^^^^^^^ the trait `SomeTrait` cannot be made into an object
- |
- = note: associated function `foo` has no `self` parameter
error[E0033]: type `&dyn SomeTrait` cannot be dereferenced
- --> $DIR/E0033-teach.rs:13:9
+ --> $DIR/E0033-teach.rs:12:9
|
LL | let &invalid = trait_obj;
| ^^^^^^^^ type `&dyn SomeTrait` cannot be dereferenced
trait SomeTrait {
- fn foo();
+ fn foo(); //~ associated function `foo` has no `self` parameter
}
fn main() {
let trait_obj: &dyn SomeTrait = SomeTrait;
//~^ ERROR expected value, found trait `SomeTrait`
//~| ERROR E0038
- //~| associated function `foo` has no `self` parameter
let &invalid = trait_obj;
//~^ ERROR E0033
error[E0038]: the trait `SomeTrait` cannot be made into an object
--> $DIR/E0033.rs:6:20
|
+LL | fn foo();
+ | --- associated function `foo` has no `self` parameter
+...
LL | let trait_obj: &dyn SomeTrait = SomeTrait;
| ^^^^^^^^^^^^^^ the trait `SomeTrait` cannot be made into an object
- |
- = note: associated function `foo` has no `self` parameter
error[E0033]: type `&dyn SomeTrait` cannot be dereferenced
- --> $DIR/E0033.rs:11:9
+ --> $DIR/E0033.rs:10:9
|
LL | let &invalid = trait_obj;
| ^^^^^^^^ type `&dyn SomeTrait` cannot be dereferenced
error[E0038]: the trait `Trait` cannot be made into an object
--> $DIR/E0038.rs:5:1
|
+LL | fn foo(&self) -> Self;
+ | --- method `foo` references the `Self` type in its arguments or return type
+...
LL | fn call_foo(x: Box<dyn Trait>) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` cannot be made into an object
- |
- = note: method `foo` references the `Self` type in its arguments or return type
error: aborting due to previous error
error[E0038]: the trait `Bar` cannot be made into an object
--> $DIR/issue-18959.rs:11:1
|
+LL | pub trait Foo { fn foo<T>(&self, ext_thing: &T); }
+ | --- method `foo` has generic type parameters
+...
LL | fn foo(b: &dyn Bar) {
| ^^^^^^^^^^^^^^^^^^^ the trait `Bar` cannot be made into an object
- |
- = note: method `foo` has generic type parameters
error: aborting due to previous error
error[E0038]: the trait `Qiz` cannot be made into an object
--> $DIR/issue-19380.rs:11:3
|
+LL | fn qiz();
+ | --- associated function `qiz` has no `self` parameter
+...
LL | foos: &'static [&'static (dyn Qiz + 'static)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Qiz` cannot be made into an object
- |
- = note: associated function `qiz` has no `self` parameter
error: aborting due to previous error
error[E0038]: the trait `Bar` cannot be made into an object
--> $DIR/issue-19538.rs:17:15
|
+LL | fn foo<T>(&self, val: T);
+ | --- method `foo` has generic type parameters
+...
LL | let test: &mut dyn Bar = &mut thing;
| ^^^^^^^^^^^^ the trait `Bar` cannot be made into an object
- |
- = note: method `foo` has generic type parameters
error[E0038]: the trait `Bar` cannot be made into an object
--> $DIR/issue-19538.rs:17:30
|
+LL | fn foo<T>(&self, val: T);
+ | --- method `foo` has generic type parameters
+...
LL | let test: &mut dyn Bar = &mut thing;
| ^^^^^^^^^^ the trait `Bar` cannot be made into an object
|
- = note: method `foo` has generic type parameters
= note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&mut dyn Bar>` for `&mut Thing`
error: aborting due to 2 previous errors
error: the trait `X` cannot be made into an object
- --> $DIR/issue-50781.rs:6:5
+ --> $DIR/issue-50781.rs:6:8
|
LL | fn foo(&self) where Self: Trait;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^
|
note: lint level defined here
--> $DIR/issue-50781.rs:1:9
error[E0038]: the trait `Bar` cannot be made into an object
--> $DIR/object-safety-associated-consts.rs:9:1
|
+LL | const X: usize;
+ | - the trait cannot contain associated consts like `X`
+...
LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bar` cannot be made into an object
- |
- = note: the trait cannot contain associated consts like `X`
error: aborting due to previous error
error[E0038]: the trait `Bar` cannot be made into an object
--> $DIR/object-safety-generics.rs:14:1
|
+LL | fn bar<T>(&self, t: T);
+ | --- method `bar` has generic type parameters
+...
LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bar` cannot be made into an object
- |
- = note: method `bar` has generic type parameters
error[E0038]: the trait `Bar` cannot be made into an object
--> $DIR/object-safety-generics.rs:19:1
|
+LL | fn bar<T>(&self, t: T);
+ | --- method `bar` has generic type parameters
+...
LL | fn make_bar_explicit<T:Bar>(t: &T) -> &dyn Bar {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bar` cannot be made into an object
- |
- = note: method `bar` has generic type parameters
error: aborting due to 2 previous errors
error[E0038]: the trait `Bar` cannot be made into an object
--> $DIR/object-safety-mentions-Self.rs:17:1
|
+LL | fn bar(&self, x: &Self);
+ | --- method `bar` references the `Self` type in its arguments or return type
+...
LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bar` cannot be made into an object
- |
- = note: method `bar` references the `Self` type in its arguments or return type
error[E0038]: the trait `Baz` cannot be made into an object
--> $DIR/object-safety-mentions-Self.rs:22:1
|
+LL | fn bar(&self) -> Self;
+ | --- method `bar` references the `Self` type in its arguments or return type
+...
LL | fn make_baz<T:Baz>(t: &T) -> &dyn Baz {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Baz` cannot be made into an object
- |
- = note: method `bar` references the `Self` type in its arguments or return type
error: aborting due to 2 previous errors
error[E0038]: the trait `Foo` cannot be made into an object
--> $DIR/object-safety-no-static.rs:8:1
|
+LL | fn foo();
+ | --- associated function `foo` has no `self` parameter
+...
LL | fn foo_implicit<T:Foo+'static>(b: Box<T>) -> Box<dyn Foo + 'static> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` cannot be made into an object
- |
- = note: associated function `foo` has no `self` parameter
error: aborting due to previous error
|
LL | fn bar(_x: Foo) {}
| ^^^^^^^^^^^^^^^ the trait `issue_3907::Foo` cannot be made into an object
- |
- = note: associated function `bar` has no `self` parameter
error: aborting due to previous error
error[E0038]: the trait `Foo` cannot be made into an object
--> $DIR/arbitrary-self-types-not-object-safe.rs:31:32
|
+LL | fn foo(self: &Rc<Self>) -> usize;
+ | --- method `foo`'s receiver cannot be dispatched on
+...
LL | let x = Rc::new(5usize) as Rc<dyn Foo>;
| ^^^^^^^^^^^ the trait `Foo` cannot be made into an object
- |
- = note: method `foo`'s receiver cannot be dispatched on
error[E0038]: the trait `Foo` cannot be made into an object
--> $DIR/arbitrary-self-types-not-object-safe.rs:31:13
|
+LL | fn foo(self: &Rc<Self>) -> usize;
+ | --- method `foo`'s receiver cannot be dispatched on
+...
LL | let x = Rc::new(5usize) as Rc<dyn Foo>;
| ^^^^^^^^^^^^^^^ the trait `Foo` cannot be made into an object
|
- = note: method `foo`'s receiver cannot be dispatched on
= note: required because of the requirements on the impl of `std::ops::CoerceUnsized<std::rc::Rc<dyn Foo>>` for `std::rc::Rc<usize>`
error: aborting due to 2 previous errors
error[E0038]: the trait `assoc_const::C` cannot be made into an object
--> $DIR/trait-item-privacy.rs:101:5
|
+LL | const A: u8 = 0;
+ | - the trait cannot contain associated consts like `A`
+...
+LL | const B: u8 = 0;
+ | - the trait cannot contain associated consts like `B`
+...
+LL | const C: u8 = 0;
+ | - the trait cannot contain associated consts like `C`
+...
LL | C::A;
| ^^^^ the trait `assoc_const::C` cannot be made into an object
- |
- = note: the trait cannot contain associated consts like `C`
- = note: the trait cannot contain associated consts like `B`
- = note: the trait cannot contain associated consts like `A`
error[E0223]: ambiguous associated type
--> $DIR/trait-item-privacy.rs:115:12
error[E0038]: the trait `Tr` cannot be made into an object
--> $DIR/trait-object-safety.rs:15:22
|
+LL | fn foo();
+ | --- associated function `foo` has no `self` parameter
+...
LL | let _: &dyn Tr = &St;
| ^^^ the trait `Tr` cannot be made into an object
|
- = note: associated function `foo` has no `self` parameter
= note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Tr>` for `&St`
error[E0038]: the trait `Tr` cannot be made into an object
--> $DIR/trait-object-safety.rs:15:12
|
+LL | fn foo();
+ | --- associated function `foo` has no `self` parameter
+...
LL | let _: &dyn Tr = &St;
| ^^^^^^^ the trait `Tr` cannot be made into an object
- |
- = note: associated function `foo` has no `self` parameter
error: aborting due to 2 previous errors
error[E0038]: the trait `bar` cannot be made into an object
--> $DIR/trait-test-2.rs:11:16
|
+LL | trait bar { fn dup(&self) -> Self; fn blah<X>(&self); }
+ | --- ---- method `blah` has generic type parameters
+ | |
+ | method `dup` references the `Self` type in its arguments or return type
+...
LL | (box 10 as Box<dyn bar>).dup();
| ^^^^^^^^^^^^ the trait `bar` cannot be made into an object
- |
- = note: method `dup` references the `Self` type in its arguments or return type
- = note: method `blah` has generic type parameters
error[E0038]: the trait `bar` cannot be made into an object
--> $DIR/trait-test-2.rs:11:6
|
+LL | trait bar { fn dup(&self) -> Self; fn blah<X>(&self); }
+ | --- ---- method `blah` has generic type parameters
+ | |
+ | method `dup` references the `Self` type in its arguments or return type
+...
LL | (box 10 as Box<dyn bar>).dup();
| ^^^^^^ the trait `bar` cannot be made into an object
|
- = note: method `dup` references the `Self` type in its arguments or return type
- = note: method `blah` has generic type parameters
= note: required because of the requirements on the impl of `std::ops::CoerceUnsized<std::boxed::Box<dyn bar>>` for `std::boxed::Box<{integer}>`
error: aborting due to 4 previous errors
error[E0038]: the trait `MyAdd` cannot be made into an object
--> $DIR/type-parameter-defaults-referencing-Self-ppaux.rs:14:18
|
+LL | trait MyAdd<Rhs=Self> { fn add(&self, other: &Rhs) -> Self; }
+ | --- method `add` references the `Self` type in its arguments or return type
+...
LL | let y = x as dyn MyAdd<i32>;
| ^^^^^^^^^^^^^^ the trait `MyAdd` cannot be made into an object
- |
- = note: method `add` references the `Self` type in its arguments or return type
error: aborting due to 2 previous errors
error[E0038]: the trait `A` cannot be made into an object
--> $DIR/wf-object-safe.rs:9:13
|
+LL | fn foo(&self, _x: &Self);
+ | --- method `foo` references the `Self` type in its arguments or return type
+...
LL | let _x: &dyn A;
| ^^^^^^ the trait `A` cannot be made into an object
- |
- = note: method `foo` references the `Self` type in its arguments or return type
error: aborting due to previous error