Skip to content

Commit 6b583d6

Browse files
authored
Merge pull request #2039 from rust-lang-nursery/ptr-arg-suggestion
suggestion for ptr_arg
2 parents b0b6055 + e7e8e79 commit 6b583d6

File tree

3 files changed

+39
-12
lines changed

3 files changed

+39
-12
lines changed

clippy_lints/src/ptr.rs

+24-6
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ use rustc::ty;
77
use syntax::ast::NodeId;
88
use syntax::codemap::Span;
99
use syntax_pos::MultiSpan;
10-
use utils::{match_qpath, match_type, paths, span_lint, span_lint_and_then};
10+
use utils::{match_qpath, match_type, paths, snippet_opt, span_lint, span_lint_and_then,
11+
span_lint_and_sugg, walk_ptrs_hir_ty};
1112

1213
/// **What it does:** This lint checks for function arguments of type `&String`
1314
/// or `&Vec` unless
@@ -137,20 +138,37 @@ fn check_fn(cx: &LateContext, decl: &FnDecl, fn_id: NodeId) {
137138
) = ty.sty
138139
{
139140
if match_type(cx, ty, &paths::VEC) {
140-
span_lint(
141+
let mut ty_snippet = None;
142+
if_let_chain!([
143+
let TyPath(QPath::Resolved(_, ref path)) = walk_ptrs_hir_ty(arg).node,
144+
let Some(&PathSegment{ref parameters, ..}) = path.segments.last(),
145+
parameters.types.len() == 1,
146+
], {
147+
ty_snippet = snippet_opt(cx, parameters.types[0].span);
148+
});
149+
//TODO: Suggestion
150+
span_lint_and_then(
141151
cx,
142152
PTR_ARG,
143153
arg.span,
144154
"writing `&Vec<_>` instead of `&[_]` involves one more reference and cannot be used \
145-
with non-Vec-based slices. Consider changing the type to `&[...]`",
155+
with non-Vec-based slices.",
156+
|db| {
157+
if let Some(ref snippet) = ty_snippet {
158+
db.span_suggestion(arg.span,
159+
"change this to",
160+
format!("&[{}]", snippet));
161+
}
162+
}
146163
);
147164
} else if match_type(cx, ty, &paths::STRING) {
148-
span_lint(
165+
span_lint_and_sugg(
149166
cx,
150167
PTR_ARG,
151168
arg.span,
152-
"writing `&String` instead of `&str` involves a new object where a slice will do. \
153-
Consider changing the type to `&str`",
169+
"writing `&String` instead of `&str` involves a new object where a slice will do.",
170+
"change this to",
171+
"&str".to_string()
154172
);
155173
}
156174
}

clippy_lints/src/utils/mod.rs

+9
Original file line numberDiff line numberDiff line change
@@ -645,6 +645,15 @@ pub fn multispan_sugg(db: &mut DiagnosticBuilder, help_msg: String, sugg: Vec<(S
645645
db.suggestions.push(sugg);
646646
}
647647

648+
/// Return the base type for HIR references and pointers.
649+
pub fn walk_ptrs_hir_ty(ty: &hir::Ty) -> &hir::Ty {
650+
match ty.node {
651+
TyPtr(ref mut_ty) |
652+
TyRptr(_, ref mut_ty) => walk_ptrs_hir_ty(&mut_ty.ty),
653+
_ => ty
654+
}
655+
}
656+
648657
/// Return the base type for references and raw pointers.
649658
pub fn walk_ptrs_ty(ty: Ty) -> Ty {
650659
match ty.sty {

tests/ui/ptr_arg.stderr

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
1-
error: writing `&Vec<_>` instead of `&[_]` involves one more reference and cannot be used with non-Vec-based slices. Consider changing the type to `&[...]`
1+
error: writing `&Vec<_>` instead of `&[_]` involves one more reference and cannot be used with non-Vec-based slices.
22
--> $DIR/ptr_arg.rs:6:14
33
|
44
6 | fn do_vec(x: &Vec<i64>) {
5-
| ^^^^^^^^^
5+
| ^^^^^^^^^ help: change this to: `&[i64]`
66
|
77
= note: `-D ptr-arg` implied by `-D warnings`
88

9-
error: writing `&String` instead of `&str` involves a new object where a slice will do. Consider changing the type to `&str`
9+
error: writing `&String` instead of `&str` involves a new object where a slice will do.
1010
--> $DIR/ptr_arg.rs:14:14
1111
|
1212
14 | fn do_str(x: &String) {
13-
| ^^^^^^^
13+
| ^^^^^^^ help: change this to: `&str`
1414

15-
error: writing `&Vec<_>` instead of `&[_]` involves one more reference and cannot be used with non-Vec-based slices. Consider changing the type to `&[...]`
15+
error: writing `&Vec<_>` instead of `&[_]` involves one more reference and cannot be used with non-Vec-based slices.
1616
--> $DIR/ptr_arg.rs:27:18
1717
|
1818
27 | fn do_vec(x: &Vec<i64>);
19-
| ^^^^^^^^^
19+
| ^^^^^^^^^ help: change this to: `&[i64]`
2020

2121
error: aborting due to 3 previous errors
2222

0 commit comments

Comments
 (0)