Skip to content

Commit ed13f9e

Browse files
committed
submodules: update clippy from dc69a5c to c3e9136
Changes: ```` Fix breakage due to rust-lang/rust#61856 Fix dogfood test Hash discriminant of lifetime.name Hash discriminant of Lifetime::Name Updated tests. Respond to review comments Updated test stderr Added doc comment fixed type printout Respond to comments and improve printout Responded to comments and fixed compile bug Fixed more compile errors Fix some of the compile errors Changed Ty to ty, added lifetime 'tcx Lint for type repetition in trait bounds. ````
1 parent ce5a662 commit ed13f9e

11 files changed

+252
-16
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1138,6 +1138,7 @@ Released 2018-09-13
11381138
[`trivially_copy_pass_by_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#trivially_copy_pass_by_ref
11391139
[`try_err`]: https://rust-lang.github.io/rust-clippy/master/index.html#try_err
11401140
[`type_complexity`]: https://rust-lang.github.io/rust-clippy/master/index.html#type_complexity
1141+
[`type_repetition_in_bounds`]: https://rust-lang.github.io/rust-clippy/master/index.html#type_repetition_in_bounds
11411142
[`unicode_not_nfc`]: https://rust-lang.github.io/rust-clippy/master/index.html#unicode_not_nfc
11421143
[`unimplemented`]: https://rust-lang.github.io/rust-clippy/master/index.html#unimplemented
11431144
[`unit_arg`]: https://rust-lang.github.io/rust-clippy/master/index.html#unit_arg

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

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

9-
[There are 308 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html)
9+
[There are 309 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html)
1010

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

clippy_lints/src/escape.rs

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use rustc::hir::intravisit as visit;
2-
use rustc::hir::*;
2+
use rustc::hir::{self, *};
33
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
44
use rustc::middle::expr_use_visitor::*;
55
use rustc::middle::mem_categorization::{cmt_, Categorization};
@@ -101,6 +101,19 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BoxedLocal {
101101
}
102102
}
103103

104+
// TODO: Replace with Map::is_argument(..) when it's fixed
105+
fn is_argument(map: &hir::map::Map<'_>, id: HirId) -> bool {
106+
match map.find(id) {
107+
Some(Node::Binding(_)) => (),
108+
_ => return false,
109+
}
110+
111+
match map.find(map.get_parent_node(id)) {
112+
Some(Node::Arg(_)) => true,
113+
_ => false,
114+
}
115+
}
116+
104117
impl<'a, 'tcx> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> {
105118
fn consume(&mut self, _: HirId, _: Span, cmt: &cmt_<'tcx>, mode: ConsumeMode) {
106119
if let Categorization::Local(lid) = cmt.cat {
@@ -113,11 +126,13 @@ impl<'a, 'tcx> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> {
113126
fn matched_pat(&mut self, _: &Pat, _: &cmt_<'tcx>, _: MatchMode) {}
114127
fn consume_pat(&mut self, consume_pat: &Pat, cmt: &cmt_<'tcx>, _: ConsumeMode) {
115128
let map = &self.cx.tcx.hir();
116-
if map.is_argument(consume_pat.hir_id) {
129+
if is_argument(map, consume_pat.hir_id) {
117130
// Skip closure arguments
118-
if let Some(Node::Expr(..)) = map.find(map.get_parent_node(consume_pat.hir_id)) {
131+
let parent_id = map.get_parent_node(consume_pat.hir_id);
132+
if let Some(Node::Expr(..)) = map.find(map.get_parent_node(parent_id)) {
119133
return;
120134
}
135+
121136
if is_non_trait_box(cmt.ty) && !self.is_large_box(cmt.ty) {
122137
self.set.insert(consume_pat.hir_id);
123138
}

clippy_lints/src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,7 @@ pub mod strings;
263263
pub mod suspicious_trait_impl;
264264
pub mod swap;
265265
pub mod temporary_assignment;
266+
pub mod trait_bounds;
266267
pub mod transmute;
267268
pub mod transmuting_null;
268269
pub mod trivially_copy_pass_by_ref;
@@ -588,6 +589,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) {
588589
reg.register_late_lint_pass(box checked_conversions::CheckedConversions);
589590
reg.register_late_lint_pass(box integer_division::IntegerDivision);
590591
reg.register_late_lint_pass(box inherent_to_string::InherentToString);
592+
reg.register_late_lint_pass(box trait_bounds::TraitBounds);
591593

592594
reg.register_lint_group("clippy::restriction", Some("clippy_restriction"), vec![
593595
arithmetic::FLOAT_ARITHMETIC,
@@ -858,6 +860,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) {
858860
swap::ALMOST_SWAPPED,
859861
swap::MANUAL_SWAP,
860862
temporary_assignment::TEMPORARY_ASSIGNMENT,
863+
trait_bounds::TYPE_REPETITION_IN_BOUNDS,
861864
transmute::CROSSPOINTER_TRANSMUTE,
862865
transmute::TRANSMUTE_BYTES_TO_STR,
863866
transmute::TRANSMUTE_INT_TO_BOOL,
@@ -1039,6 +1042,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) {
10391042
reference::REF_IN_DEREF,
10401043
swap::MANUAL_SWAP,
10411044
temporary_assignment::TEMPORARY_ASSIGNMENT,
1045+
trait_bounds::TYPE_REPETITION_IN_BOUNDS,
10421046
transmute::CROSSPOINTER_TRANSMUTE,
10431047
transmute::TRANSMUTE_BYTES_TO_STR,
10441048
transmute::TRANSMUTE_INT_TO_BOOL,

clippy_lints/src/trait_bounds.rs

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
use crate::utils::{in_macro, snippet, span_help_and_lint, SpanlessHash};
2+
use rustc::hir::*;
3+
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
4+
use rustc::{declare_tool_lint, impl_lint_pass};
5+
use rustc_data_structures::fx::FxHashMap;
6+
7+
#[derive(Copy, Clone)]
8+
pub struct TraitBounds;
9+
10+
declare_clippy_lint! {
11+
/// **What it does:** This lint warns about unnecessary type repetitions in trait bounds
12+
///
13+
/// **Why is this bad?** Repeating the type for every bound makes the code
14+
/// less readable than combining the bounds
15+
///
16+
/// **Example:**
17+
/// ```rust
18+
/// pub fn foo<T>(t: T) where T: Copy, T: Clone
19+
/// ```
20+
///
21+
/// Could be written as:
22+
///
23+
/// ```rust
24+
/// pub fn foo<T>(t: T) where T: Copy + Clone
25+
/// ```
26+
pub TYPE_REPETITION_IN_BOUNDS,
27+
complexity,
28+
"Types are repeated unnecessary in trait bounds use `+` instead of using `T: _, T: _`"
29+
}
30+
31+
impl_lint_pass!(TraitBounds => [TYPE_REPETITION_IN_BOUNDS]);
32+
33+
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TraitBounds {
34+
fn check_generics(&mut self, cx: &LateContext<'a, 'tcx>, gen: &'tcx Generics) {
35+
if in_macro(gen.span) {
36+
return;
37+
}
38+
let hash = |ty| -> u64 {
39+
let mut hasher = SpanlessHash::new(cx, cx.tables);
40+
hasher.hash_ty(ty);
41+
hasher.finish()
42+
};
43+
let mut map = FxHashMap::default();
44+
for bound in &gen.where_clause.predicates {
45+
if let WherePredicate::BoundPredicate(ref p) = bound {
46+
let h = hash(&p.bounded_ty);
47+
if let Some(ref v) = map.insert(h, p.bounds.iter().collect::<Vec<_>>()) {
48+
let mut hint_string = format!(
49+
"consider combining the bounds: `{}:",
50+
snippet(cx, p.bounded_ty.span, "_")
51+
);
52+
for b in v.iter() {
53+
if let GenericBound::Trait(ref poly_trait_ref, _) = b {
54+
let path = &poly_trait_ref.trait_ref.path;
55+
hint_string.push_str(&format!(" {} +", path));
56+
}
57+
}
58+
for b in p.bounds.iter() {
59+
if let GenericBound::Trait(ref poly_trait_ref, _) = b {
60+
let path = &poly_trait_ref.trait_ref.path;
61+
hint_string.push_str(&format!(" {} +", path));
62+
}
63+
}
64+
hint_string.truncate(hint_string.len() - 2);
65+
hint_string.push('`');
66+
span_help_and_lint(
67+
cx,
68+
TYPE_REPETITION_IN_BOUNDS,
69+
p.span,
70+
"this type has already been used as a bound predicate",
71+
&hint_string,
72+
);
73+
}
74+
}
75+
}
76+
}
77+
}

