mut_mut now more robust (thanks to Manishearth, see issue #9)

This commit is contained in:
llogiq 2015-05-18 10:41:15 +02:00
parent 96bfade4f1
commit 1f8453ab73
2 changed files with 29 additions and 19 deletions

View File

@ -1,11 +1,7 @@
use syntax::ptr::P;
use syntax::ast;
use syntax::ast::*;
use syntax::ast_util::{is_comparison_binop, binop_to_string};
use syntax::visit::{FnKind};
use rustc::lint::{Context, LintPass, LintArray, Lint, Level};
use rustc::middle::ty::{self, expr_ty, ty_str, ty_ptr, ty_rptr, ty_float};
use syntax::codemap::{Span, Spanned};
use rustc::lint::{Context, LintPass, LintArray, Lint};
use rustc::middle::ty::{expr_ty, sty, ty_ptr, ty_rptr, mt};
declare_lint!(pub MUT_MUT, Warn,
"Warn on usage of double-mut refs, e.g. '&mut &mut ...'");
@ -27,25 +23,34 @@ impl LintPass for MutMut {
}
}
if unwrap_addr(expr).and_then(unwrap_addr).is_some() {
cx.span_lint(MUT_MUT, expr.span,
"We're not sure what this means, so if you know, please tell us.")
}
unwrap_addr(expr).map(|e| {
if unwrap_addr(e).is_some() {
cx.span_lint(MUT_MUT, expr.span,
"We're not sure what this means, so if you know, please tell us.")
} else {
match expr_ty(cx.tcx, e).sty {
ty_ptr(mt{ty: _, mutbl: MutMutable}) |
ty_rptr(_, mt{ty: _, mutbl: MutMutable}) =>
cx.span_lint(MUT_MUT, expr.span,
"This expression mutably borrows a mutable reference. Consider direct reborrowing"),
_ => ()
}
}
});
}
fn check_ty(&mut self, cx: &Context, ty: &Ty) {
fn unwrap_mut(ty : &Ty) -> Option<&Ty> {
match ty.node {
TyPtr(MutTy{ ty: ref pty, mutbl: MutMutable }) => Option::Some(pty),
TyRptr(_, MutTy{ ty: ref pty, mutbl: MutMutable }) => Option::Some(pty),
_ => Option::None
}
}
if unwrap_mut(ty).and_then(unwrap_mut).is_some() {
cx.span_lint(MUT_MUT, ty.span,
"We're not sure what this means, so if you know, please tell us.")
}
}
}
fn unwrap_mut(ty : &Ty) -> Option<&Ty> {
match ty.node {
TyPtr(MutTy{ ty: ref pty, mutbl: MutMutable }) => Option::Some(pty),
TyRptr(_, MutTy{ ty: ref pty, mutbl: MutMutable }) => Option::Some(pty),
_ => Option::None
}
}

View File

@ -7,8 +7,13 @@ fn fun(x : &mut &mut u32) -> bool { //~ERROR
}
#[deny(mut_mut)]
#[allow(unused_mut, unused_variables)]
fn main() {
let mut x = &mut &mut 1u32; //~ERROR
{
let mut y = &mut x; //~ERROR
}
if fun(x) {
let y : &mut &mut &mut u32 = &mut &mut &mut 2;
//~^ ERROR