1
Fork 0

Tweak "object unsafe" errors

Fix #77598.
This commit is contained in:
Esteban Küber 2020-10-15 17:23:45 -07:00
parent 9832374f6e
commit ae0e3d0511
57 changed files with 720 additions and 442 deletions

View file

@ -13,6 +13,7 @@ use crate::mir::interpret::ErrorHandled;
use crate::ty::subst::SubstsRef;
use crate::ty::{self, AdtKind, Ty, TyCtxt};
use rustc_errors::{Applicability, DiagnosticBuilder};
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_span::symbol::Symbol;
@ -652,7 +653,7 @@ impl ObjectSafetyViolation {
.into()
}
}
ObjectSafetyViolation::Method(name, MethodViolationCode::StaticMethod(_), _) => {
ObjectSafetyViolation::Method(name, MethodViolationCode::StaticMethod(_, _, _), _) => {
format!("associated function `{}` has no `self` parameter", name).into()
}
ObjectSafetyViolation::Method(
@ -686,32 +687,65 @@ impl ObjectSafetyViolation {
}
}
pub fn solution(&self) -> Option<(String, Option<(String, Span)>)> {
Some(match *self {
ObjectSafetyViolation::SizedSelf(_) | ObjectSafetyViolation::SupertraitSelf(_) => {
return None;
pub fn solution(&self, err: &mut DiagnosticBuilder<'_>) {
match *self {
ObjectSafetyViolation::SizedSelf(_) | ObjectSafetyViolation::SupertraitSelf(_) => {}
ObjectSafetyViolation::Method(
name,
MethodViolationCode::StaticMethod(sugg, self_span, has_args),
_,
) => {
err.span_suggestion(
self_span,
&format!(
"consider turning `{}` into a method by giving it a `&self` argument",
name
),
format!("&self{}", if has_args { ", " } else { "" }),
Applicability::MaybeIncorrect,
);
match sugg {
Some((sugg, span)) => {
err.span_suggestion(
span,
&format!(
"alternatively, consider constraining `{}` so it does not apply to \
trait objects",
name
),
sugg.to_string(),
Applicability::MaybeIncorrect,
);
}
None => {
err.help(&format!(
"consider turning `{}` into a method by giving it a `&self` \
argument or constraining it so it does not apply to trait objects",
name
));
}
}
}
ObjectSafetyViolation::Method(name, MethodViolationCode::StaticMethod(sugg), _) => (
format!(
"consider turning `{}` into a method by giving it a `&self` argument or \
constraining it so it does not apply to trait objects",
name
),
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),
Some(("&Self".to_string(), span)),
),
) => {
err.span_suggestion(
span,
&format!(
"consider changing method `{}`'s `self` parameter to be `&self`",
name
),
"&Self".to_string(),
Applicability::MachineApplicable,
);
}
ObjectSafetyViolation::AssocConst(name, _)
| ObjectSafetyViolation::Method(name, ..) => {
(format!("consider moving `{}` to another trait", name), None)
err.help(&format!("consider moving `{}` to another trait", name));
}
})
}
}
pub fn spans(&self) -> SmallVec<[Span; 1]> {
@ -735,7 +769,7 @@ impl ObjectSafetyViolation {
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable)]
pub enum MethodViolationCode {
/// e.g., `fn foo()`
StaticMethod(Option<(&'static str, Span)>),
StaticMethod(Option<(&'static str, Span)>, Span, bool /* has args */),
/// e.g., `fn foo(&self, x: Self)`
ReferencesSelfInput(usize),