Skip to content

Commit

Permalink
suggest MAX constant if -1 is assigned to unsigned type
Browse files Browse the repository at this point in the history
  • Loading branch information
euclio committed Oct 8, 2020
1 parent a585aae commit ced11a8
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 1 deletion.
25 changes: 25 additions & 0 deletions compiler/rustc_typeck/src/check/op.rs
Expand Up @@ -2,6 +2,7 @@

use super::method::MethodCallee;
use super::FnCtxt;
use rustc_ast as ast;
use rustc_errors::{self, struct_span_err, Applicability, DiagnosticBuilder};
use rustc_hir as hir;
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
Expand All @@ -13,6 +14,7 @@ use rustc_middle::ty::TyKind::{Adt, Array, Char, FnDef, Never, Ref, Str, Tuple,
use rustc_middle::ty::{
self, suggest_constraining_type_param, Ty, TyCtxt, TypeFoldable, TypeVisitor,
};
use rustc_span::source_map::Spanned;
use rustc_span::symbol::{sym, Ident};
use rustc_span::Span;
use rustc_trait_selection::infer::InferCtxtExt;
Expand Down Expand Up @@ -673,6 +675,29 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
match actual.kind() {
Uint(_) if op == hir::UnOp::UnNeg => {
err.note("unsigned values cannot be negated");

if let hir::ExprKind::Unary(
_,
hir::Expr {
kind:
hir::ExprKind::Lit(Spanned {
node: ast::LitKind::Int(1, _),
..
}),
..
},
) = ex.kind
{
err.span_suggestion(
ex.span,
&format!(
"you may have meant the maximum value of `{}`",
actual
),
format!("{}::MAX", actual),
Applicability::MaybeIncorrect,
);
}
}
Str | Never | Char | Tuple(_) | Array(_, _) => {}
Ref(_, ref lty, _) if *lty.kind() == Str => {}
Expand Down
Expand Up @@ -2,7 +2,10 @@ error[E0600]: cannot apply unary operator `-` to type `usize`
--> $DIR/feature-gate-negate-unsigned.rs:10:23
|
LL | let _max: usize = -1;
| ^^ cannot apply unary operator `-`
| ^^
| |
| cannot apply unary operator `-`
| help: you may have meant the maximum value of `usize`: `usize::MAX`
|
= note: unsigned values cannot be negated

Expand Down
5 changes: 5 additions & 0 deletions src/test/ui/unsigned-literal-negation.rs
@@ -0,0 +1,5 @@
fn main() {
let x = -1 as usize; //~ ERROR: cannot apply unary operator `-`
let x = (-1) as usize; //~ ERROR: cannot apply unary operator `-`
let x: u32 = -1; //~ ERROR: cannot apply unary operator `-`
}
36 changes: 36 additions & 0 deletions src/test/ui/unsigned-literal-negation.stderr
@@ -0,0 +1,36 @@
error[E0600]: cannot apply unary operator `-` to type `usize`
--> $DIR/unsigned-literal-negation.rs:2:13
|
LL | let x = -1 as usize;
| ^^
| |
| cannot apply unary operator `-`
| help: you may have meant the maximum value of `usize`: `usize::MAX`
|
= note: unsigned values cannot be negated

error[E0600]: cannot apply unary operator `-` to type `usize`
--> $DIR/unsigned-literal-negation.rs:3:13
|
LL | let x = (-1) as usize;
| ^^^^
| |
| cannot apply unary operator `-`
| help: you may have meant the maximum value of `usize`: `usize::MAX`
|
= note: unsigned values cannot be negated

error[E0600]: cannot apply unary operator `-` to type `u32`
--> $DIR/unsigned-literal-negation.rs:4:18
|
LL | let x: u32 = -1;
| ^^
| |
| cannot apply unary operator `-`
| help: you may have meant the maximum value of `u32`: `u32::MAX`
|
= note: unsigned values cannot be negated

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0600`.

0 comments on commit ced11a8

Please sign in to comment.