Skip to content

Commit 6be2bc8

Browse files
committed
Add lint for unnecessary casts
1 parent 1d9e66c commit 6be2bc8

File tree

2 files changed

+68
-1
lines changed

2 files changed

+68
-1
lines changed

src/librustc/middle/lint.rs

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ use middle::typeck;
4141
use middle::pat_util;
4242
use metadata::csearch;
4343
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};
4448

4549
use std::cmp;
4650
use 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

573615
fn 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
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#[forbid(unnecessary_typecast)];
12+
13+
fn foo_i32(_: i32) {}
14+
15+
fn foo_u64(a: u64) {
16+
let b: i32 = a as i32;
17+
foo_i32(b as i32); //~ ERROR: unnecessary type cast
18+
}
19+
20+
fn main() {
21+
let x: u64 = 1;
22+
let y: u64 = x as u64; //~ ERROR: unnecessary type cast
23+
foo_u64(y as u64); //~ ERROR: unnecessary type cast
24+
}

0 commit comments

Comments
 (0)