suggestion for ptr_arg

This commit is contained in:
Andre Bogus
2017-09-10 19:32:24 +02:00
parent b0b60558c5
commit e7e8e79020
3 changed files with 39 additions and 12 deletions

View File

@@ -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()
); );
} }
} }

View File

@@ -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 {

View File

@@ -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