Skip to content

Commit

Permalink
Auto merge of #4553 - flip1995:rollup-0chhiy3, r=flip1995
Browse files Browse the repository at this point in the history
Rollup of 4 pull requests

Successful merges:

 - #4511 (New lint: mem_replace_with_uninit)
 - #4535 (New lint: Require `# Safety` section in pub unsafe fn docs)
 - #4539 (Changes cast-lossless to a pedantic lint)
 - #4544 (#4542 remove machine applicable suggestion)

Failed merges:

r? @ghost

changelog: none
  • Loading branch information
bors committed Sep 19, 2019
2 parents a5e568b + 25c4f84 commit f84e26d
Show file tree
Hide file tree
Showing 19 changed files with 328 additions and 68 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -1050,12 +1050,14 @@ Released 2018-09-13
[`mem_discriminant_non_enum`]: https://rust-lang.github.io/rust-clippy/master/index.html#mem_discriminant_non_enum
[`mem_forget`]: https://rust-lang.github.io/rust-clippy/master/index.html#mem_forget
[`mem_replace_option_with_none`]: https://rust-lang.github.io/rust-clippy/master/index.html#mem_replace_option_with_none
[`mem_replace_with_uninit`]: https://rust-lang.github.io/rust-clippy/master/index.html#mem_replace_with_uninit
[`min_max`]: https://rust-lang.github.io/rust-clippy/master/index.html#min_max
[`misaligned_transmute`]: https://rust-lang.github.io/rust-clippy/master/index.html#misaligned_transmute
[`misrefactored_assign_op`]: https://rust-lang.github.io/rust-clippy/master/index.html#misrefactored_assign_op
[`missing_const_for_fn`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_const_for_fn
[`missing_docs_in_private_items`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_docs_in_private_items
[`missing_inline_in_public_items`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_inline_in_public_items
[`missing_safety_doc`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_safety_doc
[`mistyped_literal_suffixes`]: https://rust-lang.github.io/rust-clippy/master/index.html#mistyped_literal_suffixes
[`mixed_case_hex_literals`]: https://rust-lang.github.io/rust-clippy/master/index.html#mixed_case_hex_literals
[`module_inception`]: https://rust-lang.github.io/rust-clippy/master/index.html#module_inception
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

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

[There are 313 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html)
[There are 314 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html)

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

Expand Down
2 changes: 1 addition & 1 deletion clippy_lints/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ semver = "0.9.0"
serde = { version = "1.0", features = ["derive"] }
toml = "0.5.3"
unicode-normalization = "0.1"
pulldown-cmark = "0.5.3"
pulldown-cmark = "0.6.0"
url = { version = "2.1.0", features = ["serde"] } # cargo requires serde feat in its url dep
# see https://github.com/rust-lang/rust/pull/63587#issuecomment-522343864
if_chain = "1.0.0"
Expand Down
111 changes: 83 additions & 28 deletions clippy_lints/src/doc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,40 @@ declare_clippy_lint! {
"presence of `_`, `::` or camel-case outside backticks in documentation"
}

declare_clippy_lint! {
/// **What it does:** Checks for the doc comments of publicly visible
/// unsafe functions and warns if there is no `# Safety` section.
///
/// **Why is this bad?** Unsafe functions should document their safety
/// preconditions, so that users can be sure they are using them safely.
///
/// **Known problems:** None.
///
/// **Examples**:
/// ```rust
///# type Universe = ();
/// /// This function should really be documented
/// pub unsafe fn start_apocalypse(u: &mut Universe) {
/// unimplemented!();
/// }
/// ```
///
/// At least write a line about safety:
///
/// ```rust
///# type Universe = ();
/// /// # Safety
/// ///
/// /// This function should not be called before the horsemen are ready.
/// pub unsafe fn start_apocalypse(u: &mut Universe) {
/// unimplemented!();
/// }
/// ```
pub MISSING_SAFETY_DOC,
style,
"`pub unsafe fn` without `# Safety` docs"
}

#[allow(clippy::module_name_repetitions)]
#[derive(Clone)]
pub struct DocMarkdown {
Expand All @@ -46,15 +80,28 @@ impl DocMarkdown {
}
}

impl_lint_pass!(DocMarkdown => [DOC_MARKDOWN]);
impl_lint_pass!(DocMarkdown => [DOC_MARKDOWN, MISSING_SAFETY_DOC]);

impl EarlyLintPass for DocMarkdown {
fn check_crate(&mut self, cx: &EarlyContext<'_>, krate: &ast::Crate) {
check_attrs(cx, &self.valid_idents, &krate.attrs);
}

fn check_item(&mut self, cx: &EarlyContext<'_>, item: &ast::Item) {
check_attrs(cx, &self.valid_idents, &item.attrs);
if check_attrs(cx, &self.valid_idents, &item.attrs) {
return;
}
// no safety header
if let ast::ItemKind::Fn(_, ref header, ..) = item.node {
if item.vis.node.is_pub() && header.unsafety == ast::Unsafety::Unsafe {
span_lint(
cx,
MISSING_SAFETY_DOC,
item.span,
"unsafe function's docs miss `# Safety` section",
);
}
}
}
}

Expand Down Expand Up @@ -115,7 +162,7 @@ pub fn strip_doc_comment_decoration(comment: &str, span: Span) -> (String, Vec<(
panic!("not a doc-comment: {}", comment);
}

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

Expand All @@ -129,7 +176,7 @@ pub fn check_attrs<'a>(cx: &EarlyContext<'_>, valid_idents: &FxHashSet<String>,
}
} else if attr.check_name(sym!(doc)) {
// ignore mix of sugared and non-sugared doc
return;
return true; // don't trigger the safety check
}
}

Expand All @@ -140,57 +187,64 @@ pub fn check_attrs<'a>(cx: &EarlyContext<'_>, valid_idents: &FxHashSet<String>,
current += offset_copy;
}

if !doc.is_empty() {
let parser = pulldown_cmark::Parser::new(&doc).into_offset_iter();
// Iterate over all `Events` and combine consecutive events into one
let events = parser.coalesce(|previous, current| {
use pulldown_cmark::Event::*;

let previous_range = previous.1;
let current_range = current.1;

match (previous.0, current.0) {
(Text(previous), Text(current)) => {
let mut previous = previous.to_string();
previous.push_str(&current);
Ok((Text(previous.into()), previous_range))
},
(previous, current) => Err(((previous, previous_range), (current, current_range))),
}
});
check_doc(cx, valid_idents, events, &spans);
if doc.is_empty() {
return false;
}

let parser = pulldown_cmark::Parser::new(&doc).into_offset_iter();
// Iterate over all `Events` and combine consecutive events into one
let events = parser.coalesce(|previous, current| {
use pulldown_cmark::Event::*;

let previous_range = previous.1;
let current_range = current.1;

match (previous.0, current.0) {
(Text(previous), Text(current)) => {
let mut previous = previous.to_string();
previous.push_str(&current);
Ok((Text(previous.into()), previous_range))
},
(previous, current) => Err(((previous, previous_range), (current, current_range))),
}
});
check_doc(cx, valid_idents, events, &spans)
}

fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize>)>>(
cx: &EarlyContext<'_>,
valid_idents: &FxHashSet<String>,
events: Events,
spans: &[(usize, Span)],
) {
) -> bool {
// true if a safety header was found
use pulldown_cmark::Event::*;
use pulldown_cmark::Tag::*;

let mut safety_header = false;
let mut in_code = false;
let mut in_link = None;
let mut in_heading = false;

for (event, range) in events {
match event {
Start(CodeBlock(_)) => in_code = true,
End(CodeBlock(_)) => in_code = false,
Start(Link(_, url, _)) => in_link = Some(url),
End(Link(..)) => in_link = None,
Start(_tag) | End(_tag) => (), // We don't care about other tags
Html(_html) | InlineHtml(_html) => (), // HTML is weird, just ignore it
SoftBreak | HardBreak | TaskListMarker(_) | Code(_) => (),
Start(Heading(_)) => in_heading = true,
End(Heading(_)) => in_heading = false,
Start(_tag) | End(_tag) => (), // We don't care about other tags
Html(_html) => (), // HTML is weird, just ignore it
SoftBreak | HardBreak | TaskListMarker(_) | Code(_) | Rule => (),
FootnoteReference(text) | Text(text) => {
if Some(&text) == in_link.as_ref() {
// Probably a link of the form `<http://example.com>`
// Which are represented as a link to "http://example.com" with
// text "http://example.com" by pulldown-cmark
continue;
}

safety_header |= in_heading && text.trim() == "Safety";
if !in_code {
let index = match spans.binary_search_by(|c| c.0.cmp(&range.start)) {
Ok(o) => o,
Expand All @@ -207,6 +261,7 @@ fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize
},
}
}
safety_header
}

fn check_text(cx: &EarlyContext<'_>, valid_idents: &FxHashSet<String>, text: &str, span: Span) {
Expand Down
3 changes: 2 additions & 1 deletion clippy_lints/src/explicit_write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,8 @@ fn write_output_string(write_args: &HirVec<Expr>) -> Option<String> {
if output_args.len() > 0;
if let ExprKind::AddrOf(_, ref output_string_expr) = output_args[0].node;
if let ExprKind::Array(ref string_exprs) = output_string_expr.node;
if string_exprs.len() > 0;
// we only want to provide an automatic suggestion for simple (non-format) strings
if string_exprs.len() == 1;
if let ExprKind::Lit(ref lit) = string_exprs[0].node;
if let LitKind::Str(ref write_output, _) = lit.node;
then {
Expand Down
7 changes: 5 additions & 2 deletions clippy_lints/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -667,6 +667,7 @@ pub fn register_plugins(reg: &mut rustc_driver::plugin::Registry<'_>, conf: &Con
shadow::SHADOW_UNRELATED,
strings::STRING_ADD_ASSIGN,
trait_bounds::TYPE_REPETITION_IN_BOUNDS,
types::CAST_LOSSLESS,
types::CAST_POSSIBLE_TRUNCATION,
types::CAST_POSSIBLE_WRAP,
types::CAST_PRECISION_LOSS,
Expand Down Expand Up @@ -708,6 +709,7 @@ pub fn register_plugins(reg: &mut rustc_driver::plugin::Registry<'_>, conf: &Con
copies::IFS_SAME_COND,
copies::IF_SAME_THEN_ELSE,
derive::DERIVE_HASH_XOR_EQ,
doc::MISSING_SAFETY_DOC,
double_comparison::DOUBLE_COMPARISONS,
double_parens::DOUBLE_PARENS,
drop_bounds::DROP_BOUNDS,
Expand Down Expand Up @@ -781,6 +783,7 @@ pub fn register_plugins(reg: &mut rustc_driver::plugin::Registry<'_>, conf: &Con
matches::SINGLE_MATCH,
mem_discriminant::MEM_DISCRIMINANT_NON_ENUM,
mem_replace::MEM_REPLACE_OPTION_WITH_NONE,
mem_replace::MEM_REPLACE_WITH_UNINIT,
methods::CHARS_LAST_CMP,
methods::CHARS_NEXT_CMP,
methods::CLONE_DOUBLE_REF,
Expand Down Expand Up @@ -890,7 +893,6 @@ pub fn register_plugins(reg: &mut rustc_driver::plugin::Registry<'_>, conf: &Con
types::ABSURD_EXTREME_COMPARISONS,
types::BORROWED_BOX,
types::BOX_VEC,
types::CAST_LOSSLESS,
types::CAST_PTR_ALIGNMENT,
types::CAST_REF_TO_MUT,
types::CHAR_LIT_AS_U8,
Expand Down Expand Up @@ -929,6 +931,7 @@ pub fn register_plugins(reg: &mut rustc_driver::plugin::Registry<'_>, conf: &Con
block_in_if_condition::BLOCK_IN_IF_CONDITION_EXPR,
block_in_if_condition::BLOCK_IN_IF_CONDITION_STMT,
collapsible_if::COLLAPSIBLE_IF,
doc::MISSING_SAFETY_DOC,
enum_variants::ENUM_VARIANT_NAMES,
enum_variants::MODULE_INCEPTION,
eq_op::OP_REF,
Expand Down Expand Up @@ -1072,7 +1075,6 @@ pub fn register_plugins(reg: &mut rustc_driver::plugin::Registry<'_>, conf: &Con
transmute::TRANSMUTE_PTR_TO_REF,
transmute::USELESS_TRANSMUTE,
types::BORROWED_BOX,
types::CAST_LOSSLESS,
types::CHAR_LIT_AS_U8,
types::OPTION_OPTION,
types::TYPE_COMPLEXITY,
Expand Down Expand Up @@ -1116,6 +1118,7 @@ pub fn register_plugins(reg: &mut rustc_driver::plugin::Registry<'_>, conf: &Con
loops::REVERSE_RANGE_LOOP,
loops::WHILE_IMMUTABLE_CONDITION,
mem_discriminant::MEM_DISCRIMINANT_NON_ENUM,
mem_replace::MEM_REPLACE_WITH_UNINIT,
methods::CLONE_DOUBLE_REF,
methods::INTO_ITER_ON_ARRAY,
methods::TEMPORARY_CSTRING_AS_PTR,
Expand Down
Loading

0 comments on commit f84e26d

Please sign in to comment.