1
Fork 0

don't add redundant help for object safety violations

This commit is contained in:
Ryan Mehri 2023-10-26 08:20:49 -07:00
parent 4fd68eb47b
commit af6b84aaab
No known key found for this signature in database
GPG key ID: CEAFB62465F3A716
4 changed files with 75 additions and 35 deletions

View file

@ -843,50 +843,31 @@ impl ObjectSafetyViolation {
}
}
pub fn solution(&self, err: &mut Diagnostic) {
pub fn solution(&self) -> ObjectSafetyViolationSolution {
match self {
ObjectSafetyViolation::SizedSelf(_)
| ObjectSafetyViolation::SupertraitSelf(_)
| ObjectSafetyViolation::SupertraitNonLifetimeBinder(..) => {}
| ObjectSafetyViolation::SupertraitNonLifetimeBinder(..) => {
ObjectSafetyViolationSolution::None
}
ObjectSafetyViolation::Method(
name,
MethodViolationCode::StaticMethod(Some((add_self_sugg, make_sized_sugg))),
_,
) => {
err.span_suggestion(
add_self_sugg.1,
format!(
"consider turning `{name}` into a method by giving it a `&self` argument"
),
add_self_sugg.0.to_string(),
Applicability::MaybeIncorrect,
);
err.span_suggestion(
make_sized_sugg.1,
format!(
"alternatively, consider constraining `{name}` so it does not apply to \
trait objects"
),
make_sized_sugg.0.to_string(),
Applicability::MaybeIncorrect,
);
}
) => ObjectSafetyViolationSolution::AddSelfOrMakeSized {
name: *name,
add_self_sugg: add_self_sugg.clone(),
make_sized_sugg: make_sized_sugg.clone(),
},
ObjectSafetyViolation::Method(
name,
MethodViolationCode::UndispatchableReceiver(Some(span)),
_,
) => {
err.span_suggestion(
*span,
format!("consider changing method `{name}`'s `self` parameter to be `&self`"),
"&Self",
Applicability::MachineApplicable,
);
}
) => ObjectSafetyViolationSolution::ChangeToRefSelf(*name, *span),
ObjectSafetyViolation::AssocConst(name, _)
| ObjectSafetyViolation::GAT(name, _)
| ObjectSafetyViolation::Method(name, ..) => {
err.help(format!("consider moving `{name}` to another trait"));
ObjectSafetyViolationSolution::MoveToAnotherTrait(*name)
}
}
}
@ -910,6 +891,60 @@ impl ObjectSafetyViolation {
}
}
#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub enum ObjectSafetyViolationSolution {
None,
AddSelfOrMakeSized {
name: Symbol,
add_self_sugg: (String, Span),
make_sized_sugg: (String, Span),
},
ChangeToRefSelf(Symbol, Span),
MoveToAnotherTrait(Symbol),
}
impl ObjectSafetyViolationSolution {
pub fn add_to(self, err: &mut Diagnostic) {
match self {
ObjectSafetyViolationSolution::None => {}
ObjectSafetyViolationSolution::AddSelfOrMakeSized {
name,
add_self_sugg,
make_sized_sugg,
} => {
err.span_suggestion(
add_self_sugg.1,
format!(
"consider turning `{name}` into a method by giving it a `&self` argument"
),
add_self_sugg.0,
Applicability::MaybeIncorrect,
);
err.span_suggestion(
make_sized_sugg.1,
format!(
"alternatively, consider constraining `{name}` so it does not apply to \
trait objects"
),
make_sized_sugg.0,
Applicability::MaybeIncorrect,
);
}
ObjectSafetyViolationSolution::ChangeToRefSelf(name, span) => {
err.span_suggestion(
span,
format!("consider changing method `{name}`'s `self` parameter to be `&self`"),
"&Self",
Applicability::MachineApplicable,
);
}
ObjectSafetyViolationSolution::MoveToAnotherTrait(name) => {
err.help(format!("consider moving `{name}` to another trait"));
}
}
}
}
/// Reasons a method might not be object-safe.
#[derive(Clone, Debug, PartialEq, Eq, Hash, HashStable, PartialOrd, Ord)]
pub enum MethodViolationCode {