1
Fork 0

suggest a float literal when dividing a floating-point type by {integer}

fix a message

implement a rustfix-applicable suggestion

implement `suggest_floating_point_literal`

add `ObligationCauseCode::BinOp`

remove duplicate code

fix function names in uitests

use `Diagnostic` instead of `DiagnosticBuilder`
This commit is contained in:
Takayuki Maeda 2022-02-17 19:33:32 +09:00
parent 12b71ed4c5
commit c60bae78ac
12 changed files with 543 additions and 18 deletions

View file

@ -501,6 +501,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
err.span_label(enclosing_scope_span, s.as_str());
}
self.suggest_floating_point_literal(&obligation, &mut err, &trait_ref);
self.suggest_dereferences(&obligation, &mut err, trait_predicate);
self.suggest_fn_call(&obligation, &mut err, trait_predicate);
self.suggest_remove_reference(&obligation, &mut err, trait_predicate);

View file

@ -174,6 +174,13 @@ pub trait InferCtxtExt<'tcx> {
trait_pred: ty::PolyTraitPredicate<'tcx>,
span: Span,
);
fn suggest_floating_point_literal(
&self,
obligation: &PredicateObligation<'tcx>,
err: &mut Diagnostic,
trait_ref: &ty::PolyTraitRef<'tcx>,
);
}
fn predicate_constraint(generics: &hir::Generics<'_>, pred: String) -> (Span, String) {
@ -1910,8 +1917,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
| ObligationCauseCode::AwaitableExpr(_)
| ObligationCauseCode::ForLoopIterator
| ObligationCauseCode::QuestionMark
| ObligationCauseCode::CheckAssociatedTypeBounds { .. }
| ObligationCauseCode::LetElse
| ObligationCauseCode::CheckAssociatedTypeBounds { .. } => {}
| ObligationCauseCode::BinOp { .. } => {}
ObligationCauseCode::SliceOrArrayElem => {
err.note("slice and array elements must have `Sized` type");
}
@ -2497,6 +2505,32 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
}
}
}
fn suggest_floating_point_literal(
&self,
obligation: &PredicateObligation<'tcx>,
err: &mut Diagnostic,
trait_ref: &ty::PolyTraitRef<'tcx>,
) {
let rhs_span = match obligation.cause.code() {
ObligationCauseCode::BinOp { rhs_span: Some(span), is_lit } if *is_lit => span,
_ => return,
};
match (
trait_ref.skip_binder().self_ty().kind(),
trait_ref.skip_binder().substs.type_at(1).kind(),
) {
(ty::Float(_), ty::Infer(InferTy::IntVar(_))) => {
err.span_suggestion_verbose(
rhs_span.shrink_to_hi(),
"consider using a floating-point literal by writing it with `.0`",
String::from(".0"),
Applicability::MaybeIncorrect,
);
}
_ => {}
}
}
}
/// Collect all the returned expressions within the input expression.