@@ -41,6 +41,10 @@ use middle::typeck;
41
41
use middle:: pat_util;
42
42
use metadata:: csearch;
43
43
use util:: ppaux:: { ty_to_str} ;
44
+ use std:: to_str:: ToStr ;
45
+
46
+ use middle:: typeck:: infer;
47
+ use middle:: typeck:: astconv:: { ast_ty_to_ty, AstConv } ;
44
48
45
49
use std:: cmp;
46
50
use std:: hashmap:: HashMap ;
@@ -91,6 +95,7 @@ pub enum lint {
91
95
unused_mut,
92
96
unnecessary_allocation,
93
97
dead_code,
98
+ unnecessary_typecast,
94
99
95
100
missing_doc,
96
101
unreachable_code,
@@ -267,6 +272,13 @@ static lint_table: &'static [(&'static str, LintSpec)] = &[
267
272
default : warn
268
273
} ) ,
269
274
275
+ ( "unnecessary_typecast" ,
276
+ LintSpec {
277
+ lint : unnecessary_typecast,
278
+ desc : "detects unnecessary type casts, that can be removed" ,
279
+ default : allow,
280
+ } ) ,
281
+
270
282
( "unused_mut" ,
271
283
LintSpec {
272
284
lint : unused_mut,
@@ -336,7 +348,6 @@ static lint_table: &'static [(&'static str, LintSpec)] = &[
336
348
desc : "unknown features found in crate-level #[feature] directives" ,
337
349
default : deny,
338
350
} ) ,
339
-
340
351
( "unknown_crate_type" ,
341
352
LintSpec {
342
353
lint : unknown_crate_type,
@@ -569,6 +580,37 @@ fn check_while_true_expr(cx: &Context, e: &ast::Expr) {
569
580
_ => ( )
570
581
}
571
582
}
583
+ impl < ' a > AstConv for Context < ' a > {
584
+ fn tcx ( & self ) -> ty:: ctxt { self . tcx }
585
+
586
+ fn get_item_ty ( & self , id : ast:: DefId ) -> ty:: ty_param_bounds_and_ty {
587
+ ty:: lookup_item_type ( self . tcx , id)
588
+ }
589
+
590
+ fn get_trait_def ( & self , id : ast:: DefId ) -> @ty:: TraitDef {
591
+ ty:: lookup_trait_def ( self . tcx , id)
592
+ }
593
+
594
+ fn ty_infer ( & self , _span : Span ) -> ty:: t {
595
+ let infcx: @infer:: InferCtxt = infer:: new_infer_ctxt ( self . tcx ) ;
596
+ infcx. next_ty_var ( )
597
+ }
598
+ }
599
+
600
+
601
+ fn check_unused_casts ( cx : & Context , e : & ast:: Expr ) {
602
+ return match e. node {
603
+ ast:: ExprCast ( expr, ty) => {
604
+ let infcx: @infer:: InferCtxt = infer:: new_infer_ctxt ( cx. tcx ) ;
605
+ let t_t = ast_ty_to_ty ( cx, & infcx, ty) ;
606
+ if ty:: get ( ty:: expr_ty ( cx. tcx , expr) ) . sty == ty:: get ( t_t) . sty {
607
+ cx. span_lint ( unnecessary_typecast, ty. span ,
608
+ "unnecessary type cast" ) ;
609
+ }
610
+ }
611
+ _ => ( )
612
+ } ;
613
+ }
572
614
573
615
fn check_type_limits ( cx : & Context , e : & ast:: Expr ) {
574
616
return match e. node {
@@ -1361,6 +1403,7 @@ impl<'a> Visitor<()> for Context<'a> {
1361
1403
check_heap_expr ( self , e) ;
1362
1404
1363
1405
check_type_limits ( self , e) ;
1406
+ check_unused_casts ( self , e) ;
1364
1407
1365
1408
visit:: walk_expr ( self , e, ( ) ) ;
1366
1409
}
0 commit comments