Skip to content

Commit ced11a8

Browse files
committed
suggest MAX constant if -1 is assigned to unsigned type
1 parent a585aae commit ced11a8

File tree

4 files changed

+70
-1
lines changed

4 files changed

+70
-1
lines changed

compiler/rustc_typeck/src/check/op.rs

+25
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
33
use super::method::MethodCallee;
44
use super::FnCtxt;
5+
use rustc_ast as ast;
56
use rustc_errors::{self, struct_span_err, Applicability, DiagnosticBuilder};
67
use rustc_hir as hir;
78
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
@@ -13,6 +14,7 @@ use rustc_middle::ty::TyKind::{Adt, Array, Char, FnDef, Never, Ref, Str, Tuple,
1314
use rustc_middle::ty::{
1415
self, suggest_constraining_type_param, Ty, TyCtxt, TypeFoldable, TypeVisitor,
1516
};
17+
use rustc_span::source_map::Spanned;
1618
use rustc_span::symbol::{sym, Ident};
1719
use rustc_span::Span;
1820
use rustc_trait_selection::infer::InferCtxtExt;
@@ -673,6 +675,29 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
673675
match actual.kind() {
674676
Uint(_) if op == hir::UnOp::UnNeg => {
675677
err.note("unsigned values cannot be negated");
678+
679+
if let hir::ExprKind::Unary(
680+
_,
681+
hir::Expr {
682+
kind:
683+
hir::ExprKind::Lit(Spanned {
684+
node: ast::LitKind::Int(1, _),
685+
..
686+
}),
687+
..
688+
},
689+
) = ex.kind
690+
{
691+
err.span_suggestion(
692+
ex.span,
693+
&format!(
694+
"you may have meant the maximum value of `{}`",
695+
actual
696+
),
697+
format!("{}::MAX", actual),
698+
Applicability::MaybeIncorrect,
699+
);
700+
}
676701
}
677702
Str | Never | Char | Tuple(_) | Array(_, _) => {}
678703
Ref(_, ref lty, _) if *lty.kind() == Str => {}

src/test/ui/feature-gates/feature-gate-negate-unsigned.stderr

+4-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ error[E0600]: cannot apply unary operator `-` to type `usize`
22
--> $DIR/feature-gate-negate-unsigned.rs:10:23
33
|
44
LL | let _max: usize = -1;
5-
| ^^ cannot apply unary operator `-`
5+
| ^^
6+
| |
7+
| cannot apply unary operator `-`
8+
| help: you may have meant the maximum value of `usize`: `usize::MAX`
69
|
710
= note: unsigned values cannot be negated
811

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
fn main() {
2+
let x = -1 as usize; //~ ERROR: cannot apply unary operator `-`
3+
let x = (-1) as usize; //~ ERROR: cannot apply unary operator `-`
4+
let x: u32 = -1; //~ ERROR: cannot apply unary operator `-`
5+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
error[E0600]: cannot apply unary operator `-` to type `usize`
2+
--> $DIR/unsigned-literal-negation.rs:2:13
3+
|
4+
LL | let x = -1 as usize;
5+
| ^^
6+
| |
7+
| cannot apply unary operator `-`
8+
| help: you may have meant the maximum value of `usize`: `usize::MAX`
9+
|
10+
= note: unsigned values cannot be negated
11+
12+
error[E0600]: cannot apply unary operator `-` to type `usize`
13+
--> $DIR/unsigned-literal-negation.rs:3:13
14+
|
15+
LL | let x = (-1) as usize;
16+
| ^^^^
17+
| |
18+
| cannot apply unary operator `-`
19+
| help: you may have meant the maximum value of `usize`: `usize::MAX`
20+
|
21+
= note: unsigned values cannot be negated
22+
23+
error[E0600]: cannot apply unary operator `-` to type `u32`
24+
--> $DIR/unsigned-literal-negation.rs:4:18
25+
|
26+
LL | let x: u32 = -1;
27+
| ^^
28+
| |
29+
| cannot apply unary operator `-`
30+
| help: you may have meant the maximum value of `u32`: `u32::MAX`
31+
|
32+
= note: unsigned values cannot be negated
33+
34+
error: aborting due to 3 previous errors
35+
36+
For more information about this error, try `rustc --explain E0600`.

0 commit comments

Comments
 (0)