Skip to content

Commit fd28667

Browse files
author
rudyardrichter
committed
Add lint to suggest into()
1 parent fc008aa commit fd28667

File tree

5 files changed

+83
-4
lines changed

5 files changed

+83
-4
lines changed

CHANGELOG.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -654,6 +654,7 @@ All notable changes to this project will be documented in this file.
654654
[`explicit_iter_loop`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#explicit_iter_loop
655655
[`explicit_write`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#explicit_write
656656
[`extend_from_slice`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#extend_from_slice
657+
[`extra_unused_lifetimes`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#extra_unused_lifetimes
657658
[`fallible_impl_from`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#fallible_impl_from
658659
[`filter_map`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#filter_map
659660
[`filter_next`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#filter_next
@@ -835,9 +836,9 @@ All notable changes to this project will be documented in this file.
835836
[`unused_collect`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#unused_collect
836837
[`unused_io_amount`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#unused_io_amount
837838
[`unused_label`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#unused_label
838-
[`unused_lifetimes`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#unused_lifetimes
839839
[`use_debug`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#use_debug
840840
[`use_self`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#use_self
841+
[`use_shared_from_slice`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#use_shared_from_slice
841842
[`used_underscore_binding`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#used_underscore_binding
842843
[`useless_asref`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#useless_asref
843844
[`useless_attribute`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#useless_attribute

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
A collection of lints to catch common mistakes and improve your [Rust](https://github.com/rust-lang/rust) code.
99

10-
[There are 259 lints included in this crate!](https://rust-lang-nursery.github.io/rust-clippy/master/index.html)
10+
[There are 260 lints included in this crate!](https://rust-lang-nursery.github.io/rust-clippy/master/index.html)
1111

1212
We have a bunch of lint categories to allow you to choose how much clippy is supposed to ~~annoy~~ help you:
1313

clippy_lints/src/lib.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ pub mod unsafe_removed_from_name;
201201
pub mod unused_io_amount;
202202
pub mod unused_label;
203203
pub mod use_self;
204+
pub mod use_shared_from_slice;
204205
pub mod vec;
205206
pub mod write;
206207
pub mod zero_div_zero;
@@ -542,8 +543,8 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) {
542543
len_zero::LEN_WITHOUT_IS_EMPTY,
543544
len_zero::LEN_ZERO,
544545
let_if_seq::USELESS_LET_IF_SEQ,
545-
lifetimes::NEEDLESS_LIFETIMES,
546546
lifetimes::EXTRA_UNUSED_LIFETIMES,
547+
lifetimes::NEEDLESS_LIFETIMES,
547548
literal_representation::INCONSISTENT_DIGIT_GROUPING,
548549
literal_representation::LARGE_DIGIT_GROUPS,
549550
literal_representation::UNREADABLE_LITERAL,
@@ -785,8 +786,8 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) {
785786
identity_conversion::IDENTITY_CONVERSION,
786787
identity_op::IDENTITY_OP,
787788
int_plus_one::INT_PLUS_ONE,
788-
lifetimes::NEEDLESS_LIFETIMES,
789789
lifetimes::EXTRA_UNUSED_LIFETIMES,
790+
lifetimes::NEEDLESS_LIFETIMES,
790791
loops::EXPLICIT_COUNTER_LOOP,
791792
loops::MUT_RANGE_BOUND,
792793
loops::WHILE_LET_LOOP,
@@ -910,6 +911,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) {
910911
mutex_atomic::MUTEX_INTEGER,
911912
needless_borrow::NEEDLESS_BORROW,
912913
ranges::RANGE_PLUS_ONE,
914+
use_shared_from_slice::USE_SHARED_FROM_SLICE,
913915
]);
914916
}
915917

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
use rustc::hir::Expr;
2+
use rustc::lint::{LateContext, LateLintPass, LintArray, LintContext, LintPass};
3+
use rustc::ty;
4+
use utils::{match_type, span_lint_and_sugg, walk_ptrs_ty};
5+
use utils::paths;
6+
7+
/// **What it does:**
8+
/// Checks for usage of `Rc<String>` or `Rc<Vec<T>>`.
9+
///
10+
/// **Why is this bad?**
11+
/// Using a `Rc<str>` or `Rc<[T]>` is more efficient and easy to construct with
12+
/// `into()`.
13+
///
14+
/// **Known problems:**
15+
/// None.
16+
///
17+
/// **Example:**
18+
///
19+
/// ```rust
20+
/// use std::rc::Rc;
21+
///
22+
/// // Bad
23+
/// let bad_ref: Rc<Vec<usize>> = Rc::new(vec!(1, 2, 3));
24+
///
25+
/// // Good
26+
/// let good_ref: Rc<[usize]> = Rc::new(vec!(1, 2, 3).into());
27+
/// ```
28+
declare_clippy_lint! {
29+
pub USE_SHARED_FROM_SLICE,
30+
nursery,
31+
"use `into()` to construct `Rc` from slice"
32+
}
33+
34+
#[derive(Copy, Clone, Debug)]
35+
pub struct Pass;
36+
37+
impl LintPass for Pass {
38+
fn get_lints(&self) -> LintArray {
39+
lint_array!(USE_SHARED_FROM_SLICE)
40+
}
41+
}
42+
43+
impl <'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
44+
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
45+
let expr_ty = walk_ptrs_ty(cx.tables.expr_ty(expr));
46+
47+
// Check for expressions with the type `Rc<Vec<T>>`.
48+
if_chain! {
49+
if let ty::TyAdt(_, subst) = expr_ty.sty;
50+
if match_type(cx, expr_ty, &paths::RC);
51+
if match_type(cx, subst.type_at(1), &paths::VEC);
52+
then {
53+
span_lint_and_sugg(
54+
cx,
55+
USE_SHARED_FROM_SLICE,
56+
expr.span,
57+
"constructing reference-counted type from vec",
58+
"consider using `into()`",
59+
format!("TODO"),
60+
);
61+
}
62+
}
63+
64+
// TODO
65+
// Check for expressions with the type `Rc<String>`.
66+
// Check for expressions with the type `Arc<String>`.
67+
// Check for expressions with the type `Arc<Vec<T>>`.
68+
}
69+
}

tests/ui/use_shared_from_slice.rs

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
use std::rc::Rc;
2+
3+
fn main() {
4+
let bad_ref: Rc<Vec<usize>> = Rc::new(vec!(1, 2, 3));
5+
6+
let good_ref: Rc<[usize]> = Rc::new(vec!(1, 2, 3).into());
7+
}

0 commit comments

Comments
 (0)