clippy_lints/src/utils/hir_utils.rs

Lines changed: 102 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -438,9 +438,9 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
438438
self.hash_expr(fun);
439439
self.hash_exprs(args);
440440
},
441-
ExprKind::Cast(ref e, ref _ty) | ExprKind::Type(ref e, ref _ty) => {
441+
ExprKind::Cast(ref e, ref ty) | ExprKind::Type(ref e, ref ty) => {
442442
self.hash_expr(e);
443-
// TODO: _ty
443+
self.hash_ty(ty);
444444
},
445445
ExprKind::Closure(cap, _, eid, _, _) => {
446446
match cap {
@@ -512,7 +512,10 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
512512
self.hash_expr(e);
513513
}
514514
},
515-
ExprKind::Tup(ref v) | ExprKind::Array(ref v) => {
515+
ExprKind::Tup(ref tup) => {
516+
self.hash_exprs(tup);
517+
},
518+
ExprKind::Array(ref v) => {
516519
self.hash_exprs(v);
517520
},
518521
ExprKind::Unary(lop, ref le) => {
@@ -574,4 +577,100 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
574577
},
575578
}
576579
}
580+
581+
pub fn hash_lifetime(&mut self, lifetime: &Lifetime) {
582+
std::mem::discriminant(&lifetime.name).hash(&mut self.s);
583+
if let LifetimeName::Param(ref name) = lifetime.name {
584+
std::mem::discriminant(name).hash(&mut self.s);
585+
match name {
586+
ParamName::Plain(ref ident) => {
587+
ident.name.hash(&mut self.s);
588+
},
589+
ParamName::Fresh(ref size) => {
590+
size.hash(&mut self.s);
591+
},
592+
ParamName::Error => {},
593+
}
594+
}
595+
}
596+
597+
pub fn hash_ty(&mut self, ty: &Ty) {
598+
self.hash_tykind(&ty.node);
599+
}
600+
601+
pub fn hash_tykind(&mut self, ty: &TyKind) {
602+
std::mem::discriminant(ty).hash(&mut self.s);
603+
match ty {
604+
TyKind::Slice(ty) => {
605+
self.hash_ty(ty);
606+
},
607+
TyKind::Array(ty, anon_const) => {
608+
self.hash_ty(ty);
609+
self.hash_expr(&self.cx.tcx.hir().body(anon_const.body).value);
610+
},
611+
TyKind::Ptr(mut_ty) => {
612+
self.hash_ty(&mut_ty.ty);
613+
mut_ty.mutbl.hash(&mut self.s);
614+
},
615+
TyKind::Rptr(lifetime, mut_ty) => {
616+
self.hash_lifetime(lifetime);
617+
self.hash_ty(&mut_ty.ty);
618+
mut_ty.mutbl.hash(&mut self.s);
619+
},
620+
TyKind::BareFn(bfn) => {
621+
bfn.unsafety.hash(&mut self.s);
622+
bfn.abi.hash(&mut self.s);
623+
for arg in &bfn.decl.inputs {
624+
self.hash_ty(&arg);
625+
}
626+
match bfn.decl.output {
627+
FunctionRetTy::DefaultReturn(_) => {
628+
().hash(&mut self.s);
629+
},
630+
FunctionRetTy::Return(ref ty) => {
631+
self.hash_ty(ty);
632+
},
633+
}
634+
bfn.decl.c_variadic.hash(&mut self.s);
635+
},
636+
TyKind::Tup(ty_list) => {
637+
for ty in ty_list {
638+
self.hash_ty(ty);
639+
}
640+
},
641+
TyKind::Path(qpath) => match qpath {
642+
QPath::Resolved(ref maybe_ty, ref path) => {
643+
if let Some(ref ty) = maybe_ty {
644+
self.hash_ty(ty);
645+
}
646+
for segment in &path.segments {
647+
segment.ident.name.hash(&mut self.s);
648+
}
649+
},
650+
QPath::TypeRelative(ref ty, ref segment) => {
651+
self.hash_ty(ty);
652+
segment.ident.name.hash(&mut self.s);
653+
},
654+
},
655+
TyKind::Def(_, arg_list) => {
656+
for arg in arg_list {
657+
match arg {
658+
GenericArg::Lifetime(ref l) => self.hash_lifetime(l),
659+
GenericArg::Type(ref ty) => self.hash_ty(&ty),
660+
GenericArg::Const(ref ca) => {
661+
self.hash_expr(&self.cx.tcx.hir().body(ca.value.body).value);
662+
},
663+
}
664+
}
665+
},
666+
TyKind::TraitObject(_, lifetime) => {
667+
self.hash_lifetime(lifetime);
668+
},
669+
TyKind::Typeof(anon_const) => {
670+
self.hash_expr(&self.cx.tcx.hir().body(anon_const.body).value);
671+
},
672+
TyKind::CVarArgs(lifetime) => self.hash_lifetime(lifetime),
673+
TyKind::Err | TyKind::Infer | TyKind::Never => {},
674+
}
675+
}
577676
}

