Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Suggest type for overflowing bin/hex-literals #48432

Merged
merged 6 commits into from
Mar 6, 2018

Conversation

flip1995
Copy link
Member

Fixes #48073

For hexadecimal and binary literals, which overflow, it gives an additional note to the warning message, like in this comment.

Additionally it will suggest a type (X < Y):

  • iX: if literal fits in uX => uX, else => iY
  • -iX => iY
  • uX => uY

Exceptions: isize, usize. I don't think you can make a good suggestion here. The programmer has to figure it out on it's own in this case.

r? @oli-obk

@rust-highfive
Copy link
Collaborator

Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @oli-obk (or someone else) soon.

If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes.

Please see the contribution instructions for more information.

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Feb 22, 2018
Copy link
Contributor

@oli-obk oli-obk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The final error message output looks good to me

if bits < 128 {
// v & 0b0..01..1, |1| = bits
let trimmed = v & ((1 << bits) - 1);
actually = if v & (1 << (bits - 1)) == 0 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can simplify these conversions by first casting to i128 and then bitshifting by 128 - bits to the left and then to the right.

ast::FloatTy::F64 => v.as_str().parse().map(f64::is_infinite),
}
}
ast::LitKind::Float(v, _) | ast::LitKind::FloatUnsuffixed(v) => match t
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unrelated formatting change

cx.span_lint(OVERFLOWING_LITERALS,
e.span,
&format!("literal out of range for {:?}", t));
cx.span_lint(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unrelated formatting change

@@ -340,6 +421,69 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits {
_ => false,
}
}

