mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-11-10 15:14:29 +00:00
add notes for immutable inputs
This commit is contained in:
parent
ad01fa9b57
commit
36b8554cf1
4 changed files with 32 additions and 47 deletions
|
@ -15,6 +15,7 @@
|
|||
#![allow(needless_lifetimes)]
|
||||
|
||||
extern crate syntax;
|
||||
extern crate syntax_pos;
|
||||
#[macro_use]
|
||||
extern crate rustc;
|
||||
extern crate rustc_data_structures;
|
||||
|
|
|
@ -5,7 +5,9 @@ use rustc::hir::map::NodeItem;
|
|||
use rustc::lint::*;
|
||||
use rustc::ty;
|
||||
use syntax::ast::NodeId;
|
||||
use utils::{match_path, match_type, paths, span_lint};
|
||||
use syntax::codemap::Span;
|
||||
use syntax_pos::MultiSpan;
|
||||
use utils::{match_path, match_type, paths, span_lint, span_lint_and_then};
|
||||
|
||||
/// **What it does:** This lint checks for function arguments of type `&String` or `&Vec` unless
|
||||
/// the references are mutable.
|
||||
|
@ -132,29 +134,31 @@ fn check_fn(cx: &LateContext, decl: &FnDecl, fn_id: NodeId) {
|
|||
}
|
||||
|
||||
if let FunctionRetTy::Return(ref ty) = decl.output {
|
||||
if let Some((out, MutMutable)) = get_rptr_lm(ty) {
|
||||
if let Some(MutImmutable) =
|
||||
decl.inputs
|
||||
.iter()
|
||||
.filter_map(|ty| get_rptr_lm(ty))
|
||||
.filter(|&(lt, _)| lt.name == out.name)
|
||||
.fold(None, |x, (_, m)| match (x, m) {
|
||||
(Some(MutMutable), _) |
|
||||
(_, MutMutable) => Some(MutMutable),
|
||||
(_, m) => Some(m),
|
||||
}) {
|
||||
span_lint(cx,
|
||||
MUT_FROM_REF,
|
||||
ty.span,
|
||||
"this function takes an immutable ref to return a mutable one");
|
||||
if let Some((out, MutMutable, _)) = get_rptr_lm(ty) {
|
||||
let mut immutables = vec![];
|
||||
for (_, ref mutbl, ref argspan) in decl.inputs
|
||||
.iter()
|
||||
.filter_map(|ty| get_rptr_lm(ty))
|
||||
.filter(|&(lt, _, _)| lt.name == out.name) {
|
||||
if *mutbl == MutMutable { return; }
|
||||
immutables.push(*argspan);
|
||||
}
|
||||
if immutables.is_empty() { return; }
|
||||
span_lint_and_then(cx,
|
||||
MUT_FROM_REF,
|
||||
ty.span,
|
||||
"mutable borrow from immutable input(s)",
|
||||
|db| {
|
||||
let ms = MultiSpan::from_spans(immutables);
|
||||
db.span_note(ms, "immutable borrow here");
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn get_rptr_lm(ty: &Ty) -> Option<(&Lifetime, Mutability)> {
|
||||
fn get_rptr_lm(ty: &Ty) -> Option<(&Lifetime, Mutability, Span)> {
|
||||
if let Ty_::TyRptr(ref lt, ref m) = ty.node {
|
||||
Some((lt, m.mutbl))
|
||||
Some((lt, m.mutbl, ty.span))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
|
|
@ -29,6 +29,10 @@ fn fail_lifetime<'a>(x: &'a u32, y: &mut u32) -> &'a mut u32 {
|
|||
unimplemented!()
|
||||
}
|
||||
|
||||
fn fail_double<'a>(x: &'a u32, y: &'a u32, z: &'b mut u32) -> &'a mut u32 {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
// this is OK, because the result borrows y
|
||||
fn works<'a>(x: &u32, y: &'a mut u32) -> &'a mut u32 {
|
||||
unimplemented!()
|
||||
|
|
|
@ -1,32 +1,8 @@
|
|||
error: this function takes an immutable ref to return a mutable one
|
||||
--> $DIR/mut_from_ref.rs:9:39
|
||||
|
|
||||
9 | fn this_wont_hurt_a_bit(&self) -> &mut Foo {
|
||||
| ^^^^^^^^
|
||||
|
|
||||
note: lint level defined here
|
||||
--> $DIR/mut_from_ref.rs:4:9
|
||||
|
|
||||
4 | #![deny(mut_from_ref)]
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: this function takes an immutable ref to return a mutable one
|
||||
--> $DIR/mut_from_ref.rs:15:25
|
||||
error[E0261]: use of undeclared lifetime name `'b`
|
||||
--> $DIR/mut_from_ref.rs:32:48
|
||||
|
|
||||
15 | fn ouch(x: &Foo) -> &mut Foo;
|
||||
| ^^^^^^^^
|
||||
32 | fn fail_double<'a>(x: &'a u32, y: &'a u32, z: &'b mut u32) -> &'a mut u32 {
|
||||
| ^^ undeclared lifetime
|
||||
|
||||
error: this function takes an immutable ref to return a mutable one
|
||||
--> $DIR/mut_from_ref.rs:24:21
|
||||
|
|
||||
24 | fn fail(x: &u32) -> &mut u16 {
|
||||
| ^^^^^^^^
|
||||
|
||||
error: this function takes an immutable ref to return a mutable one
|
||||
--> $DIR/mut_from_ref.rs:28:50
|
||||
|
|
||||
28 | fn fail_lifetime<'a>(x: &'a u32, y: &mut u32) -> &'a mut u32 {
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
Loading…
Reference in a new issue