8
8
// option. This file may not be copied, modified, or distributed
9
9
// except according to those terms.
10
10
11
+ #![ allow( non_snake_case) ]
12
+
11
13
use middle:: { infer} ;
12
14
use middle:: def_id:: DefId ;
13
15
use middle:: subst:: Substs ;
@@ -24,13 +26,19 @@ use std::{i8, i16, i32, i64, u8, u16, u32, u64, f32, f64};
24
26
use syntax:: { abi, ast} ;
25
27
use syntax:: attr:: { self , AttrMetaMethods } ;
26
28
use syntax:: codemap:: { self , Span } ;
27
- use syntax:: feature_gate:: { emit_feature_err, GateIssue } ;
28
29
use syntax:: ast:: { TyIs , TyUs , TyI8 , TyU8 , TyI16 , TyU16 , TyI32 , TyU32 , TyI64 , TyU64 } ;
29
30
30
31
use rustc_front:: hir;
31
32
use rustc_front:: intravisit:: { self , Visitor } ;
32
33
use rustc_front:: util:: is_shift_binop;
33
34
35
+ register_long_diagnostics ! {
36
+ E0519 : r##"
37
+ It is not allowed to negate an unsigned integer.
38
+ You can negate a signed integer and cast it to an unsigned integer.
39
+ "##
40
+ }
41
+
34
42
declare_lint ! {
35
43
UNUSED_COMPARISONS ,
36
44
Warn ,
@@ -73,30 +81,24 @@ impl LateLintPass for TypeLimits {
73
81
fn check_expr ( & mut self , cx : & LateContext , e : & hir:: Expr ) {
74
82
match e. node {
75
83
hir:: ExprUnary ( hir:: UnNeg , ref expr) => {
76
- match expr. node {
77
- hir:: ExprLit ( ref lit) => {
78
- match lit. node {
79
- ast:: LitInt ( _, ast:: UnsignedIntLit ( _) ) => {
80
- check_unsigned_negation_feature ( cx, e. span ) ;
81
- } ,
82
- ast:: LitInt ( _, ast:: UnsuffixedIntLit ( _) ) => {
83
- if let ty:: TyUint ( _) = cx. tcx . node_id_to_type ( e. id ) . sty {
84
- check_unsigned_negation_feature ( cx, e. span ) ;
85
- }
86
- } ,
87
- _ => ( )
88
- }
89
- } ,
90
- _ => {
91
- let t = cx. tcx . node_id_to_type ( expr. id ) ;
92
- match t. sty {
93
- ty:: TyUint ( _) => {
94
- check_unsigned_negation_feature ( cx, e. span ) ;
95
- } ,
96
- _ => ( )
97
- }
84
+ if let hir:: ExprLit ( ref lit) = expr. node {
85
+ match lit. node {
86
+ ast:: LitInt ( _, ast:: UnsignedIntLit ( _) ) => {
87
+ forbid_unsigned_negation ( cx, e. span ) ;
88
+ } ,
89
+ ast:: LitInt ( _, ast:: UnsuffixedIntLit ( _) ) => {
90
+ if let ty:: TyUint ( _) = cx. tcx . node_id_to_type ( e. id ) . sty {
91
+ forbid_unsigned_negation ( cx, e. span ) ;
92
+ }
93
+ } ,
94
+ _ => ( )
98
95
}
99
- } ;
96
+ } else {
97
+ let t = cx. tcx . node_id_to_type ( expr. id ) ;
98
+ if let ty:: TyUint ( _) = t. sty {
99
+ forbid_unsigned_negation ( cx, e. span ) ;
100
+ }
101
+ }
100
102
// propagate negation, if the negation itself isn't negated
101
103
if self . negated_expr_id != e. id {
102
104
self . negated_expr_id = expr. id ;
@@ -322,15 +324,10 @@ impl LateLintPass for TypeLimits {
322
324
}
323
325
}
324
326
325
- fn check_unsigned_negation_feature ( cx : & LateContext , span : Span ) {
326
- if !cx. sess ( ) . features . borrow ( ) . negate_unsigned {
327
- emit_feature_err (
328
- & cx. sess ( ) . parse_sess . span_diagnostic ,
329
- "negate_unsigned" ,
330
- span,
331
- GateIssue :: Language ,
332
- "unary negation of unsigned integers may be removed in the future" ) ;
333
- }
327
+ fn forbid_unsigned_negation ( cx : & LateContext , span : Span ) {
328
+ span_err ! ( cx. sess( ) , span, E0519 ,
329
+ "unary negation of unsigned integer" ) ;
330
+ cx. sess ( ) . span_help ( span, "use a cast or the `!` operator" ) ;
334
331
}
335
332
}
336
333
}
0 commit comments