Use more appropriate spans on object unsafe traits and provide structured suggestions when possible
This commit is contained in:
parent
413bfa4b98
commit
a52ec87a17
@ -1073,10 +1073,16 @@ pub fn report_object_safety_error(
|
||||
err.span_label(span, &msg);
|
||||
}
|
||||
}
|
||||
if let (Some(_), Some(note)) = (trait_span, violation.solution()) {
|
||||
// Only provide the help if its a local trait, otherwise it's not actionable.
|
||||
match (trait_span, violation.solution()) {
|
||||
(Some(_), Some((note, None))) => {
|
||||
err.help(¬e);
|
||||
}
|
||||
(Some(_), Some((note, Some((sugg, span))))) => {
|
||||
err.span_suggestion(span, ¬e, sugg, Applicability::MachineApplicable);
|
||||
}
|
||||
// Only provide the help if its a local trait, otherwise it's not actionable.
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
if let (Some(trait_span), true) = (trait_span, had_span_label) {
|
||||
|
@ -13,6 +13,7 @@ use super::elaborate_predicates;
|
||||
use crate::traits::{self, Obligation, ObligationCause};
|
||||
use crate::ty::subst::{InternalSubsts, Subst};
|
||||
use crate::ty::{self, Predicate, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_session::lint::builtin::WHERE_CLAUSES_OBJECT_SAFETY;
|
||||
@ -48,14 +49,20 @@ impl ObjectSafetyViolation {
|
||||
"it 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!(
|
||||
"method `{}` references the `Self` type in its parameters or return type",
|
||||
ObjectSafetyViolation::Method(
|
||||
name,
|
||||
)
|
||||
.into(),
|
||||
MethodViolationCode::ReferencesSelfInput(_),
|
||||
DUMMY_SP,
|
||||
) => format!("method `{}` references the `Self` type in its parameters", name).into(),
|
||||
ObjectSafetyViolation::Method(name, MethodViolationCode::ReferencesSelfInput(_), _) => {
|
||||
format!("method `{}` references the `Self` type in this parameter", name).into()
|
||||
}
|
||||
ObjectSafetyViolation::Method(name, MethodViolationCode::ReferencesSelfOutput, _) => {
|
||||
format!("method `{}` references the `Self` type in its return type", name).into()
|
||||
}
|
||||
ObjectSafetyViolation::Method(
|
||||
name,
|
||||
MethodViolationCode::WhereClauseReferencesSelf,
|
||||
@ -78,23 +85,31 @@ impl ObjectSafetyViolation {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn solution(&self) -> Option<String> {
|
||||
pub fn solution(&self) -> Option<(String, Option<(String, Span)>)> {
|
||||
Some(match *self {
|
||||
ObjectSafetyViolation::SizedSelf(_) | ObjectSafetyViolation::SupertraitSelf => {
|
||||
return None;
|
||||
}
|
||||
ObjectSafetyViolation::Method(name, MethodViolationCode::StaticMethod, _) => format!(
|
||||
ObjectSafetyViolation::Method(name, MethodViolationCode::StaticMethod(sugg), _) => (
|
||||
format!(
|
||||
"consider turning `{}` into a method by giving it a `&self` argument or \
|
||||
constraining it with `where Self: Sized`",
|
||||
constraining it so it does not apply to trait objects",
|
||||
name
|
||||
),
|
||||
ObjectSafetyViolation::Method(name, MethodViolationCode::UndispatchableReceiver, _) => {
|
||||
sugg.map(|(sugg, sp)| (sugg.to_string(), sp)),
|
||||
),
|
||||
ObjectSafetyViolation::Method(
|
||||
name,
|
||||
MethodViolationCode::UndispatchableReceiver,
|
||||
span,
|
||||
) => (
|
||||
format!("consider changing method `{}`'s `self` parameter to be `&self`", name)
|
||||
.into()
|
||||
}
|
||||
.into(),
|
||||
Some(("&Self".to_string(), span)),
|
||||
),
|
||||
ObjectSafetyViolation::AssocConst(name, _)
|
||||
| ObjectSafetyViolation::Method(name, ..) => {
|
||||
format!("consider moving `{}` to another trait", name)
|
||||
(format!("consider moving `{}` to another trait", name), None)
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -119,10 +134,13 @@ impl ObjectSafetyViolation {
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub enum MethodViolationCode {
|
||||
/// e.g., `fn foo()`
|
||||
StaticMethod,
|
||||
StaticMethod(Option<(&'static str, Span)>),
|
||||
|
||||
/// e.g., `fn foo(&self, x: Self)` or `fn foo(&self) -> Self`
|
||||
ReferencesSelf,
|
||||
/// e.g., `fn foo(&self, x: Self)`
|
||||
ReferencesSelfInput(usize),
|
||||
|
||||
/// e.g., `fn foo(&self) -> Self`
|
||||
ReferencesSelfOutput,
|
||||
|
||||
/// e.g., `fn foo(&self) where Self: Clone`
|
||||
WhereClauseReferencesSelf,
|
||||
@ -193,7 +211,7 @@ fn object_safety_violations_for_trait(
|
||||
.filter(|item| item.kind == ty::AssocKind::Method)
|
||||
.filter_map(|item| {
|
||||
object_safety_violation_for_method(tcx, trait_def_id, &item)
|
||||
.map(|code| ObjectSafetyViolation::Method(item.ident.name, code, item.ident.span))
|
||||
.map(|(code, span)| ObjectSafetyViolation::Method(item.ident.name, code, span))
|
||||
})
|
||||
.filter(|violation| {
|
||||
if let ObjectSafetyViolation::Method(
|
||||
@ -224,10 +242,16 @@ fn object_safety_violations_for_trait(
|
||||
)
|
||||
};
|
||||
err.span_label(*span, &msg);
|
||||
if let (Some(_), Some(note)) = (node, violation.solution()) {
|
||||
// Only provide the help if its a local trait, otherwise it's not actionable.
|
||||
match (node, violation.solution()) {
|
||||
(Some(_), Some((note, None))) => {
|
||||
err.help(¬e);
|
||||
}
|
||||
(Some(_), Some((note, Some((sugg, span))))) => {
|
||||
err.span_suggestion(span, ¬e, sugg, Applicability::MachineApplicable);
|
||||
}
|
||||
// Only provide the help if its a local trait, otherwise it's not actionable.
|
||||
_ => {}
|
||||
}
|
||||
err.emit();
|
||||
false
|
||||
} else {
|
||||
@ -398,7 +422,7 @@ fn object_safety_violation_for_method(
|
||||
tcx: TyCtxt<'_>,
|
||||
trait_def_id: DefId,
|
||||
method: &ty::AssocItem,
|
||||
) -> Option<MethodViolationCode> {
|
||||
) -> Option<(MethodViolationCode, Span)> {
|
||||
debug!("object_safety_violation_for_method({:?}, {:?})", trait_def_id, method);
|
||||
// Any method that has a `Self : Sized` requisite is otherwise
|
||||
// exempt from the regulations.
|
||||
@ -406,7 +430,26 @@ fn object_safety_violation_for_method(
|
||||
return None;
|
||||
}
|
||||
|
||||
virtual_call_violation_for_method(tcx, trait_def_id, method)
|
||||
let violation = virtual_call_violation_for_method(tcx, trait_def_id, method);
|
||||
// Get an accurate span depending on the violation.
|
||||
violation.map(|v| {
|
||||
let node = tcx.hir().get_if_local(method.def_id);
|
||||
let span = match (v, node) {
|
||||
(MethodViolationCode::ReferencesSelfInput(arg), Some(node)) => node
|
||||
.fn_decl()
|
||||
.and_then(|decl| decl.inputs.get(arg + 1))
|
||||
.map_or(method.ident.span, |arg| arg.span),
|
||||
(MethodViolationCode::UndispatchableReceiver, Some(node)) => node
|
||||
.fn_decl()
|
||||
.and_then(|decl| decl.inputs.get(0))
|
||||
.map_or(method.ident.span, |arg| arg.span),
|
||||
(MethodViolationCode::ReferencesSelfOutput, Some(node)) => {
|
||||
node.fn_decl().map_or(method.ident.span, |decl| decl.output.span())
|
||||
}
|
||||
_ => method.ident.span,
|
||||
};
|
||||
(v, span)
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns `Some(_)` if this method cannot be called on a trait
|
||||
@ -420,18 +463,26 @@ fn virtual_call_violation_for_method<'tcx>(
|
||||
) -> Option<MethodViolationCode> {
|
||||
// The method's first parameter must be named `self`
|
||||
if !method.method_has_self_argument {
|
||||
return Some(MethodViolationCode::StaticMethod);
|
||||
// We'll attempt to provide a structured suggestion for `Self: Sized`.
|
||||
let sugg =
|
||||
tcx.hir().get_if_local(method.def_id).as_ref().and_then(|node| node.generics()).map(
|
||||
|generics| match generics.where_clause.predicates {
|
||||
[] => (" where Self: Sized", generics.where_clause.span),
|
||||
[.., pred] => (", Self: Sized", pred.span().shrink_to_hi()),
|
||||
},
|
||||
);
|
||||
return Some(MethodViolationCode::StaticMethod(sugg));
|
||||
}
|
||||
|
||||
let sig = tcx.fn_sig(method.def_id);
|
||||
|
||||
for input_ty in &sig.skip_binder().inputs()[1..] {
|
||||
for (i, input_ty) in sig.skip_binder().inputs()[1..].iter().enumerate() {
|
||||
if contains_illegal_self_type_reference(tcx, trait_def_id, input_ty) {
|
||||
return Some(MethodViolationCode::ReferencesSelf);
|
||||
return Some(MethodViolationCode::ReferencesSelfInput(i));
|
||||
}
|
||||
}
|
||||
if contains_illegal_self_type_reference(tcx, trait_def_id, sig.output().skip_binder()) {
|
||||
return Some(MethodViolationCode::ReferencesSelf);
|
||||
return Some(MethodViolationCode::ReferencesSelfOutput);
|
||||
}
|
||||
|
||||
// We can't monomorphize things like `fn foo<A>(...)`.
|
||||
|
@ -2631,4 +2631,25 @@ impl Node<'_> {
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn fn_decl(&self) -> Option<&FnDecl<'_>> {
|
||||
match self {
|
||||
Node::TraitItem(TraitItem { kind: TraitItemKind::Method(fn_sig, _), .. })
|
||||
| Node::ImplItem(ImplItem { kind: ImplItemKind::Method(fn_sig, _), .. })
|
||||
| Node::Item(Item { kind: ItemKind::Fn(fn_sig, _, _), .. }) => Some(fn_sig.decl),
|
||||
Node::ForeignItem(ForeignItem { kind: ForeignItemKind::Fn(fn_decl, _, _), .. }) => {
|
||||
Some(fn_decl)
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn generics(&self) -> Option<&Generics<'_>> {
|
||||
match self {
|
||||
Node::TraitItem(TraitItem { generics, .. })
|
||||
| Node::ImplItem(ImplItem { generics, .. })
|
||||
| Node::Item(Item { kind: ItemKind::Fn(_, generics, _), .. }) => Some(generics),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -172,7 +172,7 @@ impl<'a> Parser<'a> {
|
||||
/// ```
|
||||
pub(super) fn parse_where_clause(&mut self) -> PResult<'a, WhereClause> {
|
||||
let mut where_clause =
|
||||
WhereClause { predicates: Vec::new(), span: self.prev_span.to(self.prev_span) };
|
||||
WhereClause { predicates: Vec::new(), span: self.prev_span.shrink_to_hi() };
|
||||
|
||||
if !self.eat_keyword(kw::Where) {
|
||||
return Ok(where_clause);
|
||||
|
@ -2,7 +2,7 @@ error[E0038]: the trait `NotObjectSafe` cannot be made into an object
|
||||
--> $DIR/coherence-impl-trait-for-trait-object-safe.rs:7:6
|
||||
|
|
||||
LL | trait NotObjectSafe { fn eq(&self, other: Self); }
|
||||
| ------------- -- ...because method `eq` references the `Self` type in its parameters or return type
|
||||
| ------------- ---- ...because method `eq` references the `Self` type in this parameter
|
||||
| |
|
||||
| this trait cannot be made into an object...
|
||||
LL | impl NotObjectSafe for dyn NotObjectSafe { }
|
||||
|
@ -15,7 +15,10 @@ LL | fn foo();
|
||||
LL | let trait_obj: &dyn SomeTrait = SomeTrait;
|
||||
| ^^^^^^^^^^^^^^ the trait `SomeTrait` cannot be made into an object
|
||||
|
|
||||
= help: consider turning `foo` into a method by giving it a `&self` argument or constraining it with `where Self: Sized`
|
||||
help: consider turning `foo` into a method by giving it a `&self` argument or constraining it so it does not apply to trait objects
|
||||
|
|
||||
LL | fn foo() where Self: Sized;
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0033]: type `&dyn SomeTrait` cannot be dereferenced
|
||||
--> $DIR/E0033-teach.rs:12:9
|
||||
|
@ -15,7 +15,10 @@ LL | fn foo();
|
||||
LL | let trait_obj: &dyn SomeTrait = SomeTrait;
|
||||
| ^^^^^^^^^^^^^^ the trait `SomeTrait` cannot be made into an object
|
||||
|
|
||||
= help: consider turning `foo` into a method by giving it a `&self` argument or constraining it with `where Self: Sized`
|
||||
help: consider turning `foo` into a method by giving it a `&self` argument or constraining it so it does not apply to trait objects
|
||||
|
|
||||
LL | fn foo() where Self: Sized;
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0033]: type `&dyn SomeTrait` cannot be dereferenced
|
||||
--> $DIR/E0033.rs:10:9
|
||||
|
@ -4,7 +4,7 @@ error[E0038]: the trait `Trait` cannot be made into an object
|
||||
LL | trait Trait {
|
||||
| ----- this trait cannot be made into an object...
|
||||
LL | fn foo(&self) -> Self;
|
||||
| --- ...because method `foo` references the `Self` type in its parameters or return type
|
||||
| ---- ...because method `foo` references the `Self` type in its return type
|
||||
...
|
||||
LL | fn call_foo(x: Box<dyn Trait>) {
|
||||
| ^^^^^^^^^^^^^^ the trait `Trait` cannot be made into an object
|
||||
|
@ -20,7 +20,10 @@ LL | fn static_fn() {}
|
||||
LL | fn return_non_object_safe_ref() -> &'static dyn NonObjectSafe2 {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NonObjectSafe2` cannot be made into an object
|
||||
|
|
||||
= help: consider turning `static_fn` into a method by giving it a `&self` argument or constraining it with `where Self: Sized`
|
||||
help: consider turning `static_fn` into a method by giving it a `&self` argument or constraining it so it does not apply to trait objects
|
||||
|
|
||||
LL | fn static_fn() where Self: Sized {}
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0038]: the trait `NonObjectSafe3` cannot be made into an object
|
||||
--> $DIR/feature-gate-object_safe_for_dispatch.rs:27:35
|
||||
@ -41,7 +44,7 @@ error[E0038]: the trait `NonObjectSafe4` cannot be made into an object
|
||||
LL | trait NonObjectSafe4 {
|
||||
| -------------- this trait cannot be made into an object...
|
||||
LL | fn foo(&self, &Self);
|
||||
| --- ...because method `foo` references the `Self` type in its parameters or return type
|
||||
| ----- ...because method `foo` references the `Self` type in this parameter
|
||||
...
|
||||
LL | fn return_non_object_safe_rc() -> std::rc::Rc<dyn NonObjectSafe4> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NonObjectSafe4` cannot be made into an object
|
||||
|
@ -9,7 +9,10 @@ LL | fn foo() -> Self;
|
||||
LL | fn car() -> dyn NotObjectSafe {
|
||||
| ^^^^^^^^^^^^^^^^^ the trait `NotObjectSafe` cannot be made into an object
|
||||
|
|
||||
= help: consider turning `foo` into a method by giving it a `&self` argument or constraining it with `where Self: Sized`
|
||||
help: consider turning `foo` into a method by giving it a `&self` argument or constraining it so it does not apply to trait objects
|
||||
|
|
||||
LL | fn foo() -> Self where Self: Sized;
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0038]: the trait `NotObjectSafe` cannot be made into an object
|
||||
--> $DIR/object-unsafe-trait-in-return-position-dyn-trait.rs:28:13
|
||||
@ -22,7 +25,10 @@ LL | fn foo() -> Self;
|
||||
LL | fn cat() -> Box<dyn NotObjectSafe> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ the trait `NotObjectSafe` cannot be made into an object
|
||||
|
|
||||
= help: consider turning `foo` into a method by giving it a `&self` argument or constraining it with `where Self: Sized`
|
||||
help: consider turning `foo` into a method by giving it a `&self` argument or constraining it so it does not apply to trait objects
|
||||
|
|
||||
LL | fn foo() -> Self where Self: Sized;
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -9,7 +9,10 @@ LL | fn qiz();
|
||||
LL | foos: &'static [&'static (dyn Qiz + 'static)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Qiz` cannot be made into an object
|
||||
|
|
||||
= help: consider turning `qiz` into a method by giving it a `&self` argument or constraining it with `where Self: Sized`
|
||||
help: consider turning `qiz` into a method by giving it a `&self` argument or constraining it so it does not apply to trait objects
|
||||
|
|
||||
LL | fn qiz() where Self: Sized;
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -4,7 +4,7 @@ error[E0038]: the trait `Bar` cannot be made into an object
|
||||
LL | trait Bar {
|
||||
| --- this trait cannot be made into an object...
|
||||
LL | fn bar(&self, x: &Self);
|
||||
| --- ...because method `bar` references the `Self` type in its parameters or return type
|
||||
| ----- ...because method `bar` references the `Self` type in this parameter
|
||||
...
|
||||
LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
|
||||
| ^^^^^^^^ the trait `Bar` cannot be made into an object
|
||||
@ -17,7 +17,7 @@ error[E0038]: the trait `Baz` cannot be made into an object
|
||||
LL | trait Baz {
|
||||
| --- this trait cannot be made into an object...
|
||||
LL | fn baz(&self) -> Self;
|
||||
| --- ...because method `baz` references the `Self` type in its parameters or return type
|
||||
| ---- ...because method `baz` references the `Self` type in its return type
|
||||
...
|
||||
LL | fn make_baz<T:Baz>(t: &T) -> &dyn Baz {
|
||||
| ^^^^^^^^ the trait `Baz` cannot be made into an object
|
||||
|
@ -4,7 +4,7 @@ error[E0038]: the trait `Bar` cannot be made into an object
|
||||
LL | trait Bar {
|
||||
| --- this trait cannot be made into an object...
|
||||
LL | fn bar(&self, x: &Self);
|
||||
| --- ...because method `bar` references the `Self` type in its parameters or return type
|
||||
| ----- ...because method `bar` references the `Self` type in this parameter
|
||||
...
|
||||
LL | t
|
||||
| ^ the trait `Bar` cannot be made into an object
|
||||
@ -19,7 +19,7 @@ error[E0038]: the trait `Baz` cannot be made into an object
|
||||
LL | trait Baz {
|
||||
| --- this trait cannot be made into an object...
|
||||
LL | fn baz(&self) -> Self;
|
||||
| --- ...because method `baz` references the `Self` type in its parameters or return type
|
||||
| ---- ...because method `baz` references the `Self` type in its return type
|
||||
...
|
||||
LL | t
|
||||
| ^ the trait `Baz` cannot be made into an object
|
||||
|
@ -9,7 +9,10 @@ LL | fn foo() {}
|
||||
LL | fn diverges() -> Box<dyn Foo> {
|
||||
| ^^^^^^^^^^^^ the trait `Foo` cannot be made into an object
|
||||
|
|
||||
= help: consider turning `foo` into a method by giving it a `&self` argument or constraining it with `where Self: Sized`
|
||||
help: consider turning `foo` into a method by giving it a `&self` argument or constraining it so it does not apply to trait objects
|
||||
|
|
||||
LL | fn foo() where Self: Sized {}
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -9,9 +9,12 @@ LL | fn foo() {}
|
||||
LL | let b: Box<dyn Foo> = Box::new(Bar);
|
||||
| ^^^^^^^^^^^^^ the trait `Foo` cannot be made into an object
|
||||
|
|
||||
= help: consider turning `foo` into a method by giving it a `&self` argument or constraining it with `where Self: Sized`
|
||||
= note: required because of the requirements on the impl of `std::ops::CoerceUnsized<std::boxed::Box<dyn Foo>>` for `std::boxed::Box<Bar>`
|
||||
= note: required by cast to type `std::boxed::Box<dyn Foo>`
|
||||
help: consider turning `foo` into a method by giving it a `&self` argument or constraining it so it does not apply to trait objects
|
||||
|
|
||||
LL | fn foo() where Self: Sized {}
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -4,12 +4,13 @@ error[E0038]: the trait `Foo` cannot be made into an object
|
||||
LL | trait Foo {
|
||||
| --- this trait cannot be made into an object...
|
||||
LL | fn foo(self: &Rc<Self>) -> usize;
|
||||
| --- ...because method `foo`'s `self` parameter cannot be dispatched on
|
||||
| ---------
|
||||
| |
|
||||
| ...because method `foo`'s `self` parameter cannot be dispatched on
|
||||
| help: consider changing method `foo`'s `self` parameter to be `&self`: `&Self`
|
||||
...
|
||||
LL | let x = Rc::new(5usize) as Rc<dyn Foo>;
|
||||
| ^^^^^^^^^^^ the trait `Foo` cannot be made into an object
|
||||
|
|
||||
= help: consider changing method `foo`'s `self` parameter to be `&self`
|
||||
|
||||
error[E0038]: the trait `Foo` cannot be made into an object
|
||||
--> $DIR/arbitrary-self-types-not-object-safe.rs:33:13
|
||||
@ -17,12 +18,14 @@ error[E0038]: the trait `Foo` cannot be made into an object
|
||||
LL | trait Foo {
|
||||
| --- this trait cannot be made into an object...
|
||||
LL | fn foo(self: &Rc<Self>) -> usize;
|
||||
| --- ...because method `foo`'s `self` parameter cannot be dispatched on
|
||||
| ---------
|
||||
| |
|
||||
| ...because method `foo`'s `self` parameter cannot be dispatched on
|
||||
| help: consider changing method `foo`'s `self` parameter to be `&self`: `&Self`
|
||||
...
|
||||
LL | let x = Rc::new(5usize) as Rc<dyn Foo>;
|
||||
| ^^^^^^^^^^^^^^^ the trait `Foo` cannot be made into an object
|
||||
|
|
||||
= help: consider changing method `foo`'s `self` parameter to be `&self`
|
||||
= note: required because of the requirements on the impl of `std::ops::CoerceUnsized<std::rc::Rc<dyn Foo>>` for `std::rc::Rc<usize>`
|
||||
= note: required by cast to type `std::rc::Rc<dyn Foo>`
|
||||
|
||||
|
@ -4,12 +4,14 @@ error[E0038]: the trait `Foo` cannot be made into an object
|
||||
LL | trait Foo {
|
||||
| --- this trait cannot be made into an object...
|
||||
LL | fn foo(self: &Rc<Self>) -> usize;
|
||||
| --- ...because method `foo`'s `self` parameter cannot be dispatched on
|
||||
| ---------
|
||||
| |
|
||||
| ...because method `foo`'s `self` parameter cannot be dispatched on
|
||||
| help: consider changing method `foo`'s `self` parameter to be `&self`: `&Self`
|
||||
...
|
||||
LL | let x = Rc::new(5usize) as Rc<dyn Foo>;
|
||||
| ^^^^^^^^^^^^^^^ the trait `Foo` cannot be made into an object
|
||||
|
|
||||
= help: consider changing method `foo`'s `self` parameter to be `&self`
|
||||
= note: required because of the requirements on the impl of `std::ops::CoerceUnsized<std::rc::Rc<dyn Foo>>` for `std::rc::Rc<usize>`
|
||||
= note: required by cast to type `std::rc::Rc<dyn Foo>`
|
||||
|
||||
|
@ -44,7 +44,10 @@ LL | fn f(a: B) -> B;
|
||||
| |
|
||||
| ...because associated function `f` has no `self` parameter
|
||||
|
|
||||
= help: consider turning `f` into a method by giving it a `&self` argument or constraining it with `where Self: Sized`
|
||||
help: consider turning `f` into a method by giving it a `&self` argument or constraining it so it does not apply to trait objects
|
||||
|
|
||||
LL | fn f(a: B) -> B where Self: Sized;
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
|
@ -9,9 +9,12 @@ LL | fn foo();
|
||||
LL | let _: &dyn Tr = &St;
|
||||
| ^^^ the trait `Tr` cannot be made into an object
|
||||
|
|
||||
= help: consider turning `foo` into a method by giving it a `&self` argument or constraining it with `where Self: Sized`
|
||||
= note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Tr>` for `&St`
|
||||
= note: required by cast to type `&dyn Tr`
|
||||
help: consider turning `foo` into a method by giving it a `&self` argument or constraining it so it does not apply to trait objects
|
||||
|
|
||||
LL | fn foo() where Self: Sized;
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0038]: the trait `Tr` cannot be made into an object
|
||||
--> $DIR/trait-object-safety.rs:15:12
|
||||
@ -24,7 +27,10 @@ LL | fn foo();
|
||||
LL | let _: &dyn Tr = &St;
|
||||
| ^^^^^^^ the trait `Tr` cannot be made into an object
|
||||
|
|
||||
= help: consider turning `foo` into a method by giving it a `&self` argument or constraining it with `where Self: Sized`
|
||||
help: consider turning `foo` into a method by giving it a `&self` argument or constraining it so it does not apply to trait objects
|
||||
|
|
||||
LL | fn foo() where Self: Sized;
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -14,9 +14,9 @@ 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); }
|
||||
| --- --- ---- ...because method `blah` has generic type parameters
|
||||
| --- ---- ---- ...because method `blah` has generic type parameters
|
||||
| | |
|
||||
| | ...because method `dup` references the `Self` type in its parameters or return type
|
||||
| | ...because method `dup` references the `Self` type in its return type
|
||||
| this trait cannot be made into an object...
|
||||
...
|
||||
LL | (box 10 as Box<dyn bar>).dup();
|
||||
@ -29,9 +29,9 @@ 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); }
|
||||
| --- --- ---- ...because method `blah` has generic type parameters
|
||||
| --- ---- ---- ...because method `blah` has generic type parameters
|
||||
| | |
|
||||
| | ...because method `dup` references the `Self` type in its parameters or return type
|
||||
| | ...because method `dup` references the `Self` type in its return type
|
||||
| this trait cannot be made into an object...
|
||||
...
|
||||
LL | (box 10 as Box<dyn bar>).dup();
|
||||
|
@ -14,7 +14,7 @@ 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; }
|
||||
| ----- --- ...because method `add` references the `Self` type in its parameters or return type
|
||||
| ----- ---- ...because method `add` references the `Self` type in its return type
|
||||
| |
|
||||
| this trait cannot be made into an object...
|
||||
...
|
||||
|
@ -4,7 +4,7 @@ error[E0038]: the trait `A` cannot be made into an object
|
||||
LL | trait A {
|
||||
| - this trait cannot be made into an object...
|
||||
LL | fn foo(&self, _x: &Self);
|
||||
| --- ...because method `foo` references the `Self` type in its parameters or return type
|
||||
| ----- ...because method `foo` references the `Self` type in this parameter
|
||||
...
|
||||
LL | let _x: &dyn A;
|
||||
| ^^^^^^ the trait `A` cannot be made into an object
|
||||
|
Loading…
Reference in New Issue
Block a user