Skip to content

Commit df5a1ee

Browse files
committed
update clippy to the rustc-pr-67224 branch
Actually to commit <69f99e74ac2266dff4b5adc7c59b35236f0abef1>.
1 parent 8e8c6c0 commit df5a1ee

24 files changed

+434
-73
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1092,6 +1092,7 @@ Released 2018-09-13
10921092
[`misrefactored_assign_op`]: https://rust-lang.github.io/rust-clippy/master/index.html#misrefactored_assign_op
10931093
[`missing_const_for_fn`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_const_for_fn
10941094
[`missing_docs_in_private_items`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_docs_in_private_items
1095+
[`missing_errors_doc`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_errors_doc
10951096
[`missing_inline_in_public_items`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_inline_in_public_items
10961097
[`missing_safety_doc`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_safety_doc
10971098
[`mistyped_literal_suffixes`]: https://rust-lang.github.io/rust-clippy/master/index.html#mistyped_literal_suffixes
@@ -1213,6 +1214,7 @@ Released 2018-09-13
12131214
[`too_many_lines`]: https://rust-lang.github.io/rust-clippy/master/index.html#too_many_lines
12141215
[`toplevel_ref_arg`]: https://rust-lang.github.io/rust-clippy/master/index.html#toplevel_ref_arg
12151216
[`transmute_bytes_to_str`]: https://rust-lang.github.io/rust-clippy/master/index.html#transmute_bytes_to_str
1217+
[`transmute_float_to_int`]: https://rust-lang.github.io/rust-clippy/master/index.html#transmute_float_to_int
12161218
[`transmute_int_to_bool`]: https://rust-lang.github.io/rust-clippy/master/index.html#transmute_int_to_bool
12171219
[`transmute_int_to_char`]: https://rust-lang.github.io/rust-clippy/master/index.html#transmute_int_to_char
12181220
[`transmute_int_to_float`]: https://rust-lang.github.io/rust-clippy/master/index.html#transmute_int_to_float

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

Lines changed: 92 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::utils::span_lint;
1+
use crate::utils::{match_type, paths, return_ty, span_lint};
22
use itertools::Itertools;
33
use pulldown_cmark;
44
use rustc::hir;
@@ -8,7 +8,7 @@ use rustc_data_structures::fx::FxHashSet;
88
use rustc_session::declare_tool_lint;
99
use std::ops::Range;
1010
use syntax::ast::{AttrKind, Attribute};
11-
use syntax::source_map::{BytePos, Span};
11+
use syntax::source_map::{BytePos, MultiSpan, Span};
1212
use syntax_pos::Pos;
1313
use url::Url;
1414

@@ -45,7 +45,7 @@ declare_clippy_lint! {
4545
///
4646
/// **Known problems:** None.
4747
///
48-
/// **Examples**:
48+
/// **Examples:**
4949
/// ```rust
5050
///# type Universe = ();
5151
/// /// This function should really be documented
@@ -70,6 +70,35 @@ declare_clippy_lint! {
7070
"`pub unsafe fn` without `# Safety` docs"
7171
}
7272

73+
declare_clippy_lint! {
74+
/// **What it does:** Checks the doc comments of publicly visible functions that
75+
/// return a `Result` type and warns if there is no `# Errors` section.
76+
///
77+
/// **Why is this bad?** Documenting the type of errors that can be returned from a
78+
/// function can help callers write code to handle the errors appropriately.
79+
///
80+
/// **Known problems:** None.
81+
///
82+
/// **Examples:**
83+
///
84+
/// Since the following function returns a `Result` it has an `# Errors` section in
85+
/// its doc comment:
86+
///
87+
/// ```rust
88+
///# use std::io;
89+
/// /// # Errors
90+
/// ///
91+
/// /// Will return `Err` if `filename` does not exist or the user does not have
92+
/// /// permission to read it.
93+
/// pub fn read(filename: String) -> io::Result<String> {
94+
/// unimplemented!();
95+
/// }
96+
/// ```
97+
pub MISSING_ERRORS_DOC,
98+
pedantic,
99+
"`pub fn` returns `Result` without `# Errors` in doc comment"
100+
}
101+
73102
declare_clippy_lint! {
74103
/// **What it does:** Checks for `fn main() { .. }` in doctests
75104
///
@@ -114,28 +143,18 @@ impl DocMarkdown {
114143
}
115144
}
116145

117-
impl_lint_pass!(DocMarkdown => [DOC_MARKDOWN, MISSING_SAFETY_DOC, NEEDLESS_DOCTEST_MAIN]);
146+
impl_lint_pass!(DocMarkdown => [DOC_MARKDOWN, MISSING_SAFETY_DOC, MISSING_ERRORS_DOC, NEEDLESS_DOCTEST_MAIN]);
118147

119148
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for DocMarkdown {
120149
fn check_crate(&mut self, cx: &LateContext<'a, 'tcx>, krate: &'tcx hir::Crate) {
121150
check_attrs(cx, &self.valid_idents, &krate.attrs);
122151
}
123152

124153
fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx hir::Item) {
125-
if check_attrs(cx, &self.valid_idents, &item.attrs) {
126-
return;
127-
}
128-
// no safety header
154+
let headers = check_attrs(cx, &self.valid_idents, &item.attrs);
129155
match item.kind {
130156
hir::ItemKind::Fn(ref sig, ..) => {
131-
if cx.access_levels.is_exported(item.hir_id) && sig.header.unsafety == hir::Unsafety::Unsafe {
132-
span_lint(
133-
cx,
134-
MISSING_SAFETY_DOC,
135-
item.span,
136-
"unsafe function's docs miss `# Safety` section",
137-
);
138-
}
157+
lint_for_missing_headers(cx, item.hir_id, item.span, sig, headers);
139158
},
140159
hir::ItemKind::Impl(_, _, _, _, ref trait_ref, ..) => {
141160
self.in_trait_impl = trait_ref.is_some();
@@ -151,40 +170,51 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for DocMarkdown {
151170
}
152171

153172
fn check_trait_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx hir::TraitItem) {
154-
if check_attrs(cx, &self.valid_idents, &item.attrs) {
155-
return;
156-
}
157-
// no safety header
173+
let headers = check_attrs(cx, &self.valid_idents, &item.attrs);
158174
if let hir::TraitItemKind::Method(ref sig, ..) = item.kind {
159-
if cx.access_levels.is_exported(item.hir_id) && sig.header.unsafety == hir::Unsafety::Unsafe {
160-
span_lint(
161-
cx,
162-
MISSING_SAFETY_DOC,
163-
item.span,
164-
"unsafe function's docs miss `# Safety` section",
165-
);
166-
}
175+
lint_for_missing_headers(cx, item.hir_id, item.span, sig, headers);
167176
}
168177
}
169178

170179
fn check_impl_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx hir::ImplItem) {
171-
if check_attrs(cx, &self.valid_idents, &item.attrs) || self.in_trait_impl {
180+
let headers = check_attrs(cx, &self.valid_idents, &item.attrs);
181+
if self.in_trait_impl {
172182
return;
173183
}
174-
// no safety header
175184
if let hir::ImplItemKind::Method(ref sig, ..) = item.kind {
176-
if cx.access_levels.is_exported(item.hir_id) && sig.header.unsafety == hir::Unsafety::Unsafe {
177-
span_lint(
178-
cx,
179-
MISSING_SAFETY_DOC,
180-
item.span,
181-
"unsafe function's docs miss `# Safety` section",
182-
);
183-
}
185+
lint_for_missing_headers(cx, item.hir_id, item.span, sig, headers);
184186
}
185187
}
186188
}
187189

190+
fn lint_for_missing_headers<'a, 'tcx>(
191+
cx: &LateContext<'a, 'tcx>,
192+
hir_id: hir::HirId,
193+
span: impl Into<MultiSpan> + Copy,
194+
sig: &hir::FnSig,
195+
headers: DocHeaders,
196+
) {
197+
if !cx.access_levels.is_exported(hir_id) {
198+
return; // Private functions do not require doc comments
199+
}
200+
if !headers.safety && sig.header.unsafety == hir::Unsafety::Unsafe {
201+
span_lint(
202+
cx,
203+
MISSING_SAFETY_DOC,
204+
span,
205+
"unsafe function's docs miss `# Safety` section",
206+
);
207+
}
208+
if !headers.errors && match_type(cx, return_ty(cx, hir_id), &paths::RESULT) {
209+
span_lint(
210+
cx,
211+
MISSING_ERRORS_DOC,
212+
span,
213+
"docs for function returning `Result` missing `# Errors` section",
214+
);
215+
}
216+
}
217+
188218
/// Cleanup documentation decoration (`///` and such).
189219
///
190220
/// We can't use `syntax::attr::AttributeMethods::with_desugared_doc` or
@@ -243,7 +273,13 @@ pub fn strip_doc_comment_decoration(comment: &str, span: Span) -> (String, Vec<(
243273
panic!("not a doc-comment: {}", comment);
244274
}
245275

246-
pub fn check_attrs<'a>(cx: &LateContext<'_, '_>, valid_idents: &FxHashSet<String>, attrs: &'a [Attribute]) -> bool {
276+
#[derive(Copy, Clone)]
277+
struct DocHeaders {
278+
safety: bool,
279+
errors: bool,
280+
}
281+
282+
fn check_attrs<'a>(cx: &LateContext<'_, '_>, valid_idents: &FxHashSet<String>, attrs: &'a [Attribute]) -> DocHeaders {
247283
let mut doc = String::new();
248284
let mut spans = vec![];
249285

@@ -255,7 +291,11 @@ pub fn check_attrs<'a>(cx: &LateContext<'_, '_>, valid_idents: &FxHashSet<String
255291
doc.push_str(&comment);
256292
} else if attr.check_name(sym!(doc)) {
257293
// ignore mix of sugared and non-sugared doc
258-
return true; // don't trigger the safety check
294+
// don't trigger the safety or errors check
295+
return DocHeaders {
296+
safety: true,
297+
errors: true,
298+
};
259299
}
260300
}
261301

@@ -267,7 +307,10 @@ pub fn check_attrs<'a>(cx: &LateContext<'_, '_>, valid_idents: &FxHashSet<String
267307
}
268308

269309
if doc.is_empty() {
270-
return false;
310+
return DocHeaders {
311+
safety: false,
312+
errors: false,
313+
};
271314
}
272315

273316
let parser = pulldown_cmark::Parser::new(&doc).into_offset_iter();
@@ -295,12 +338,15 @@ fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize
295338
valid_idents: &FxHashSet<String>,
296339
events: Events,
297340
spans: &[(usize, Span)],
298-
) -> bool {
341+
) -> DocHeaders {
299342
// true if a safety header was found
300343
use pulldown_cmark::Event::*;
301344
use pulldown_cmark::Tag::*;
302345

303-
let mut safety_header = false;
346+
let mut headers = DocHeaders {
347+
safety: false,
348+
errors: false,
349+
};
304350
let mut in_code = false;
305351
let mut in_link = None;
306352
let mut in_heading = false;
@@ -323,7 +369,8 @@ fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize
323369
// text "http://example.com" by pulldown-cmark
324370
continue;
325371
}
326-
safety_header |= in_heading && text.trim() == "Safety";
372+
headers.safety |= in_heading && text.trim() == "Safety";
373+
headers.errors |= in_heading && text.trim() == "Errors";
327374
let index = match spans.binary_search_by(|c| c.0.cmp(&range.start)) {
328375
Ok(o) => o,
329376
Err(e) => e - 1,
@@ -340,7 +387,7 @@ fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize
340387
},
341388
}
342389
}
343-
safety_header
390+
headers
344391
}
345392

346393
fn check_code(cx: &LateContext<'_, '_>, text: &str, span: Span) {

clippy_lints/src/functions.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -449,6 +449,7 @@ fn check_must_use_candidate<'a, 'tcx>(
449449
|| mutates_static(cx, body)
450450
|| in_external_macro(cx.sess(), item_span)
451451
|| returns_unit(decl)
452+
|| !cx.access_levels.is_exported(item_id)
452453
|| is_must_use_ty(cx, return_ty(cx, item_id))
453454
{
454455
return;

clippy_lints/src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,7 @@ pub fn register_plugins(store: &mut lint::LintStore, sess: &Session, conf: &Conf
488488
&derive::DERIVE_HASH_XOR_EQ,
489489
&derive::EXPL_IMPL_CLONE_ON_COPY,
490490
&doc::DOC_MARKDOWN,
491+
&doc::MISSING_ERRORS_DOC,
491492
&doc::MISSING_SAFETY_DOC,
492493
&doc::NEEDLESS_DOCTEST_MAIN,
493494
&double_comparison::DOUBLE_COMPARISONS,
@@ -734,6 +735,7 @@ pub fn register_plugins(store: &mut lint::LintStore, sess: &Session, conf: &Conf
734735
&trait_bounds::TYPE_REPETITION_IN_BOUNDS,
735736
&transmute::CROSSPOINTER_TRANSMUTE,
736737
&transmute::TRANSMUTE_BYTES_TO_STR,
738+
&transmute::TRANSMUTE_FLOAT_TO_INT,
737739
&transmute::TRANSMUTE_INT_TO_BOOL,
738740
&transmute::TRANSMUTE_INT_TO_CHAR,
739741
&transmute::TRANSMUTE_INT_TO_FLOAT,
@@ -1013,6 +1015,7 @@ pub fn register_plugins(store: &mut lint::LintStore, sess: &Session, conf: &Conf
10131015
LintId::of(&default_trait_access::DEFAULT_TRAIT_ACCESS),
10141016
LintId::of(&derive::EXPL_IMPL_CLONE_ON_COPY),
10151017
LintId::of(&doc::DOC_MARKDOWN),
1018+
LintId::of(&doc::MISSING_ERRORS_DOC),
10161019
LintId::of(&empty_enum::EMPTY_ENUM),
10171020
LintId::of(&enum_glob_use::ENUM_GLOB_USE),
10181021
LintId::of(&enum_variants::MODULE_NAME_REPETITIONS),
@@ -1584,6 +1587,7 @@ pub fn register_plugins(store: &mut lint::LintStore, sess: &Session, conf: &Conf
15841587
LintId::of(&mutex_atomic::MUTEX_INTEGER),
15851588
LintId::of(&needless_borrow::NEEDLESS_BORROW),
15861589
LintId::of(&path_buf_push_overwrite::PATH_BUF_PUSH_OVERWRITE),
1590+
LintId::of(&transmute::TRANSMUTE_FLOAT_TO_INT),
15871591
LintId::of(&use_self::USE_SELF),
15881592
]);
15891593
}

clippy_lints/src/strings.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use rustc::declare_lint_pass;
22
use rustc::hir::*;
3-
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
3+
use rustc::lint::{in_external_macro, LateContext, LateLintPass, LintArray, LintContext, LintPass};
44
use rustc_errors::Applicability;
55
use rustc_session::declare_tool_lint;
66
use syntax::source_map::Spanned;
@@ -80,6 +80,10 @@ declare_lint_pass!(StringAdd => [STRING_ADD, STRING_ADD_ASSIGN]);
8080

8181
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for StringAdd {
8282
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) {
83+
if in_external_macro(cx.sess(), e.span) {
84+
return;
85+
}
86+
8387
if let ExprKind::Binary(
8488
Spanned {
8589
node: BinOpKind::Add, ..

0 commit comments

Comments
 (0)