Skip to content

Commit 1748d44

Browse files
committed
Update Clippy
1 parent 1d57a66 commit 1748d44

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+1730
-796
lines changed

.travis.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ install:
3030
npm install remark-cli remark-lint
3131
fi
3232
if [ "$TRAVIS_OS_NAME" == "windows" ]; then
33-
choco install windows-sdk-10.0
33+
choco install windows-sdk-10.1
3434
fi
3535
fi
3636
@@ -62,8 +62,8 @@ matrix:
6262
if: repo =~ /^rust-lang\/rust-clippy$/ AND branch IN (auto, try)
6363
- env: INTEGRATION=rust-lang/rustfmt
6464
if: repo =~ /^rust-lang\/rust-clippy$/ AND branch IN (auto, try)
65-
- env: INTEGRATION=hyperium/hyper
66-
if: repo =~ /^rust-lang\/rust-clippy$/ AND branch IN (auto, try)
65+
# - env: INTEGRATION=hyperium/hyper
66+
# if: repo =~ /^rust-lang\/rust-clippy$/ AND branch IN (auto, try)
6767
- env: INTEGRATION=bluss/rust-itertools
6868
if: repo =~ /^rust-lang\/rust-clippy$/ AND branch IN (auto, try)
6969
- env: INTEGRATION=serde-rs/serde
@@ -72,8 +72,8 @@ matrix:
7272
if: repo =~ /^rust-lang\/rust-clippy$/ AND branch IN (auto, try)
7373
- env: INTEGRATION=rust-random/rand
7474
if: repo =~ /^rust-lang\/rust-clippy$/ AND branch IN (auto, try)
75-
- env: INTEGRATION=rust-lang-nursery/futures-rs
76-
if: repo =~ /^rust-lang\/rust-clippy$/ AND branch IN (auto, try)
75+
# - env: INTEGRATION=rust-lang-nursery/futures-rs
76+
# if: repo =~ /^rust-lang\/rust-clippy$/ AND branch IN (auto, try)
7777
- env: INTEGRATION=Marwes/combine
7878
if: repo =~ /^rust-lang\/rust-clippy$/ AND branch IN (auto, try)
7979
- env: INTEGRATION=rust-lang-nursery/failure

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1105,6 +1105,7 @@ Released 2018-09-13
11051105
[`needless_borrowed_reference`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrowed_reference
11061106
[`needless_collect`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_collect
11071107
[`needless_continue`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_continue
1108+
[`needless_doctest_main`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_doctest_main
11081109
[`needless_lifetimes`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
11091110
[`needless_pass_by_value`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_value
11101111
[`needless_range_loop`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_range_loop
@@ -1224,6 +1225,7 @@ Released 2018-09-13
12241225
[`unsafe_removed_from_name`]: https://rust-lang.github.io/rust-clippy/master/index.html#unsafe_removed_from_name
12251226
[`unsafe_vector_initialization`]: https://rust-lang.github.io/rust-clippy/master/index.html#unsafe_vector_initialization
12261227
[`unseparated_literal_suffix`]: https://rust-lang.github.io/rust-clippy/master/index.html#unseparated_literal_suffix
1228+
[`unsound_collection_transmute`]: https://rust-lang.github.io/rust-clippy/master/index.html#unsound_collection_transmute
12271229
[`unstable_as_mut_slice`]: https://rust-lang.github.io/rust-clippy/master/index.html#unstable_as_mut_slice
12281230
[`unstable_as_slice`]: https://rust-lang.github.io/rust-clippy/master/index.html#unstable_as_slice
12291231
[`unused_collect`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_collect

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 317 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html)
9+
[There are 319 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_dev/src/fmt.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,10 +100,7 @@ pub fn run(check: bool, verbose: bool) {
100100
}
101101

102102
fn format_command(program: impl AsRef<OsStr>, dir: impl AsRef<Path>, args: &[impl AsRef<OsStr>]) -> String {
103-
let arg_display: Vec<_> = args
104-
.iter()
105-
.map(|a| escape(a.as_ref().to_string_lossy()).to_owned())
106-
.collect();
103+
let arg_display: Vec<_> = args.iter().map(|a| escape(a.as_ref().to_string_lossy())).collect();
107104

108105
format!(
109106
"cd {} && {} {}",

clippy_dev/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ impl Lint {
5757
lints.filter(|l| l.deprecation.is_none() && !l.is_internal())
5858
}
5959

60-
/// Returns the lints in a HashMap, grouped by the different lint groups
60+
/// Returns the lints in a `HashMap`, grouped by the different lint groups
6161
pub fn by_lint_group(lints: &[Self]) -> HashMap<String, Vec<Self>> {
6262
lints
6363
.iter()

clippy_lints/src/booleans.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,7 @@ impl<'a, 'tcx> NonminimalBoolVisitor<'a, 'tcx> {
343343

344344
let stats = terminal_stats(&expr);
345345
let mut simplified = expr.simplify();
346-
for simple in Bool::Not(Box::new(expr.clone())).simplify() {
346+
for simple in Bool::Not(Box::new(expr)).simplify() {
347347
match simple {
348348
Bool::Not(_) | Bool::True | Bool::False => {},
349349
_ => simplified.push(Bool::Not(Box::new(simple.clone()))),

clippy_lints/src/consts.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ impl Constant {
152152
}
153153

154154
/// Parses a `LitKind` to a `Constant`.
155-
pub fn lit_to_constant(lit: &LitKind, ty: Ty<'_>) -> Constant {
155+
pub fn lit_to_constant(lit: &LitKind, ty: Option<Ty<'_>>) -> Constant {
156156
use syntax::ast::*;
157157

158158
match *lit {
@@ -161,7 +161,9 @@ pub fn lit_to_constant(lit: &LitKind, ty: Ty<'_>) -> Constant {
161161
LitKind::ByteStr(ref s) => Constant::Binary(Lrc::clone(s)),
162162
LitKind::Char(c) => Constant::Char(c),
163163
LitKind::Int(n, _) => Constant::Int(n),
164-
LitKind::Float(ref is, _) | LitKind::FloatUnsuffixed(ref is) => match ty.kind {
164+
LitKind::Float(ref is, FloatTy::F32) => Constant::F32(is.as_str().parse().unwrap()),
165+
LitKind::Float(ref is, FloatTy::F64) => Constant::F64(is.as_str().parse().unwrap()),
166+
LitKind::FloatUnsuffixed(ref is) => match ty.expect("type of float is known").kind {
165167
ty::Float(FloatTy::F32) => Constant::F32(is.as_str().parse().unwrap()),
166168
ty::Float(FloatTy::F64) => Constant::F64(is.as_str().parse().unwrap()),
167169
_ => bug!(),
@@ -225,7 +227,7 @@ impl<'c, 'cc> ConstEvalLateContext<'c, 'cc> {
225227
match e.kind {
226228
ExprKind::Path(ref qpath) => self.fetch_path(qpath, e.hir_id),
227229
ExprKind::Block(ref block, _) => self.block(block),
228-
ExprKind::Lit(ref lit) => Some(lit_to_constant(&lit.node, self.tables.expr_ty(e))),
230+
ExprKind::Lit(ref lit) => Some(lit_to_constant(&lit.node, self.tables.expr_ty_opt(e))),
229231
ExprKind::Array(ref vec) => self.multi(vec).map(Constant::Vec),
230232
ExprKind::Tup(ref tup) => self.multi(tup).map(Constant::Tuple),
231233
ExprKind::Repeat(ref value, _) => {
@@ -322,7 +324,7 @@ impl<'c, 'cc> ConstEvalLateContext<'c, 'cc> {
322324
vec.iter().map(|elem| self.expr(elem)).collect::<Option<_>>()
323325
}
324326

325-
/// Lookup a possibly constant expression from a ExprKind::Path.
327+
/// Lookup a possibly constant expression from a `ExprKind::Path`.
326328
fn fetch_path(&mut self, qpath: &QPath, id: HirId) -> Option<Constant> {
327329
use rustc::mir::interpret::GlobalId;
328330

clippy_lints/src/doc.rs

Lines changed: 106 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
use crate::utils::span_lint;
22
use itertools::Itertools;
33
use pulldown_cmark;
4-
use rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintPass};
4+
use rustc::hir;
5+
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
56
use rustc::{declare_tool_lint, impl_lint_pass};
67
use rustc_data_structures::fx::FxHashSet;
78
use std::ops::Range;
8-
use syntax::ast;
9+
use syntax::ast::Attribute;
910
use syntax::source_map::{BytePos, Span};
1011
use syntax_pos::Pos;
1112
use url::Url;
@@ -68,32 +69,110 @@ declare_clippy_lint! {
6869
"`pub unsafe fn` without `# Safety` docs"
6970
}
7071

72+
declare_clippy_lint! {
73+
/// **What it does:** Checks for `fn main() { .. }` in doctests
74+
///
75+
/// **Why is this bad?** The test can be shorter (and likely more readable)
76+
/// if the `fn main()` is left implicit.
77+
///
78+
/// **Known problems:** None.
79+
///
80+
/// **Examples:**
81+
/// ``````rust
82+
/// /// An example of a doctest with a `main()` function
83+
/// ///
84+
/// /// # Examples
85+
/// ///
86+
/// /// ```
87+
/// /// fn main() {
88+
/// /// // this needs not be in an `fn`
89+
/// /// }
90+
/// /// ```
91+
/// fn needless_main() {
92+
/// unimplemented!();
93+
/// }
94+
/// ``````
95+
pub NEEDLESS_DOCTEST_MAIN,
96+
style,
97+
"presence of `fn main() {` in code examples"
98+
}
99+
71100
#[allow(clippy::module_name_repetitions)]
72101
#[derive(Clone)]
73102
pub struct DocMarkdown {
74103
valid_idents: FxHashSet<String>,
104+
in_trait_impl: bool,
75105
}
76106

77107
impl DocMarkdown {
78108
pub fn new(valid_idents: FxHashSet<String>) -> Self {
79-
Self { valid_idents }
109+
Self {
110+
valid_idents,
111+
in_trait_impl: false,
112+
}
80113
}
81114
}
82115

83-
impl_lint_pass!(DocMarkdown => [DOC_MARKDOWN, MISSING_SAFETY_DOC]);
116+
impl_lint_pass!(DocMarkdown => [DOC_MARKDOWN, MISSING_SAFETY_DOC, NEEDLESS_DOCTEST_MAIN]);
84117

85-
impl EarlyLintPass for DocMarkdown {
86-
fn check_crate(&mut self, cx: &EarlyContext<'_>, krate: &ast::Crate) {
118+
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for DocMarkdown {
119+
fn check_crate(&mut self, cx: &LateContext<'a, 'tcx>, krate: &'tcx hir::Crate) {
87120
check_attrs(cx, &self.valid_idents, &krate.attrs);
88121
}
89122

90-
fn check_item(&mut self, cx: &EarlyContext<'_>, item: &ast::Item) {
123+
fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx hir::Item) {
124+
if check_attrs(cx, &self.valid_idents, &item.attrs) {
125+
return;
126+
}
127+
// no safety header
128+
match item.kind {
129+
hir::ItemKind::Fn(_, ref header, ..) => {
130+
if cx.access_levels.is_exported(item.hir_id) && header.unsafety == hir::Unsafety::Unsafe {
131+
span_lint(
132+
cx,
133+
MISSING_SAFETY_DOC,
134+
item.span,
135+
"unsafe function's docs miss `# Safety` section",
136+
);
137+
}
138+
},
139+
hir::ItemKind::Impl(_, _, _, _, ref trait_ref, ..) => {
140+
self.in_trait_impl = trait_ref.is_some();
141+
},
142+
_ => {},
143+
}
144+
}
145+
146+
fn check_item_post(&mut self, _cx: &LateContext<'a, 'tcx>, item: &'tcx hir::Item) {
147+
if let hir::ItemKind::Impl(..) = item.kind {
148+
self.in_trait_impl = false;
149+
}
150+
}
151+
152+
fn check_trait_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx hir::TraitItem) {
91153
if check_attrs(cx, &self.valid_idents, &item.attrs) {
92154
return;
93155
}
94156
// no safety header
95-
if let ast::ItemKind::Fn(_, ref header, ..) = item.kind {
96-
if item.vis.node.is_pub() && header.unsafety == ast::Unsafety::Unsafe {
157+
if let hir::TraitItemKind::Method(ref sig, ..) = item.kind {
158+
if cx.access_levels.is_exported(item.hir_id) && sig.header.unsafety == hir::Unsafety::Unsafe {
159+
span_lint(
160+
cx,
161+
MISSING_SAFETY_DOC,
162+
item.span,
163+
"unsafe function's docs miss `# Safety` section",
164+
);
165+
}
166+
}
167+
}
168+
169+
fn check_impl_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx hir::ImplItem) {
170+
if check_attrs(cx, &self.valid_idents, &item.attrs) || self.in_trait_impl {
171+
return;
172+
}
173+
// no safety header
174+
if let hir::ImplItemKind::Method(ref sig, ..) = item.kind {
175+
if cx.access_levels.is_exported(item.hir_id) && sig.header.unsafety == hir::Unsafety::Unsafe {
97176
span_lint(
98177
cx,
99178
MISSING_SAFETY_DOC,
@@ -162,7 +241,7 @@ pub fn strip_doc_comment_decoration(comment: &str, span: Span) -> (String, Vec<(
162241
panic!("not a doc-comment: {}", comment);
163242
}
164243

165-
pub fn check_attrs<'a>(cx: &EarlyContext<'_>, valid_idents: &FxHashSet<String>, attrs: &'a [ast::Attribute]) -> bool {
244+
pub fn check_attrs<'a>(cx: &LateContext<'_, '_>, valid_idents: &FxHashSet<String>, attrs: &'a [Attribute]) -> bool {
166245
let mut doc = String::new();
167246
let mut spans = vec![];
168247

@@ -212,7 +291,7 @@ pub fn check_attrs<'a>(cx: &EarlyContext<'_>, valid_idents: &FxHashSet<String>,
212291
}
213292

214293
fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize>)>>(
215-
cx: &EarlyContext<'_>,
294+
cx: &LateContext<'_, '_>,
216295
valid_idents: &FxHashSet<String>,
217296
events: Events,
218297
spans: &[(usize, Span)],
@@ -245,14 +324,14 @@ fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize
245324
continue;
246325
}
247326
safety_header |= in_heading && text.trim() == "Safety";
248-
if !in_code {
249-
let index = match spans.binary_search_by(|c| c.0.cmp(&range.start)) {
250-
Ok(o) => o,
251-
Err(e) => e - 1,
252-
};
253-
254-
let (begin, span) = spans[index];
255-
327+
let index = match spans.binary_search_by(|c| c.0.cmp(&range.start)) {
328+
Ok(o) => o,
329+
Err(e) => e - 1,
330+
};
331+
let (begin, span) = spans[index];
332+
if in_code {
333+
check_code(cx, &text, span);
334+
} else {
256335
// Adjust for the beginning of the current `Event`
257336
let span = span.with_lo(span.lo() + BytePos::from_usize(range.start - begin));
258337

@@ -264,7 +343,13 @@ fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize
264343
safety_header
265344
}
266345

267-
fn check_text(cx: &EarlyContext<'_>, valid_idents: &FxHashSet<String>, text: &str, span: Span) {
346+
fn check_code(cx: &LateContext<'_, '_>, text: &str, span: Span) {
347+
if text.contains("fn main() {") {
348+
span_lint(cx, NEEDLESS_DOCTEST_MAIN, span, "needless `fn main` in doctest");
349+
}
350+
}
351+
352+
fn check_text(cx: &LateContext<'_, '_>, valid_idents: &FxHashSet<String>, text: &str, span: Span) {
268353
for word in text.split(|c: char| c.is_whitespace() || c == '\'') {
269354
// Trim punctuation as in `some comment (see foo::bar).`
270355
// ^^
@@ -287,7 +372,7 @@ fn check_text(cx: &EarlyContext<'_>, valid_idents: &FxHashSet<String>, text: &st
287372
}
288373
}
289374

290-
fn check_word(cx: &EarlyContext<'_>, word: &str, span: Span) {
375+
fn check_word(cx: &LateContext<'_, '_>, word: &str, span: Span) {
291376
/// Checks if a string is camel-case, i.e., contains at least two uppercase
292377
/// letters (`Clippy` is ok) and one lower-case letter (`NASA` is ok).
293378
/// Plurals are also excluded (`IDs` is ok).

0 commit comments

Comments
 (0)