-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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 casting on numeric type error #47247
Conversation
(rust_highfive has picked a reviewer for you, use r? to override) |
Shouldn't we suggest to use |
More globally, I'm not sure talking about size fit/shortage is a good idea. Just talking about |
src/librustc_typeck/check/demand.rs
Outdated
&format!("{}, producing the closest possible value", | ||
msg), | ||
suggestion); | ||
err.warn("casting here will cause Undefined Behavior if the value is \ |
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.
Should "undefined behaviour" be capitalised like this? It doesn't seem to be typical in error messages.
I find the possibility of using the compiler errors to teach the language appealing. Presenting some of the possible trade offs inline like this seems like a great opportunity, even though completely I agree with the problems presented by
Part of what gave me pause is that
after:
That being said, the way I wrote the code was to make it possible to only show a subset of these suggestions depending on the case. I could suggest |
Updated the PR to only suggest |
That's problematic that |
@GuillaumeGomez in https://github.com/rust-lang/rust/pull/47247/files#diff-1743dc5c92f33d15fb1e903d7ad3ce58 (which is admittedly very verbose, as it has every single possible numeric type mismatch) you can see that the only suggestions provided are for the types that have a
|
src/librustc_typeck/check/demand.rs
Outdated
let can_cast = false; | ||
|
||
let needs_paren = match expr.node { | ||
hir::ExprBinary(..) => true, |
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.
I think you can reuse syntax::util::parser::expr_precedence
here and get more precise result.
See fn print_expr_method_call
in pprust.rs
for an example.
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.
Updated.
cast_suggestion); | ||
err.warn("casting here will cause undefined behavior if the value is \ | ||
finite but larger or smaller than the largest or smallest \ | ||
finite value representable by `f32` (this is a bug and will be \ |
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.
float <-> float conversions are buggy?
I don't think this is true. There's -Z saturating-float-casts
for correcting float -> int casts, but everything else is already correct, if I remember correctly.
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.
This warning is taken from https://doc.rust-lang.org/book/first-edition/casting-between-types.html#numeric-casts. Is it out of date?
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.
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.
The default behavior is indeed still UB, saturating casts are still opt-in.
src/librustc_typeck/check/demand.rs
Outdated
if exp.bit_width() > found.bit_width().unwrap_or(256) { | ||
err.span_suggestion(expr.span, | ||
&format!("{}, producing the floating point \ | ||
representation of the integer, rounded if \ |
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.
If into
is available, then the conversion will be lossless and no rounding will happen.
Also into
is not available for i/usize
and floats.
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.
Updated message.
The suggestion is not given for isize
/usize
(that's what the unwrap(256)
is doing). Added comment to that effect.
src/librustc_typeck/check/demand.rs
Outdated
if exp.bit_width() > found.bit_width().unwrap_or(256) { | ||
err.span_suggestion(expr.span, | ||
&format!("{}, producing the floating point \ | ||
representation of the integer, rounded if \ |
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.
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.
Done.
Looks pretty useful. |
85696b5
to
59cc9f7
Compare
src/librustc_typeck/check/demand.rs
Outdated
// For now, don't suggest casting with `as`. | ||
let can_cast = false; | ||
|
||
let needs_paren = expr_precedence(expr) < (AssocOp::As.precedence() as i8); |
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.
Argh, this expr_precedence
works on AST.
There's another one in rustc::hir::print
.
Also, AssocOp::As.precedence()
-> PREC_POSTFIX
.
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.
I'm gonna add a commit to merge both into one place (new enum that only holds the type to precedence mapping, and an into impl for {hir, ast}::Expr
so that there's only one source of truth for this. Started that yesterday but went to bed before I could complete it.
☔ The latest upstream changes (presumably #46461) made this pull request unmergeable. Please resolve the merge conflicts. |
- Use `syntax::util::parser::expr_precedence` to determine wether parenthesis are needed around the casting target. - Update message to not incorrectly mention rounding on `.into()` suggestions, as those types that do have that implemented will never round.
59cc9f7
to
27e9689
Compare
Introduce a new unified type that holds the expression precedence for both AST and HIR nodes.
27e9689
to
afe8d13
Compare
Fixed. |
src/libsyntax/ast.rs
Outdated
@@ -903,6 +917,129 @@ pub struct Expr { | |||
pub attrs: ThinVec<Attribute> | |||
} | |||
|
|||
#[derive(Debug, Clone, Copy, PartialEq, Eq)] | |||
pub enum ExprPrecedence { |
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.
Could you move all this stuff from ast.rs
somewhere, e.g. into util/parser.rs
where it was previously.
This is not a part of AST or HIR, really, it's a parsing-specific detail.
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.
Done. Waiting for the tests to run to make sure nothing broke.
@bors r+ |
📌 Commit 71c0873 has been approved by |
Suggest casting on numeric type error Re rust-lang#47168.
Re #47168.