suggestion for ptr_arg
This commit is contained in:
@@ -7,7 +7,8 @@ use rustc::ty;
|
|||||||
use syntax::ast::NodeId;
|
use syntax::ast::NodeId;
|
||||||
use syntax::codemap::Span;
|
use syntax::codemap::Span;
|
||||||
use syntax_pos::MultiSpan;
|
use syntax_pos::MultiSpan;
|
||||||
use utils::{match_qpath, match_type, paths, span_lint, span_lint_and_then};
|
use utils::{match_qpath, match_type, paths, snippet_opt, span_lint, span_lint_and_then,
|
||||||
|
span_lint_and_sugg, walk_ptrs_hir_ty};
|
||||||
|
|
||||||
/// **What it does:** This lint checks for function arguments of type `&String`
|
/// **What it does:** This lint checks for function arguments of type `&String`
|
||||||
/// or `&Vec` unless
|
/// or `&Vec` unless
|
||||||
@@ -137,20 +138,37 @@ fn check_fn(cx: &LateContext, decl: &FnDecl, fn_id: NodeId) {
|
|||||||
) = ty.sty
|
) = ty.sty
|
||||||
{
|
{
|
||||||
if match_type(cx, ty, &paths::VEC) {
|
if match_type(cx, ty, &paths::VEC) {
|
||||||
span_lint(
|
let mut ty_snippet = None;
|
||||||
|
if_let_chain!([
|
||||||
|
let TyPath(QPath::Resolved(_, ref path)) = walk_ptrs_hir_ty(arg).node,
|
||||||
|
let Some(&PathSegment{ref parameters, ..}) = path.segments.last(),
|
||||||
|
parameters.types.len() == 1,
|
||||||
|
], {
|
||||||
|
ty_snippet = snippet_opt(cx, parameters.types[0].span);
|
||||||
|
});
|
||||||
|
//TODO: Suggestion
|
||||||
|
span_lint_and_then(
|
||||||
cx,
|
cx,
|
||||||
PTR_ARG,
|
PTR_ARG,
|
||||||
arg.span,
|
arg.span,
|
||||||
"writing `&Vec<_>` instead of `&[_]` involves one more reference and cannot be used \
|
"writing `&Vec<_>` instead of `&[_]` involves one more reference and cannot be used \
|
||||||
with non-Vec-based slices. Consider changing the type to `&[...]`",
|
with non-Vec-based slices.",
|
||||||
|
|db| {
|
||||||
|
if let Some(ref snippet) = ty_snippet {
|
||||||
|
db.span_suggestion(arg.span,
|
||||||
|
"change this to",
|
||||||
|
format!("&[{}]", snippet));
|
||||||
|
}
|
||||||
|
}
|
||||||
);
|
);
|
||||||
} else if match_type(cx, ty, &paths::STRING) {
|
} else if match_type(cx, ty, &paths::STRING) {
|
||||||
span_lint(
|
span_lint_and_sugg(
|
||||||
cx,
|
cx,
|
||||||
PTR_ARG,
|
PTR_ARG,
|
||||||
arg.span,
|
arg.span,
|
||||||
"writing `&String` instead of `&str` involves a new object where a slice will do. \
|
"writing `&String` instead of `&str` involves a new object where a slice will do.",
|
||||||
Consider changing the type to `&str`",
|
"change this to",
|
||||||
|
"&str".to_string()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -645,6 +645,15 @@ pub fn multispan_sugg(db: &mut DiagnosticBuilder, help_msg: String, sugg: Vec<(S
|
|||||||
db.suggestions.push(sugg);
|
db.suggestions.push(sugg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return the base type for HIR references and pointers.
|
||||||
|
pub fn walk_ptrs_hir_ty(ty: &hir::Ty) -> &hir::Ty {
|
||||||
|
match ty.node {
|
||||||
|
TyPtr(ref mut_ty) |
|
||||||
|
TyRptr(_, ref mut_ty) => walk_ptrs_hir_ty(&mut_ty.ty),
|
||||||
|
_ => ty
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Return the base type for references and raw pointers.
|
/// Return the base type for references and raw pointers.
|
||||||
pub fn walk_ptrs_ty(ty: Ty) -> Ty {
|
pub fn walk_ptrs_ty(ty: Ty) -> Ty {
|
||||||
match ty.sty {
|
match ty.sty {
|
||||||
|
|||||||
@@ -1,22 +1,22 @@
|
|||||||
error: writing `&Vec<_>` instead of `&[_]` involves one more reference and cannot be used with non-Vec-based slices. Consider changing the type to `&[...]`
|
error: writing `&Vec<_>` instead of `&[_]` involves one more reference and cannot be used with non-Vec-based slices.
|
||||||
--> $DIR/ptr_arg.rs:6:14
|
--> $DIR/ptr_arg.rs:6:14
|
||||||
|
|
|
|
||||||
6 | fn do_vec(x: &Vec<i64>) {
|
6 | fn do_vec(x: &Vec<i64>) {
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^ help: change this to: `&[i64]`
|
||||||
|
|
|
|
||||||
= note: `-D ptr-arg` implied by `-D warnings`
|
= note: `-D ptr-arg` implied by `-D warnings`
|
||||||
|
|
||||||
error: writing `&String` instead of `&str` involves a new object where a slice will do. Consider changing the type to `&str`
|
error: writing `&String` instead of `&str` involves a new object where a slice will do.
|
||||||
--> $DIR/ptr_arg.rs:14:14
|
--> $DIR/ptr_arg.rs:14:14
|
||||||
|
|
|
|
||||||
14 | fn do_str(x: &String) {
|
14 | fn do_str(x: &String) {
|
||||||
| ^^^^^^^
|
| ^^^^^^^ help: change this to: `&str`
|
||||||
|
|
||||||
error: writing `&Vec<_>` instead of `&[_]` involves one more reference and cannot be used with non-Vec-based slices. Consider changing the type to `&[...]`
|
error: writing `&Vec<_>` instead of `&[_]` involves one more reference and cannot be used with non-Vec-based slices.
|
||||||
--> $DIR/ptr_arg.rs:27:18
|
--> $DIR/ptr_arg.rs:27:18
|
||||||
|
|
|
|
||||||
27 | fn do_vec(x: &Vec<i64>);
|
27 | fn do_vec(x: &Vec<i64>);
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^ help: change this to: `&[i64]`
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user