src/lintlist/mod.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ pub use lint::Lint;
66
pub use lint::LINT_LEVELS;
77

88
// begin lint list, do not remove this comment, it’s used in `update_lints`
9-
pub const ALL_LINTS: [Lint; 308] = [
9+
pub const ALL_LINTS: [Lint; 309] = [
1010
Lint {
1111
name: "absurd_extreme_comparisons",
1212
group: "correctness",
@@ -1848,6 +1848,13 @@ pub const ALL_LINTS: [Lint; 308] = [
18481848
deprecation: None,
18491849
module: "types",
18501850
},
1851+
Lint {
1852+
name: "type_repetition_in_bounds",
1853+
group: "complexity",
1854+
desc: "Types are repeated unnecessary in trait bounds use `+` instead of using `T: _, T: _`",
1855+
deprecation: None,
1856+
module: "trait_bounds",
1857+
},
18511858
Lint {
18521859
name: "unicode_not_nfc",
18531860
group: "pedantic",

tests/ui/float_cmp.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@ const ONE: f32 = ZERO + 1.0;
88

99
fn twice<T>(x: T) -> T
1010
where
11-
T: Add<T, Output = T>,
12-
T: Copy,
11+
T: Add<T, Output = T> + Copy,
1312
{
1413
x + x
1514
}

tests/ui/float_cmp.stderr

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,36 @@
11
error: strict comparison of f32 or f64
2-
--> $DIR/float_cmp.rs:60:5
2+
--> $DIR/float_cmp.rs:59:5
33
|
44
LL | ONE as f64 != 2.0;
55
| ^^^^^^^^^^^^^^^^^ help: consider comparing them within some error: `(ONE as f64 - 2.0).abs() > error`
66
|
77
= note: `-D clippy::float-cmp` implied by `-D warnings`
88
note: std::f32::EPSILON and std::f64::EPSILON are available.
9-
--> $DIR/float_cmp.rs:60:5
9+
--> $DIR/float_cmp.rs:59:5
1010
|
1111
LL | ONE as f64 != 2.0;
1212
| ^^^^^^^^^^^^^^^^^
1313

1414
error: strict comparison of f32 or f64
15-
--> $DIR/float_cmp.rs:65:5
15+
--> $DIR/float_cmp.rs:64:5
1616
|
1717
LL | x == 1.0;
1818
| ^^^^^^^^ help: consider comparing them within some error: `(x - 1.0).abs() < error`
1919
|
2020
note: std::f32::EPSILON and std::f64::EPSILON are available.
21-
--> $DIR/float_cmp.rs:65:5
21+
--> $DIR/float_cmp.rs:64:5
2222
|
2323
LL | x == 1.0;
2424
| ^^^^^^^^
2525

2626
error: strict comparison of f32 or f64
27-
--> $DIR/float_cmp.rs:68:5
27+
--> $DIR/float_cmp.rs:67:5
2828
|
2929
LL | twice(x) != twice(ONE as f64);
3030
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some error: `(twice(x) - twice(ONE as f64)).abs() > error`
3131
|
3232
note: std::f32::EPSILON and std::f64::EPSILON are available.
33-
--> $DIR/float_cmp.rs:68:5
33+
--> $DIR/float_cmp.rs:67:5
3434
|
3535
LL | twice(x) != twice(ONE as f64);
3636
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

tests/ui/type_repetition_in_bounds.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#[deny(clippy::type_repetition_in_bounds)]
2+
3+
pub fn foo<T>(_t: T)
4+
where
5+
T: Copy,
6+
T: Clone,
7+
{
8+
unimplemented!();
9+
}
10+
11+
pub fn bar<T, U>(_t: T, _u: U)
12+
where
13+
T: Copy,
14+
U: Clone,
15+
{
16+
unimplemented!();
17+
}
18+
19+
fn main() {}

0 commit comments

Comments
 (0)