2 use rustc::ty::{TypeAndMut, TypeVariants, MethodCall, TyS};
7 /// **What it does:** This lint detects giving a mutable reference to a function that only requires an immutable reference.
9 /// **Why is this bad?** The immutable reference rules out all other references to the value. Also the code misleads about the intent of the call site.
11 /// **Known problems:** None
13 /// **Example** `my_vec.push(&mut value)`
15 pub UNNECESSARY_MUT_PASSED,
17 "an argument is passed as a mutable reference although the function/method only demands an \
23 pub struct UnnecessaryMutPassed;
25 impl LintPass for UnnecessaryMutPassed {
26 fn get_lints(&self) -> LintArray {
27 lint_array!(UNNECESSARY_MUT_PASSED)
31 impl LateLintPass for UnnecessaryMutPassed {
32 fn check_expr(&mut self, cx: &LateContext, e: &Expr) {
33 let borrowed_table = cx.tcx.tables.borrow();
35 ExprCall(ref fn_expr, ref arguments) => {
36 let function_type = borrowed_table.node_types
38 .expect("A function with an unknown type is called. \
39 If this happened, the compiler would have \
40 aborted the compilation long ago");
41 if let ExprPath(_, ref path) = fn_expr.node {
42 check_arguments(cx, &arguments, function_type, &path.to_string());
45 ExprMethodCall(ref name, _, ref arguments) => {
46 let method_call = MethodCall::expr(e.id);
47 let method_type = borrowed_table.method_map.get(&method_call).expect("This should never happen.");
48 check_arguments(cx, &arguments, method_type.ty, &name.node.as_str())
55 fn check_arguments(cx: &LateContext, arguments: &[P<Expr>], type_definition: &TyS, name: &str) {
56 match type_definition.sty {
57 TypeVariants::TyFnDef(_, _, ref fn_type) |
58 TypeVariants::TyFnPtr(ref fn_type) => {
59 let parameters = &fn_type.sig.skip_binder().inputs;
60 for (argument, parameter) in arguments.iter().zip(parameters.iter()) {
62 TypeVariants::TyRef(_, TypeAndMut { mutbl: MutImmutable, .. }) |
63 TypeVariants::TyRawPtr(TypeAndMut { mutbl: MutImmutable, .. }) => {
64 if let ExprAddrOf(MutMutable, _) = argument.node {
66 UNNECESSARY_MUT_PASSED,
68 &format!("The function/method \"{}\" doesn't need a mutable reference", name));