-
Notifications
You must be signed in to change notification settings - Fork 13.3k
More accurate error for binop errors after identifying RHS type #90006
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Closed
Closed
Changes from all commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
9d8fb13
Evaluate binops a second time with resolved rhs type for suggestions
estebank dc7785c
Add FIXME comment for follow up work
estebank 2f499dd
Suggest replacement of existing bound instead of further contraining
estebank 2e6cab8
Fix output formatting for numeric cast
estebank 86aeb23
More accurate tracking of cast suggestions
estebank 56b12d7
Remove useless comment
estebank bee8752
Tweak output
estebank 1e48ab4
Remove mutable bindings
estebank 5b0c7f6
Account for "int to float suffix" to include `.0` in the suggestion
estebank 7110131
Add a new inference context once we have the rhs ty
estebank c8506a8
Move tests to `binops` subdirectory
estebank e938489
Use `span_suggestion_verbose` for uncalled functions
estebank 777e477
Remove duplicated errors
estebank 4797ad9
Fix formatting of comment
estebank File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -844,6 +844,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { | |||||
let mut into_suggestion = sugg.clone(); | ||||||
into_suggestion.push((expr.span.shrink_to_hi(), format!("{}.into()", close_paren))); | ||||||
let mut suffix_suggestion = sugg.clone(); | ||||||
|
||||||
if matches!( | ||||||
(&expected_ty.kind(), &checked_ty.kind()), | ||||||
(ty::Float(_), ty::Int(_) | ty::Uint(_)) | ||||||
) { | ||||||
// Add fractional part from literal, for example `42.0f32` into `42` | ||||||
estebank marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
let len = src.trim_end_matches(&checked_ty.to_string()).len(); | ||||||
let len = src[..len].trim_end_matches("_").len(); | ||||||
let pos = expr.span.lo() + BytePos(len as u32); | ||||||
let span = expr.span.with_lo(pos).with_hi(pos); | ||||||
suffix_suggestion.push((span, ".0".to_string())); | ||||||
}; | ||||||
|
||||||
suffix_suggestion.push(( | ||||||
if matches!( | ||||||
(&expected_ty.kind(), &checked_ty.kind()), | ||||||
|
@@ -915,19 +928,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { | |||||
suggestion, | ||||||
Applicability::MachineApplicable, | ||||||
); | ||||||
true | ||||||
}; | ||||||
|
||||||
let suggest_to_change_suffix_or_into = | ||||||
|err: &mut DiagnosticBuilder<'_>, | ||||||
found_to_exp_is_fallible: bool, | ||||||
exp_to_found_is_fallible: bool| { | ||||||
let exp_is_lhs = | ||||||
let exp_is_assign_lhs = | ||||||
expected_ty_expr.map(|e| self.tcx.hir().is_lhs(e.hir_id)).unwrap_or(false); | ||||||
|
||||||
if exp_is_lhs { | ||||||
return; | ||||||
if exp_is_assign_lhs { | ||||||
return false; | ||||||
} | ||||||
|
||||||
let always_fallible = found_to_exp_is_fallible | ||||||
&& (exp_to_found_is_fallible || expected_ty_expr.is_none()); | ||||||
let msg = if literal_is_ty_suffixed(expr) { | ||||||
|
@@ -938,10 +951,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { | |||||
// expected type. | ||||||
let msg = format!("`{}` cannot fit into type `{}`", src, expected_ty); | ||||||
err.note(&msg); | ||||||
return; | ||||||
return false; | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you add a comment to |
||||||
} else if in_const_context { | ||||||
// Do not recommend `into` or `try_into` in const contexts. | ||||||
return; | ||||||
return false; | ||||||
} else if found_to_exp_is_fallible { | ||||||
return suggest_fallible_into_or_lhs_from(err, exp_to_found_is_fallible); | ||||||
} else { | ||||||
|
@@ -953,6 +966,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { | |||||
into_suggestion.clone() | ||||||
}; | ||||||
err.multipart_suggestion_verbose(msg, suggestion, Applicability::MachineApplicable); | ||||||
true | ||||||
}; | ||||||
|
||||||
match (&expected_ty.kind(), &checked_ty.kind()) { | ||||||
|
@@ -966,8 +980,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { | |||||
(None, _) | (_, None) => (true, true), | ||||||
_ => (false, false), | ||||||
}; | ||||||
suggest_to_change_suffix_or_into(err, f2e_is_fallible, e2f_is_fallible); | ||||||
true | ||||||
suggest_to_change_suffix_or_into(err, f2e_is_fallible, e2f_is_fallible) | ||||||
} | ||||||
(&ty::Uint(ref exp), &ty::Uint(ref found)) => { | ||||||
let (f2e_is_fallible, e2f_is_fallible) = match (exp.bit_width(), found.bit_width()) | ||||||
|
@@ -979,8 +992,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { | |||||
(None, _) | (_, None) => (true, true), | ||||||
_ => (false, false), | ||||||
}; | ||||||
suggest_to_change_suffix_or_into(err, f2e_is_fallible, e2f_is_fallible); | ||||||
true | ||||||
suggest_to_change_suffix_or_into(err, f2e_is_fallible, e2f_is_fallible) | ||||||
} | ||||||
(&ty::Int(exp), &ty::Uint(found)) => { | ||||||
let (f2e_is_fallible, e2f_is_fallible) = match (exp.bit_width(), found.bit_width()) | ||||||
|
@@ -989,8 +1001,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { | |||||
(None, Some(8)) => (false, true), | ||||||
_ => (true, true), | ||||||
}; | ||||||
suggest_to_change_suffix_or_into(err, f2e_is_fallible, e2f_is_fallible); | ||||||
true | ||||||
suggest_to_change_suffix_or_into(err, f2e_is_fallible, e2f_is_fallible) | ||||||
} | ||||||
(&ty::Uint(exp), &ty::Int(found)) => { | ||||||
let (f2e_is_fallible, e2f_is_fallible) = match (exp.bit_width(), found.bit_width()) | ||||||
|
@@ -999,12 +1010,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { | |||||
(Some(8), None) => (true, false), | ||||||
_ => (true, true), | ||||||
}; | ||||||
suggest_to_change_suffix_or_into(err, f2e_is_fallible, e2f_is_fallible); | ||||||
true | ||||||
suggest_to_change_suffix_or_into(err, f2e_is_fallible, e2f_is_fallible) | ||||||
} | ||||||
(&ty::Float(ref exp), &ty::Float(ref found)) => { | ||||||
if found.bit_width() < exp.bit_width() { | ||||||
suggest_to_change_suffix_or_into(err, false, true); | ||||||
return suggest_to_change_suffix_or_into(err, false, true); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
? |
||||||
} else if literal_is_ty_suffixed(expr) { | ||||||
err.multipart_suggestion_verbose( | ||||||
&lit_msg, | ||||||
|
@@ -1028,15 +1038,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { | |||||
suffix_suggestion, | ||||||
Applicability::MachineApplicable, | ||||||
); | ||||||
true | ||||||
} else if can_cast { | ||||||
// Missing try_into implementation for `{float}` to `{integer}` | ||||||
err.multipart_suggestion_verbose( | ||||||
&format!("{}, rounding the float towards zero", msg), | ||||||
cast_suggestion, | ||||||
Applicability::MaybeIncorrect, // lossy conversion | ||||||
); | ||||||
true | ||||||
} else { | ||||||
false | ||||||
} | ||||||
true | ||||||
} | ||||||
(&ty::Float(ref exp), &ty::Uint(ref found)) => { | ||||||
// if `found` is `None` (meaning found is `usize`), don't suggest `.into()` | ||||||
|
@@ -1059,8 +1072,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { | |||||
// Missing try_into implementation for `{integer}` to `{float}` | ||||||
err.multipart_suggestion_verbose( | ||||||
&format!( | ||||||
"{}, producing the floating point representation of the integer, | ||||||
rounded if necessary", | ||||||
"{}, producing the floating point representation of the integer, \ | ||||||
rounded if necessary", | ||||||
cast_msg, | ||||||
), | ||||||
cast_suggestion, | ||||||
|
@@ -1091,7 +1104,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { | |||||
err.multipart_suggestion_verbose( | ||||||
&format!( | ||||||
"{}, producing the floating point representation of the integer, \ | ||||||
rounded if necessary", | ||||||
rounded if necessary", | ||||||
&msg, | ||||||
), | ||||||
cast_suggestion, | ||||||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
T: Trait<OneType> + Trait<AnotherType>
is a legitimate combination of bounds, so with filtering based on def-ids the suggestions will perpetually recommend replacingTrait<OneType>
withTrait<AnotherType>
and vice versa in case of one of the bounds missing.