@@ -41,6 +41,10 @@ use middle::typeck;
4141use middle:: pat_util;
4242use metadata:: csearch;
4343use 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 } ;
4448
4549use std:: cmp;
4650use std:: hashmap:: HashMap ;
@@ -91,6 +95,7 @@ pub enum lint {
9195 unused_mut,
9296 unnecessary_allocation,
9397 dead_code,
98+ unnecessary_typecast,
9499
95100 missing_doc,
96101 unreachable_code,
@@ -267,6 +272,13 @@ static lint_table: &'static [(&'static str, LintSpec)] = &[
267272 default : warn
268273 } ) ,
269274
275+ ( "unnecessary_typecast" ,
276+ LintSpec {
277+ lint : unnecessary_typecast,
278+ desc : "detects unnecessary type casts, that can be removed" ,
279+ default : allow,
280+ } ) ,
281+
270282 ( "unused_mut" ,
271283 LintSpec {
272284 lint : unused_mut,
@@ -336,7 +348,6 @@ static lint_table: &'static [(&'static str, LintSpec)] = &[
336348 desc : "unknown features found in crate-level #[feature] directives" ,
337349 default : deny,
338350 } ) ,
339-
340351 ( "unknown_crate_type" ,
341352 LintSpec {
342353 lint : unknown_crate_type,
@@ -569,6 +580,37 @@ fn check_while_true_expr(cx: &Context, e: &ast::Expr) {
569580 _ => ( )
570581 }
571582}
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+ }
572614
573615fn check_type_limits ( cx : & Context , e : & ast:: Expr ) {
574616 return match e. node {
@@ -1361,6 +1403,7 @@ impl<'a> Visitor<()> for Context<'a> {
13611403 check_heap_expr ( self , e) ;
13621404
13631405 check_type_limits ( self , e) ;
1406+ check_unused_casts ( self , e) ;
13641407
13651408 visit:: walk_expr ( self , e, ( ) ) ;
13661409 }
0 commit comments