fn get_bin_hex_repr(cx: &LateContext, lit: &ast::Lit) -> Option<String> {
if let Some(src) = cx.sess().codemap().span_to_snippet(lit.span).ok() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can rewrite this entire function with the ? operator instead of if let

err.emit();
return;
}
cx.span_lint(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It feels like there's a lot of duplication between the error reporting of signed and unsigned integers. Is it possible to merge them into a function?

Copy link
Member Author

@flip1995 flip1995 Feb 22, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think changing the function get_fitting_type(), that it returns the suggestion string directly is the best approach here.
An extra function for the err.note() part is hard, because we need the actually value as i128 in the singed case and as u128 in the unsigned case. Same problem with the Type.

Edit: Actually, I will rewrite the error reporting while adding the span suggestion @estebank requested.

($ty:expr, $val:expr, $negative:expr,
$($type:ident => [$($utypes:expr),*] => [$($itypes:expr),*]),+) => {
{
let _neg = if negative { 1 } else { 0 };
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: preceding underscores suppress dead code warnings, so I'd avoid them if that is not intended.

Also the PR has a succint description for what this function does, which you could copy into a comment.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The underscore is intended: for finding a fitting unsigned type, we don't look at integer types so the expanded macro never uses _neg in this case. So the line

if let &ty::TyUint(u) = t {
    return find_fit!(u, val, negative
...}

gives a warning. If there is a better way to do this, it would be nice to know :)

And yeah maybe I should have wrote a few more comments. Will do this, while implementing the other suggestions

Copy link
Contributor

@estebank estebank left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great!

Could you address @oli-obk's and my comments?

// - `uX` => `uY`
//
// No suggestion for: `isize`, `usize`.
fn get_type_suggestion<'a>(t: &ty::TypeVariants, val: u128, negative: bool) -> String {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could get_type_suggestion return an Option<String> instead? That way you communicate intent that the empty String doesn't.

match $ty {
$($type => {
$(if !negative && val <= uint_ty_range($utypes).1 {
return format!("Consider using `{:?}`", $utypes)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use leading lowercase here and below

"consider using {:?} instead"

false,
);
if !sugg_ty.is_empty() {
err.help(&sugg_ty);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It'd be nice if this were a span_suggestion instead if it is a numeric literal that sets the type, otherwise provide the help (ideally I would check the source of the type constraint and point at it, but it is not necessary to go down that rabbit hole in this PR):

warning: literal out of range for i8
  --> $DIR/type-overflow.rs:34:17
   |
34 |     let fail = -0b1111_1111i8;
   |                 ^^^^^^^^^^^^^ help: consider using `i16` instead: `-0b1111_1111i16`
   |
   = note: the literal `0b1111_1111i8` (decimal `255`) does not fit into an `i8` and will become `-1i8`

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks better. I will add this, this evening.

);
err.note(&format!(
"the literal `{}` (decimal `{}`) does not fit into \
an `{:?}` and will become `{}{:?}`.",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove trailing .

34 | let fail = -0b1111_1111i8; //~WARNING literal out of range for i8
| ^^^^^^^^^^^^^ help: consider using `i16` instead: `0b1111_1111i16`
|
= note: the literal `0b1111_1111i8` (decimal `255`) does not fit into an `i8` and will become `-1i8`
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The note says that the literal will become -1i8 (which is technically correct), while fail will have the value 1i8 due to the negation. That is, because I ignore whether the literal is negated in the generation of the note.

I'm not sure if I should change this because it is correct for the given span.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that this is fine for now. Filed #48535 to follow up.

@estebank
Copy link
Contributor

@bors r+

@bors
Copy link
Contributor

bors commented Feb 25, 2018

📌 Commit de7d375 has been approved by estebank

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Feb 25, 2018
@estebank
Copy link
Contributor

@bors rollup

@estebank
Copy link
Contributor

estebank commented Feb 28, 2018

@bors r-

@flip1995 you'll have to rebase and fix the ui test output to replace the line numbers in he margins with LL because of #48449.

@bors bors added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Feb 28, 2018
@flip1995
Copy link
Member Author

Whoops. I failed hard on the rebase. Sorry... :(
Should I open a new PR for this?

@estebank
Copy link
Contributor

estebank commented Mar 1, 2018

If you can fix the rebase, just do a git push --force.

@flip1995
Copy link
Member Author

flip1995 commented Mar 1, 2018

Fixed it somehow. That should be good now.

@estebank
Copy link
Contributor

estebank commented Mar 1, 2018

@bors r+ rollup

@bors
Copy link
Contributor

bors commented Mar 1, 2018

📌 Commit f45f760 has been approved by estebank

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Mar 1, 2018
@bors bors added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Mar 1, 2018
@estebank
Copy link
Contributor

estebank commented Mar 1, 2018

Completely missed this pitfall, @Manishearth.

@flip1995, don't test the i/u size cases, as they're platform dependent and are prone to work locally and in travis, but break in the full run on all targets.

@flip1995
Copy link
Member Author

flip1995 commented Mar 2, 2018

Should I rebase again?

Copy link
Contributor

@oli-obk oli-obk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to rebase if Travis passes

let src = cx.sess().codemap().span_to_snippet(lit.span).ok()?;
let firstch = src.chars().next()?;

if let Some(0) = char::to_digit(firstch, 10) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why don't you just check firstch == '0'?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

r=me after @oli-obk's comment is addressed. Sorry for the back and forth, @flip1995, I didn't catch this.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't know why I made this so complicated.

No problem. I'm happy for the great support on my first PR to the rust compiler! :)

@flip1995
Copy link
Member Author

flip1995 commented Mar 3, 2018

r? @estebank

@rust-highfive rust-highfive assigned estebank and unassigned oli-obk Mar 3, 2018
@oli-obk
Copy link
Contributor

oli-obk commented Mar 4, 2018

@bors r+

@bors
Copy link
Contributor

bors commented Mar 4, 2018

📌 Commit fc33b25 has been approved by oli-obk

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Mar 4, 2018
Manishearth added a commit to Manishearth/rust that referenced this pull request Mar 5, 2018
Suggest type for overflowing bin/hex-literals

Fixes rust-lang#48073

For hexadecimal and binary literals, which overflow, it gives an additional note to the warning message, like in this [comment](rust-lang#48073 (comment)).

Additionally it will suggest a type (`X < Y`):
- `iX`: if literal fits in `uX` => `uX`, else => `iY`
- `-iX` => `iY`
- `uX` => `uY`

Exceptions: `isize`, `usize`. I don't think you can make a good suggestion here. The programmer has to figure it out on it's own in this case.

r? @oli-obk
kennytm added a commit to kennytm/rust that referenced this pull request Mar 6, 2018
Suggest type for overflowing bin/hex-literals

Fixes rust-lang#48073

For hexadecimal and binary literals, which overflow, it gives an additional note to the warning message, like in this [comment](rust-lang#48073 (comment)).

Additionally it will suggest a type (`X < Y`):
- `iX`: if literal fits in `uX` => `uX`, else => `iY`
- `-iX` => `iY`
- `uX` => `uY`

Exceptions: `isize`, `usize`. I don't think you can make a good suggestion here. The programmer has to figure it out on it's own in this case.

r? @oli-obk
GuillaumeGomez added a commit to GuillaumeGomez/rust that referenced this pull request Mar 6, 2018
Suggest type for overflowing bin/hex-literals

Fixes rust-lang#48073

For hexadecimal and binary literals, which overflow, it gives an additional note to the warning message, like in this [comment](rust-lang#48073 (comment)).

Additionally it will suggest a type (`X < Y`):
- `iX`: if literal fits in `uX` => `uX`, else => `iY`
- `-iX` => `iY`
- `uX` => `uY`

Exceptions: `isize`, `usize`. I don't think you can make a good suggestion here. The programmer has to figure it out on it's own in this case.

r? @oli-obk
GuillaumeGomez added a commit to GuillaumeGomez/rust that referenced this pull request Mar 6, 2018
Suggest type for overflowing bin/hex-literals

Fixes rust-lang#48073

For hexadecimal and binary literals, which overflow, it gives an additional note to the warning message, like in this [comment](rust-lang#48073 (comment)).

Additionally it will suggest a type (`X < Y`):
- `iX`: if literal fits in `uX` => `uX`, else => `iY`
- `-iX` => `iY`
- `uX` => `uY`

Exceptions: `isize`, `usize`. I don't think you can make a good suggestion here. The programmer has to figure it out on it's own in this case.

r? @oli-obk
bors added a commit that referenced this pull request Mar 6, 2018
Rollup of 14 pull requests

- Successful merges: #48403, #48432, #48546, #48573, #48590, #48657, #48727, #48732, #48753, #48754, #48761, #48474, #48507, #47463
- Failed merges:
@alexcrichton alexcrichton merged commit fc33b25 into rust-lang:master Mar 6, 2018
@flip1995 flip1995 deleted the lit_diag branch May 6, 2018 13:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants