88// option. This file may not be copied, modified, or distributed
99// except according to those terms.
1010
11+ #![ allow( non_snake_case) ]
12+
1113use middle:: { infer} ;
1214use middle:: def_id:: DefId ;
1315use middle:: subst:: Substs ;
@@ -24,13 +26,19 @@ use std::{i8, i16, i32, i64, u8, u16, u32, u64, f32, f64};
2426use syntax:: { abi, ast} ;
2527use syntax:: attr:: { self , AttrMetaMethods } ;
2628use syntax:: codemap:: { self , Span } ;
27- use syntax:: feature_gate:: { emit_feature_err, GateIssue } ;
2829use syntax:: ast:: { TyIs , TyUs , TyI8 , TyU8 , TyI16 , TyU16 , TyI32 , TyU32 , TyI64 , TyU64 } ;
2930
3031use rustc_front:: hir;
3132use rustc_front:: intravisit:: { self , Visitor } ;
3233use rustc_front:: util:: is_shift_binop;
3334
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+
3442declare_lint ! {
3543 UNUSED_COMPARISONS ,
3644 Warn ,
@@ -73,30 +81,24 @@ impl LateLintPass for TypeLimits {
7381 fn check_expr ( & mut self , cx : & LateContext , e : & hir:: Expr ) {
7482 match e. node {
7583 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+ _ => ( )
9895 }
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+ }
100102 // propagate negation, if the negation itself isn't negated
101103 if self . negated_expr_id != e. id {
102104 self . negated_expr_id = expr. id ;
@@ -322,15 +324,10 @@ impl LateLintPass for TypeLimits {
322324 }
323325 }
324326
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" ) ;
334331 }
335332 }
336333}
0 commit comments