mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-11-26 22:50:56 +00:00
Auto merge of #13091 - Alexendoo:empty-line-after-rewrite, r=dswij
Rewrite `empty_line_after_doc_comments` and `empty_line_after_outer_attr`, move them from `nursery` to `suspicious` changelog: [`empty_line_after_doc_comments`], [`empty_line_after_outer_attr`]: rewrite and move them from `nursery` to `suspicious` They now lint when there's a comment between the last attr/doc comment and the empty line, to cover the case: ```rust /// Docs for `old_code // fn old_code() {} fn new_code() {} ``` When these lints or `suspicious_doc_comments` trigger we no longer trigger any other doc lint as a broad fix for #12917, reverts some of #13002 as the empty line lints cover it I ended up not doing https://github.com/rust-lang/rust-clippy/issues/12917#issuecomment-2161828859 as I don't think it's needed
This commit is contained in:
commit
ebcd6bc785
73 changed files with 1563 additions and 872 deletions
|
@ -1,52 +0,0 @@
|
|||
use super::{EMPTY_LINE_AFTER_DOC_COMMENTS, EMPTY_LINE_AFTER_OUTER_ATTR};
|
||||
use clippy_utils::diagnostics::span_lint;
|
||||
use clippy_utils::source::{is_present_in_source, without_block_comments, SpanRangeExt};
|
||||
use rustc_ast::{AttrKind, AttrStyle};
|
||||
use rustc_lint::EarlyContext;
|
||||
use rustc_span::Span;
|
||||
|
||||
/// Check for empty lines after outer attributes.
|
||||
///
|
||||
/// Attributes and documentation comments are both considered outer attributes
|
||||
/// by the AST. However, the average user likely considers them to be different.
|
||||
/// Checking for empty lines after each of these attributes is split into two different
|
||||
/// lints but can share the same logic.
|
||||
pub(super) fn check(cx: &EarlyContext<'_>, item: &rustc_ast::Item) {
|
||||
let mut iter = item.attrs.iter().peekable();
|
||||
while let Some(attr) = iter.next() {
|
||||
if (matches!(attr.kind, AttrKind::Normal(..)) || matches!(attr.kind, AttrKind::DocComment(..)))
|
||||
&& attr.style == AttrStyle::Outer
|
||||
&& is_present_in_source(cx, attr.span)
|
||||
{
|
||||
let begin_of_attr_to_item = Span::new(attr.span.lo(), item.span.lo(), item.span.ctxt(), item.span.parent());
|
||||
let end_of_attr_to_next_attr_or_item = Span::new(
|
||||
attr.span.hi(),
|
||||
iter.peek().map_or(item.span.lo(), |next_attr| next_attr.span.lo()),
|
||||
item.span.ctxt(),
|
||||
item.span.parent(),
|
||||
);
|
||||
|
||||
if let Some(snippet) = end_of_attr_to_next_attr_or_item.get_source_text(cx) {
|
||||
let lines = snippet.split('\n').collect::<Vec<_>>();
|
||||
let lines = without_block_comments(lines);
|
||||
|
||||
if lines.iter().filter(|l| l.trim().is_empty()).count() > 2 {
|
||||
let (lint_msg, lint_type) = match attr.kind {
|
||||
AttrKind::DocComment(..) => (
|
||||
"found an empty line after a doc comment. \
|
||||
Perhaps you need to use `//!` to make a comment on a module, remove the empty line, or make a regular comment with `//`?",
|
||||
EMPTY_LINE_AFTER_DOC_COMMENTS,
|
||||
),
|
||||
AttrKind::Normal(..) => (
|
||||
"found an empty line after an outer attribute. \
|
||||
Perhaps you forgot to add a `!` to make it an inner attribute?",
|
||||
EMPTY_LINE_AFTER_OUTER_ATTR,
|
||||
),
|
||||
};
|
||||
|
||||
span_lint(cx, lint_type, begin_of_attr_to_item, lint_msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,7 +4,6 @@ mod blanket_clippy_restriction_lints;
|
|||
mod deprecated_cfg_attr;
|
||||
mod deprecated_semver;
|
||||
mod duplicated_attributes;
|
||||
mod empty_line_after;
|
||||
mod inline_always;
|
||||
mod mixed_attributes_style;
|
||||
mod non_minimal_cfg;
|
||||
|
@ -126,94 +125,6 @@ declare_clippy_lint! {
|
|||
"use of `#[deprecated(since = \"x\")]` where x is not semver"
|
||||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
/// Checks for empty lines after outer attributes
|
||||
///
|
||||
/// ### Why is this bad?
|
||||
/// Most likely the attribute was meant to be an inner attribute using a '!'.
|
||||
/// If it was meant to be an outer attribute, then the following item
|
||||
/// should not be separated by empty lines.
|
||||
///
|
||||
/// ### Known problems
|
||||
/// Can cause false positives.
|
||||
///
|
||||
/// From the clippy side it's difficult to detect empty lines between an attributes and the
|
||||
/// following item because empty lines and comments are not part of the AST. The parsing
|
||||
/// currently works for basic cases but is not perfect.
|
||||
///
|
||||
/// ### Example
|
||||
/// ```no_run
|
||||
/// #[allow(dead_code)]
|
||||
///
|
||||
/// fn not_quite_good_code() { }
|
||||
/// ```
|
||||
///
|
||||
/// Use instead:
|
||||
/// ```no_run
|
||||
/// // Good (as inner attribute)
|
||||
/// #![allow(dead_code)]
|
||||
///
|
||||
/// fn this_is_fine() { }
|
||||
///
|
||||
/// // or
|
||||
///
|
||||
/// // Good (as outer attribute)
|
||||
/// #[allow(dead_code)]
|
||||
/// fn this_is_fine_too() { }
|
||||
/// ```
|
||||
#[clippy::version = "pre 1.29.0"]
|
||||
pub EMPTY_LINE_AFTER_OUTER_ATTR,
|
||||
nursery,
|
||||
"empty line after outer attribute"
|
||||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
/// Checks for empty lines after documentation comments.
|
||||
///
|
||||
/// ### Why is this bad?
|
||||
/// The documentation comment was most likely meant to be an inner attribute or regular comment.
|
||||
/// If it was intended to be a documentation comment, then the empty line should be removed to
|
||||
/// be more idiomatic.
|
||||
///
|
||||
/// ### Known problems
|
||||
/// Only detects empty lines immediately following the documentation. If the doc comment is followed
|
||||
/// by an attribute and then an empty line, this lint will not trigger. Use `empty_line_after_outer_attr`
|
||||
/// in combination with this lint to detect both cases.
|
||||
///
|
||||
/// Does not detect empty lines after doc attributes (e.g. `#[doc = ""]`).
|
||||
///
|
||||
/// ### Example
|
||||
/// ```no_run
|
||||
/// /// Some doc comment with a blank line after it.
|
||||
///
|
||||
/// fn not_quite_good_code() { }
|
||||
/// ```
|
||||
///
|
||||
/// Use instead:
|
||||
/// ```no_run
|
||||
/// /// Good (no blank line)
|
||||
/// fn this_is_fine() { }
|
||||
/// ```
|
||||
///
|
||||
/// ```no_run
|
||||
/// // Good (convert to a regular comment)
|
||||
///
|
||||
/// fn this_is_fine_too() { }
|
||||
/// ```
|
||||
///
|
||||
/// ```no_run
|
||||
/// //! Good (convert to a comment on an inner attribute)
|
||||
///
|
||||
/// fn this_is_fine_as_well() { }
|
||||
/// ```
|
||||
#[clippy::version = "1.70.0"]
|
||||
pub EMPTY_LINE_AFTER_DOC_COMMENTS,
|
||||
nursery,
|
||||
"empty line after documentation comments"
|
||||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
/// Checks for `warn`/`deny`/`forbid` attributes targeting the whole clippy::restriction category.
|
||||
|
@ -601,18 +512,12 @@ impl EarlyAttributes {
|
|||
|
||||
impl_lint_pass!(EarlyAttributes => [
|
||||
DEPRECATED_CFG_ATTR,
|
||||
EMPTY_LINE_AFTER_OUTER_ATTR,
|
||||
EMPTY_LINE_AFTER_DOC_COMMENTS,
|
||||
NON_MINIMAL_CFG,
|
||||
DEPRECATED_CLIPPY_CFG_ATTR,
|
||||
UNNECESSARY_CLIPPY_CFG,
|
||||
]);
|
||||
|
||||
impl EarlyLintPass for EarlyAttributes {
|
||||
fn check_item(&mut self, cx: &EarlyContext<'_>, item: &rustc_ast::Item) {
|
||||
empty_line_after::check(cx, item);
|
||||
}
|
||||
|
||||
fn check_attribute(&mut self, cx: &EarlyContext<'_>, attr: &Attribute) {
|
||||
deprecated_cfg_attr::check(cx, attr, &self.msrv);
|
||||
deprecated_cfg_attr::check_clippy(cx, attr);
|
||||
|
|
|
@ -49,8 +49,6 @@ pub static LINTS: &[&crate::LintInfo] = &[
|
|||
crate::attrs::DEPRECATED_CLIPPY_CFG_ATTR_INFO,
|
||||
crate::attrs::DEPRECATED_SEMVER_INFO,
|
||||
crate::attrs::DUPLICATED_ATTRIBUTES_INFO,
|
||||
crate::attrs::EMPTY_LINE_AFTER_DOC_COMMENTS_INFO,
|
||||
crate::attrs::EMPTY_LINE_AFTER_OUTER_ATTR_INFO,
|
||||
crate::attrs::INLINE_ALWAYS_INFO,
|
||||
crate::attrs::MIXED_ATTRIBUTES_STYLE_INFO,
|
||||
crate::attrs::NON_MINIMAL_CFG_INFO,
|
||||
|
@ -138,6 +136,8 @@ pub static LINTS: &[&crate::LintInfo] = &[
|
|||
crate::doc::DOC_LINK_WITH_QUOTES_INFO,
|
||||
crate::doc::DOC_MARKDOWN_INFO,
|
||||
crate::doc::EMPTY_DOCS_INFO,
|
||||
crate::doc::EMPTY_LINE_AFTER_DOC_COMMENTS_INFO,
|
||||
crate::doc::EMPTY_LINE_AFTER_OUTER_ATTR_INFO,
|
||||
crate::doc::MISSING_ERRORS_DOC_INFO,
|
||||
crate::doc::MISSING_PANICS_DOC_INFO,
|
||||
crate::doc::MISSING_SAFETY_DOC_INFO,
|
||||
|
|
329
clippy_lints/src/doc/empty_line_after.rs
Normal file
329
clippy_lints/src/doc/empty_line_after.rs
Normal file
|
@ -0,0 +1,329 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::source::{snippet_indent, SpanRangeExt};
|
||||
use clippy_utils::tokenize_with_text;
|
||||
use itertools::Itertools;
|
||||
use rustc_ast::token::CommentKind;
|
||||
use rustc_ast::{AttrKind, AttrStyle, Attribute};
|
||||
use rustc_errors::{Applicability, Diag, SuggestionStyle};
|
||||
use rustc_hir::{ItemKind, Node};
|
||||
use rustc_lexer::TokenKind;
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_span::{ExpnKind, InnerSpan, Span, SpanData};
|
||||
|
||||
use super::{EMPTY_LINE_AFTER_DOC_COMMENTS, EMPTY_LINE_AFTER_OUTER_ATTR};
|
||||
|
||||
#[derive(Debug, PartialEq, Clone, Copy)]
|
||||
enum StopKind {
|
||||
Attr,
|
||||
Doc(CommentKind),
|
||||
}
|
||||
|
||||
impl StopKind {
|
||||
fn is_doc(self) -> bool {
|
||||
matches!(self, StopKind::Doc(_))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Stop {
|
||||
span: Span,
|
||||
kind: StopKind,
|
||||
first: usize,
|
||||
last: usize,
|
||||
}
|
||||
|
||||
impl Stop {
|
||||
fn convert_to_inner(&self) -> (Span, String) {
|
||||
let inner = match self.kind {
|
||||
// #|[...]
|
||||
StopKind::Attr => InnerSpan::new(1, 1),
|
||||
// /// or /**
|
||||
// ^ ^
|
||||
StopKind::Doc(_) => InnerSpan::new(2, 3),
|
||||
};
|
||||
(self.span.from_inner(inner), "!".into())
|
||||
}
|
||||
|
||||
fn comment_out(&self, cx: &LateContext<'_>, suggestions: &mut Vec<(Span, String)>) {
|
||||
match self.kind {
|
||||
StopKind::Attr => {
|
||||
if cx.tcx.sess.source_map().is_multiline(self.span) {
|
||||
suggestions.extend([
|
||||
(self.span.shrink_to_lo(), "/* ".into()),
|
||||
(self.span.shrink_to_hi(), " */".into()),
|
||||
]);
|
||||
} else {
|
||||
suggestions.push((self.span.shrink_to_lo(), "// ".into()));
|
||||
}
|
||||
},
|
||||
StopKind::Doc(CommentKind::Line) => suggestions.push((self.span.shrink_to_lo(), "// ".into())),
|
||||
StopKind::Doc(CommentKind::Block) => {
|
||||
// /** outer */ /*! inner */
|
||||
// ^ ^
|
||||
let asterisk = self.span.from_inner(InnerSpan::new(1, 2));
|
||||
suggestions.push((asterisk, String::new()));
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn from_attr(cx: &LateContext<'_>, attr: &Attribute) -> Option<Self> {
|
||||
let SpanData { lo, hi, .. } = attr.span.data();
|
||||
let file = cx.tcx.sess.source_map().lookup_source_file(lo);
|
||||
|
||||
Some(Self {
|
||||
span: attr.span,
|
||||
kind: match attr.kind {
|
||||
AttrKind::Normal(_) => StopKind::Attr,
|
||||
AttrKind::DocComment(comment_kind, _) => StopKind::Doc(comment_kind),
|
||||
},
|
||||
first: file.lookup_line(file.relative_position(lo))?,
|
||||
last: file.lookup_line(file.relative_position(hi))?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents a set of attrs/doc comments separated by 1 or more empty lines
|
||||
///
|
||||
/// ```ignore
|
||||
/// /// chunk 1 docs
|
||||
/// // not an empty line so also part of chunk 1
|
||||
/// #[chunk_1_attrs] // <-- prev_stop
|
||||
///
|
||||
/// /* gap */
|
||||
///
|
||||
/// /// chunk 2 docs // <-- next_stop
|
||||
/// #[chunk_2_attrs]
|
||||
/// ```
|
||||
struct Gap<'a> {
|
||||
/// The span of individual empty lines including the newline at the end of the line
|
||||
empty_lines: Vec<Span>,
|
||||
has_comment: bool,
|
||||
next_stop: &'a Stop,
|
||||
prev_stop: &'a Stop,
|
||||
/// The chunk that includes [`prev_stop`](Self::prev_stop)
|
||||
prev_chunk: &'a [Stop],
|
||||
}
|
||||
|
||||
impl<'a> Gap<'a> {
|
||||
fn new(cx: &LateContext<'_>, prev_chunk: &'a [Stop], next_chunk: &'a [Stop]) -> Option<Self> {
|
||||
let prev_stop = prev_chunk.last()?;
|
||||
let next_stop = next_chunk.first()?;
|
||||
let gap_span = prev_stop.span.between(next_stop.span);
|
||||
let gap_snippet = gap_span.get_source_text(cx)?;
|
||||
|
||||
let mut has_comment = false;
|
||||
let mut empty_lines = Vec::new();
|
||||
|
||||
for (token, source, inner_span) in tokenize_with_text(&gap_snippet) {
|
||||
match token {
|
||||
TokenKind::BlockComment {
|
||||
doc_style: None,
|
||||
terminated: true,
|
||||
}
|
||||
| TokenKind::LineComment { doc_style: None } => has_comment = true,
|
||||
TokenKind::Whitespace => {
|
||||
let newlines = source.bytes().positions(|b| b == b'\n');
|
||||
empty_lines.extend(
|
||||
newlines
|
||||
.tuple_windows()
|
||||
.map(|(a, b)| InnerSpan::new(inner_span.start + a + 1, inner_span.start + b))
|
||||
.map(|inner_span| gap_span.from_inner(inner_span)),
|
||||
);
|
||||
},
|
||||
// Ignore cfg_attr'd out attributes as they may contain empty lines, could also be from macro
|
||||
// shenanigans
|
||||
_ => return None,
|
||||
}
|
||||
}
|
||||
|
||||
(!empty_lines.is_empty()).then_some(Self {
|
||||
empty_lines,
|
||||
has_comment,
|
||||
next_stop,
|
||||
prev_stop,
|
||||
prev_chunk,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// If the node the attributes/docs apply to is the first in the module/crate suggest converting
|
||||
/// them to inner attributes/docs
|
||||
fn suggest_inner(cx: &LateContext<'_>, diag: &mut Diag<'_, ()>, kind: StopKind, gaps: &[Gap<'_>]) {
|
||||
let Some(owner) = cx.last_node_with_lint_attrs.as_owner() else {
|
||||
return;
|
||||
};
|
||||
let parent_desc = match cx.tcx.parent_hir_node(owner.into()) {
|
||||
Node::Item(item)
|
||||
if let ItemKind::Mod(parent_mod) = item.kind
|
||||
&& let [first, ..] = parent_mod.item_ids
|
||||
&& first.owner_id == owner =>
|
||||
{
|
||||
"parent module"
|
||||
},
|
||||
Node::Crate(crate_mod)
|
||||
if let Some(first) = crate_mod
|
||||
.item_ids
|
||||
.iter()
|
||||
.map(|&id| cx.tcx.hir().item(id))
|
||||
// skip prelude imports
|
||||
.find(|item| !matches!(item.span.ctxt().outer_expn_data().kind, ExpnKind::AstPass(_)))
|
||||
&& first.owner_id == owner =>
|
||||
{
|
||||
"crate"
|
||||
},
|
||||
_ => return,
|
||||
};
|
||||
|
||||
diag.multipart_suggestion_verbose(
|
||||
match kind {
|
||||
StopKind::Attr => format!("if the attribute should apply to the {parent_desc} use an inner attribute"),
|
||||
StopKind::Doc(_) => format!("if the comment should document the {parent_desc} use an inner doc comment"),
|
||||
},
|
||||
gaps.iter()
|
||||
.flat_map(|gap| gap.prev_chunk)
|
||||
.map(Stop::convert_to_inner)
|
||||
.collect(),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
|
||||
fn check_gaps(cx: &LateContext<'_>, gaps: &[Gap<'_>]) -> bool {
|
||||
let Some(first_gap) = gaps.first() else {
|
||||
return false;
|
||||
};
|
||||
let empty_lines = || gaps.iter().flat_map(|gap| gap.empty_lines.iter().copied());
|
||||
let mut has_comment = false;
|
||||
let mut has_attr = false;
|
||||
for gap in gaps {
|
||||
has_comment |= gap.has_comment;
|
||||
if !has_attr {
|
||||
has_attr = gap.prev_chunk.iter().any(|stop| stop.kind == StopKind::Attr);
|
||||
}
|
||||
}
|
||||
let kind = first_gap.prev_stop.kind;
|
||||
let (lint, kind_desc) = match kind {
|
||||
StopKind::Attr => (EMPTY_LINE_AFTER_OUTER_ATTR, "outer attribute"),
|
||||
StopKind::Doc(_) => (EMPTY_LINE_AFTER_DOC_COMMENTS, "doc comment"),
|
||||
};
|
||||
let (lines, are, them) = if empty_lines().nth(1).is_some() {
|
||||
("lines", "are", "them")
|
||||
} else {
|
||||
("line", "is", "it")
|
||||
};
|
||||
span_lint_and_then(
|
||||
cx,
|
||||
lint,
|
||||
first_gap.prev_stop.span.to(empty_lines().last().unwrap()),
|
||||
format!("empty {lines} after {kind_desc}"),
|
||||
|diag| {
|
||||
if let Some(owner) = cx.last_node_with_lint_attrs.as_owner() {
|
||||
let def_id = owner.to_def_id();
|
||||
let def_descr = cx.tcx.def_descr(def_id);
|
||||
diag.span_label(
|
||||
cx.tcx.def_span(def_id),
|
||||
match kind {
|
||||
StopKind::Attr => format!("the attribute applies to this {def_descr}"),
|
||||
StopKind::Doc(_) => format!("the comment documents this {def_descr}"),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
diag.multipart_suggestion_with_style(
|
||||
format!("if the empty {lines} {are} unintentional remove {them}"),
|
||||
empty_lines().map(|empty_line| (empty_line, String::new())).collect(),
|
||||
Applicability::MaybeIncorrect,
|
||||
SuggestionStyle::HideCodeAlways,
|
||||
);
|
||||
|
||||
if has_comment && kind.is_doc() {
|
||||
// Likely doc comments that applied to some now commented out code
|
||||
//
|
||||
// /// Old docs for Foo
|
||||
// // struct Foo;
|
||||
|
||||
let mut suggestions = Vec::new();
|
||||
for stop in gaps.iter().flat_map(|gap| gap.prev_chunk) {
|
||||
stop.comment_out(cx, &mut suggestions);
|
||||
}
|
||||
let name = match cx.tcx.hir().opt_name(cx.last_node_with_lint_attrs) {
|
||||
Some(name) => format!("`{name}`"),
|
||||
None => "this".into(),
|
||||
};
|
||||
diag.multipart_suggestion_verbose(
|
||||
format!("if the doc comment should not document {name} comment it out"),
|
||||
suggestions,
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
} else {
|
||||
suggest_inner(cx, diag, kind, gaps);
|
||||
}
|
||||
|
||||
if kind == StopKind::Doc(CommentKind::Line)
|
||||
&& gaps
|
||||
.iter()
|
||||
.all(|gap| !gap.has_comment && gap.next_stop.kind == StopKind::Doc(CommentKind::Line))
|
||||
{
|
||||
// Commentless empty gaps between line doc comments, possibly intended to be part of the markdown
|
||||
|
||||
let indent = snippet_indent(cx, first_gap.prev_stop.span).unwrap_or_default();
|
||||
diag.multipart_suggestion_verbose(
|
||||
format!("if the documentation should include the empty {lines} include {them} in the comment"),
|
||||
empty_lines()
|
||||
.map(|empty_line| (empty_line, format!("{indent}///")))
|
||||
.collect(),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
kind.is_doc()
|
||||
}
|
||||
|
||||
/// Returns `true` if [`EMPTY_LINE_AFTER_DOC_COMMENTS`] triggered, used to skip other doc comment
|
||||
/// lints where they would be confusing
|
||||
///
|
||||
/// [`EMPTY_LINE_AFTER_OUTER_ATTR`] is also here to share an implementation but does not return
|
||||
/// `true` if it triggers
|
||||
pub(super) fn check(cx: &LateContext<'_>, attrs: &[Attribute]) -> bool {
|
||||
let mut outer = attrs
|
||||
.iter()
|
||||
.filter(|attr| attr.style == AttrStyle::Outer && !attr.span.from_expansion())
|
||||
.map(|attr| Stop::from_attr(cx, attr))
|
||||
.collect::<Option<Vec<_>>>()
|
||||
.unwrap_or_default();
|
||||
|
||||
if outer.is_empty() {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Push a fake attribute Stop for the item itself so we check for gaps between the last outer
|
||||
// attr/doc comment and the item they apply to
|
||||
let span = cx.tcx.hir().span(cx.last_node_with_lint_attrs);
|
||||
if !span.from_expansion()
|
||||
&& let Ok(line) = cx.tcx.sess.source_map().lookup_line(span.lo())
|
||||
{
|
||||
outer.push(Stop {
|
||||
span,
|
||||
kind: StopKind::Attr,
|
||||
first: line.line,
|
||||
// last doesn't need to be accurate here, we don't compare it with anything
|
||||
last: line.line,
|
||||
});
|
||||
}
|
||||
|
||||
let mut gaps = Vec::new();
|
||||
let mut last = 0;
|
||||
for pos in outer
|
||||
.array_windows()
|
||||
.positions(|[a, b]| b.first.saturating_sub(a.last) > 1)
|
||||
{
|
||||
// we want to be after the first stop in the window
|
||||
let pos = pos + 1;
|
||||
if let Some(gap) = Gap::new(cx, &outer[last..pos], &outer[pos..]) {
|
||||
last = pos;
|
||||
gaps.push(gap);
|
||||
}
|
||||
}
|
||||
|
||||
check_gaps(cx, &gaps)
|
||||
}
|
|
@ -22,7 +22,6 @@ pub(super) fn check(
|
|||
range: Range<usize>,
|
||||
mut span: Span,
|
||||
containers: &[super::Container],
|
||||
line_break_span: Span,
|
||||
) {
|
||||
if doc[range.clone()].contains('\t') {
|
||||
// We don't do tab stops correctly.
|
||||
|
@ -52,29 +51,6 @@ pub(super) fn check(
|
|||
"doc list item without indentation"
|
||||
};
|
||||
span_lint_and_then(cx, DOC_LAZY_CONTINUATION, span, msg, |diag| {
|
||||
let snippet = clippy_utils::source::snippet(cx, line_break_span, "");
|
||||
if snippet.chars().filter(|&c| c == '\n').count() > 1
|
||||
&& let Some(doc_comment_start) = snippet.rfind('\n')
|
||||
&& let doc_comment = snippet[doc_comment_start..].trim()
|
||||
&& (doc_comment == "///" || doc_comment == "//!")
|
||||
{
|
||||
// suggest filling in a blank line
|
||||
diag.span_suggestion_verbose(
|
||||
line_break_span.shrink_to_lo(),
|
||||
"if this should be its own paragraph, add a blank doc comment line",
|
||||
format!("\n{doc_comment}"),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
if ccount > 0 || blockquote_level > 0 {
|
||||
diag.help("if this not intended to be a quote at all, escape it with `\\>`");
|
||||
} else {
|
||||
let indent = list_indentation - lcount;
|
||||
diag.help(format!(
|
||||
"if this is intended to be part of the list, indent {indent} spaces"
|
||||
));
|
||||
}
|
||||
return;
|
||||
}
|
||||
if ccount == 0 && blockquote_level == 0 {
|
||||
// simpler suggestion style for indentation
|
||||
let indent = list_indentation - lcount;
|
||||
|
|
|
@ -32,6 +32,7 @@ use rustc_span::{sym, Span};
|
|||
use std::ops::Range;
|
||||
use url::Url;
|
||||
|
||||
mod empty_line_after;
|
||||
mod link_with_quotes;
|
||||
mod markdown;
|
||||
mod missing_headers;
|
||||
|
@ -455,7 +456,82 @@ declare_clippy_lint! {
|
|||
"ensure that the first line of a documentation paragraph isn't too long"
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
/// Checks for empty lines after outer attributes
|
||||
///
|
||||
/// ### Why is this bad?
|
||||
/// The attribute may have meant to be an inner attribute (`#![attr]`). If
|
||||
/// it was meant to be an outer attribute (`#[attr]`) then the empty line
|
||||
/// should be removed
|
||||
///
|
||||
/// ### Example
|
||||
/// ```no_run
|
||||
/// #[allow(dead_code)]
|
||||
///
|
||||
/// fn not_quite_good_code() {}
|
||||
/// ```
|
||||
///
|
||||
/// Use instead:
|
||||
/// ```no_run
|
||||
/// // Good (as inner attribute)
|
||||
/// #![allow(dead_code)]
|
||||
///
|
||||
/// fn this_is_fine() {}
|
||||
///
|
||||
/// // or
|
||||
///
|
||||
/// // Good (as outer attribute)
|
||||
/// #[allow(dead_code)]
|
||||
/// fn this_is_fine_too() {}
|
||||
/// ```
|
||||
#[clippy::version = "pre 1.29.0"]
|
||||
pub EMPTY_LINE_AFTER_OUTER_ATTR,
|
||||
suspicious,
|
||||
"empty line after outer attribute"
|
||||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
/// Checks for empty lines after doc comments.
|
||||
///
|
||||
/// ### Why is this bad?
|
||||
/// The doc comment may have meant to be an inner doc comment, regular
|
||||
/// comment or applied to some old code that is now commented out. If it was
|
||||
/// intended to be a doc comment, then the empty line should be removed.
|
||||
///
|
||||
/// ### Example
|
||||
/// ```no_run
|
||||
/// /// Some doc comment with a blank line after it.
|
||||
///
|
||||
/// fn f() {}
|
||||
///
|
||||
/// /// Docs for `old_code`
|
||||
/// // fn old_code() {}
|
||||
///
|
||||
/// fn new_code() {}
|
||||
/// ```
|
||||
///
|
||||
/// Use instead:
|
||||
/// ```no_run
|
||||
/// //! Convert it to an inner doc comment
|
||||
///
|
||||
/// // Or a regular comment
|
||||
///
|
||||
/// /// Or remove the empty line
|
||||
/// fn f() {}
|
||||
///
|
||||
/// // /// Docs for `old_code`
|
||||
/// // fn old_code() {}
|
||||
///
|
||||
/// fn new_code() {}
|
||||
/// ```
|
||||
#[clippy::version = "1.70.0"]
|
||||
pub EMPTY_LINE_AFTER_DOC_COMMENTS,
|
||||
suspicious,
|
||||
"empty line after doc comments"
|
||||
}
|
||||
|
||||
pub struct Documentation {
|
||||
valid_idents: FxHashSet<String>,
|
||||
check_private_items: bool,
|
||||
|
@ -482,6 +558,8 @@ impl_lint_pass!(Documentation => [
|
|||
SUSPICIOUS_DOC_COMMENTS,
|
||||
EMPTY_DOCS,
|
||||
DOC_LAZY_CONTINUATION,
|
||||
EMPTY_LINE_AFTER_OUTER_ATTR,
|
||||
EMPTY_LINE_AFTER_DOC_COMMENTS,
|
||||
TOO_LONG_FIRST_DOC_PARAGRAPH,
|
||||
]);
|
||||
|
||||
|
@ -612,12 +690,10 @@ fn check_attrs(cx: &LateContext<'_>, valid_idents: &FxHashSet<String>, attrs: &[
|
|||
Some(("fake".into(), "fake".into()))
|
||||
}
|
||||
|
||||
if is_doc_hidden(attrs) {
|
||||
if suspicious_doc_comments::check(cx, attrs) || empty_line_after::check(cx, attrs) || is_doc_hidden(attrs) {
|
||||
return None;
|
||||
}
|
||||
|
||||
suspicious_doc_comments::check(cx, attrs);
|
||||
|
||||
let (fragments, _) = attrs_to_doc_fragments(
|
||||
attrs.iter().filter_map(|attr| {
|
||||
if in_external_macro(cx.sess(), attr.span) {
|
||||
|
@ -816,7 +892,6 @@ fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize
|
|||
range.end..next_range.start,
|
||||
Span::new(span.hi(), next_span.lo(), span.ctxt(), span.parent()),
|
||||
&containers[..],
|
||||
span,
|
||||
);
|
||||
}
|
||||
},
|
||||
|
|
|
@ -7,7 +7,7 @@ use rustc_span::Span;
|
|||
|
||||
use super::SUSPICIOUS_DOC_COMMENTS;
|
||||
|
||||
pub fn check(cx: &LateContext<'_>, attrs: &[Attribute]) {
|
||||
pub fn check(cx: &LateContext<'_>, attrs: &[Attribute]) -> bool {
|
||||
let replacements: Vec<_> = collect_doc_replacements(attrs);
|
||||
|
||||
if let Some((&(lo_span, _), &(hi_span, _))) = replacements.first().zip(replacements.last()) {
|
||||
|
@ -24,6 +24,10 @@ pub fn check(cx: &LateContext<'_>, attrs: &[Attribute]) {
|
|||
);
|
||||
},
|
||||
);
|
||||
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,6 @@ use rustc_span::sym;
|
|||
/// - `hashmap.into_iter().map(|(_, v)| v)`
|
||||
///
|
||||
/// on `HashMaps` and `BTreeMaps` in std
|
||||
|
||||
pub(super) fn check<'tcx>(
|
||||
cx: &LateContext<'tcx>,
|
||||
map_type: &'tcx str, // iter / into_iter
|
||||
|
|
|
@ -183,15 +183,15 @@ pub fn span_contains_cfg(cx: &LateContext<'_>, s: Span) -> bool {
|
|||
let mut iter = tokenize_with_text(src);
|
||||
|
||||
// Search for the token sequence [`#`, `[`, `cfg`]
|
||||
while iter.any(|(t, _)| matches!(t, TokenKind::Pound)) {
|
||||
let mut iter = iter.by_ref().skip_while(|(t, _)| {
|
||||
while iter.any(|(t, ..)| matches!(t, TokenKind::Pound)) {
|
||||
let mut iter = iter.by_ref().skip_while(|(t, ..)| {
|
||||
matches!(
|
||||
t,
|
||||
TokenKind::Whitespace | TokenKind::LineComment { .. } | TokenKind::BlockComment { .. }
|
||||
)
|
||||
});
|
||||
if matches!(iter.next(), Some((TokenKind::OpenBracket, _)))
|
||||
&& matches!(iter.next(), Some((TokenKind::Ident, "cfg")))
|
||||
if matches!(iter.next(), Some((TokenKind::OpenBracket, ..)))
|
||||
&& matches!(iter.next(), Some((TokenKind::Ident, "cfg", _)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1194,8 +1194,8 @@ fn eq_span_tokens(
|
|||
&& let Some(rsrc) = right.get_source_range(cx)
|
||||
&& let Some(rsrc) = rsrc.as_str()
|
||||
{
|
||||
let pred = |t: &(_, _)| pred(t.0);
|
||||
let map = |(_, x)| x;
|
||||
let pred = |&(token, ..): &(TokenKind, _, _)| pred(token);
|
||||
let map = |(_, source, _)| source;
|
||||
|
||||
let ltok = tokenize_with_text(lsrc).filter(pred).map(map);
|
||||
let rtok = tokenize_with_text(rsrc).filter(pred).map(map);
|
||||
|
|
|
@ -121,7 +121,7 @@ use rustc_middle::ty::{
|
|||
use rustc_span::hygiene::{ExpnKind, MacroKind};
|
||||
use rustc_span::source_map::SourceMap;
|
||||
use rustc_span::symbol::{kw, Ident, Symbol};
|
||||
use rustc_span::{sym, Span};
|
||||
use rustc_span::{sym, InnerSpan, Span};
|
||||
use rustc_target::abi::Integer;
|
||||
use visitors::Visitable;
|
||||
|
||||
|
@ -2950,13 +2950,14 @@ pub fn expr_use_ctxt<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'tcx>) -> ExprU
|
|||
}
|
||||
|
||||
/// Tokenizes the input while keeping the text associated with each token.
|
||||
pub fn tokenize_with_text(s: &str) -> impl Iterator<Item = (TokenKind, &str)> {
|
||||
pub fn tokenize_with_text(s: &str) -> impl Iterator<Item = (TokenKind, &str, InnerSpan)> {
|
||||
let mut pos = 0;
|
||||
tokenize(s).map(move |t| {
|
||||
let end = pos + t.len;
|
||||
let range = pos as usize..end as usize;
|
||||
let inner = InnerSpan::new(range.start, range.end);
|
||||
pos = end;
|
||||
(t.kind, s.get(range).unwrap_or_default())
|
||||
(t.kind, s.get(range).unwrap_or_default(), inner)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -2980,8 +2981,8 @@ pub fn span_contains_comment(sm: &SourceMap, span: Span) -> bool {
|
|||
pub fn span_extract_comment(sm: &SourceMap, span: Span) -> String {
|
||||
let snippet = sm.span_to_snippet(span).unwrap_or_default();
|
||||
let res = tokenize_with_text(&snippet)
|
||||
.filter(|(t, _)| matches!(t, TokenKind::BlockComment { .. } | TokenKind::LineComment { .. }))
|
||||
.map(|(_, s)| s)
|
||||
.filter(|(t, ..)| matches!(t, TokenKind::BlockComment { .. } | TokenKind::LineComment { .. }))
|
||||
.map(|(_, s, _)| s)
|
||||
.join("\n");
|
||||
res
|
||||
}
|
||||
|
@ -3001,7 +3002,7 @@ pub fn span_find_starting_semi(sm: &SourceMap, span: Span) -> Span {
|
|||
/// pat: Some(a)
|
||||
/// else_body: return None
|
||||
/// ```
|
||||
|
||||
///
|
||||
/// And for this example:
|
||||
/// ```ignore
|
||||
/// let Some(FooBar { a, b }) = ex else { return None };
|
||||
|
@ -3011,7 +3012,7 @@ pub fn span_find_starting_semi(sm: &SourceMap, span: Span) -> Span {
|
|||
/// pat: Some(FooBar { a, b })
|
||||
/// else_body: return None
|
||||
/// ```
|
||||
|
||||
///
|
||||
/// We output `Some(a)` in the first instance, and `Some(FooBar { a, b })` in the second, because
|
||||
/// the question mark operator is applicable here. Callers have to check whether we are in a
|
||||
/// constant or not.
|
||||
|
|
|
@ -666,39 +666,6 @@ pub fn walk_span_to_context(span: Span, outer: SyntaxContext) -> Option<Span> {
|
|||
(outer_span.ctxt() == outer).then_some(outer_span)
|
||||
}
|
||||
|
||||
/// Removes block comments from the given `Vec` of lines.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust,ignore
|
||||
/// without_block_comments(vec!["/*", "foo", "*/"]);
|
||||
/// // => vec![]
|
||||
///
|
||||
/// without_block_comments(vec!["bar", "/*", "foo", "*/"]);
|
||||
/// // => vec!["bar"]
|
||||
/// ```
|
||||
pub fn without_block_comments(lines: Vec<&str>) -> Vec<&str> {
|
||||
let mut without = vec![];
|
||||
|
||||
let mut nest_level = 0;
|
||||
|
||||
for line in lines {
|
||||
if line.contains("/*") {
|
||||
nest_level += 1;
|
||||
continue;
|
||||
} else if line.contains("*/") {
|
||||
nest_level -= 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if nest_level == 0 {
|
||||
without.push(line);
|
||||
}
|
||||
}
|
||||
|
||||
without
|
||||
}
|
||||
|
||||
/// Trims the whitespace from the start and the end of the span.
|
||||
pub fn trim_span(sm: &SourceMap, span: Span) -> Span {
|
||||
let data = span.data();
|
||||
|
@ -776,7 +743,7 @@ pub fn str_literal_to_char_literal(
|
|||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::{reindent_multiline, without_block_comments};
|
||||
use super::reindent_multiline;
|
||||
|
||||
#[test]
|
||||
fn test_reindent_multiline_single_line() {
|
||||
|
@ -844,29 +811,4 @@ mod test {
|
|||
z
|
||||
}".into(), true, Some(8)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_without_block_comments_lines_without_block_comments() {
|
||||
let result = without_block_comments(vec!["/*", "", "*/"]);
|
||||
println!("result: {result:?}");
|
||||
assert!(result.is_empty());
|
||||
|
||||
let result = without_block_comments(vec!["", "/*", "", "*/", "#[crate_type = \"lib\"]", "/*", "", "*/", ""]);
|
||||
assert_eq!(result, vec!["", "#[crate_type = \"lib\"]", ""]);
|
||||
|
||||
let result = without_block_comments(vec!["/* rust", "", "*/"]);
|
||||
assert!(result.is_empty());
|
||||
|
||||
let result = without_block_comments(vec!["/* one-line comment */"]);
|
||||
assert!(result.is_empty());
|
||||
|
||||
let result = without_block_comments(vec!["/* nested", "/* multi-line", "comment", "*/", "test", "*/"]);
|
||||
assert!(result.is_empty());
|
||||
|
||||
let result = without_block_comments(vec!["/* nested /* inline /* comment */ test */ */"]);
|
||||
assert!(result.is_empty());
|
||||
|
||||
let result = without_block_comments(vec!["foo", "bar", "baz"]);
|
||||
assert_eq!(result, vec!["foo", "bar", "baz"]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#[warn(clippy::disallowed_names)]
|
||||
#![warn(clippy::disallowed_names)]
|
||||
|
||||
fn main() {
|
||||
// `foo` is part of the default configuration
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#[warn(clippy::disallowed_names)]
|
||||
#![warn(clippy::disallowed_names)]
|
||||
|
||||
fn main() {
|
||||
// `foo` is part of the default configuration
|
||||
|
|
|
@ -15,7 +15,6 @@ use proc_macros::{external, with_span};
|
|||
#[warn(deref_nullptr)]
|
||||
#[deny(deref_nullptr)]
|
||||
#[forbid(deref_nullptr)]
|
||||
|
||||
fn main() {
|
||||
external! {
|
||||
#[allow(dead_code)]
|
||||
|
|
|
@ -36,7 +36,7 @@ LL | #[expect(dead_code)]
|
|||
= help: try adding a reason at the end with `, reason = ".."`
|
||||
|
||||
error: `allow` attribute without specifying a reason
|
||||
--> tests/ui/allow_attributes_without_reason.rs:47:5
|
||||
--> tests/ui/allow_attributes_without_reason.rs:46:5
|
||||
|
|
||||
LL | #[allow(unused)]
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
@ -44,7 +44,7 @@ LL | #[allow(unused)]
|
|||
= help: try adding a reason at the end with `, reason = ".."`
|
||||
|
||||
error: `allow` attribute without specifying a reason
|
||||
--> tests/ui/allow_attributes_without_reason.rs:47:5
|
||||
--> tests/ui/allow_attributes_without_reason.rs:46:5
|
||||
|
|
||||
LL | #[allow(unused)]
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
|
|
@ -2,16 +2,16 @@
|
|||
|
||||
#![feature(rustc_private)]
|
||||
#![feature(core_intrinsics)]
|
||||
extern crate libc;
|
||||
|
||||
#[warn(clippy::cast_ptr_alignment)]
|
||||
#[allow(
|
||||
#![warn(clippy::cast_ptr_alignment)]
|
||||
#![allow(
|
||||
clippy::no_effect,
|
||||
clippy::unnecessary_operation,
|
||||
clippy::cast_lossless,
|
||||
clippy::borrow_as_ptr
|
||||
)]
|
||||
|
||||
extern crate libc;
|
||||
|
||||
fn main() {
|
||||
/* These should be warned against */
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#[allow(clippy::unnecessary_operation)]
|
||||
#[allow(clippy::implicit_clone)]
|
||||
#![allow(clippy::unnecessary_operation)]
|
||||
#![allow(clippy::implicit_clone)]
|
||||
|
||||
fn main() {
|
||||
let x = &Baz;
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
#![allow(clippy::assertions_on_constants, clippy::equatable_if_let, clippy::needless_if)]
|
||||
#![warn(clippy::collapsible_if, clippy::collapsible_else_if)]
|
||||
|
||||
#[rustfmt::skip]
|
||||
#[warn(clippy::collapsible_if)]
|
||||
#[warn(clippy::collapsible_else_if)]
|
||||
|
||||
fn main() {
|
||||
let x = "hello";
|
||||
let y = "world";
|
||||
|
@ -76,7 +74,6 @@ fn main() {
|
|||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
#[allow(dead_code)]
|
||||
fn issue_7318() {
|
||||
if true { println!("I've been resolved!")
|
||||
}else if false {}
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
#![allow(clippy::assertions_on_constants, clippy::equatable_if_let, clippy::needless_if)]
|
||||
#![warn(clippy::collapsible_if, clippy::collapsible_else_if)]
|
||||
|
||||
#[rustfmt::skip]
|
||||
#[warn(clippy::collapsible_if)]
|
||||
#[warn(clippy::collapsible_else_if)]
|
||||
|
||||
fn main() {
|
||||
let x = "hello";
|
||||
let y = "world";
|
||||
|
@ -90,7 +88,6 @@ fn main() {
|
|||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
#[allow(dead_code)]
|
||||
fn issue_7318() {
|
||||
if true { println!("I've been resolved!")
|
||||
}else{
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
error: this `else { if .. }` block can be collapsed
|
||||
--> tests/ui/collapsible_else_if.rs:13:12
|
||||
--> tests/ui/collapsible_else_if.rs:11:12
|
||||
|
|
||||
LL | } else {
|
||||
| ____________^
|
||||
|
@ -19,7 +19,7 @@ LL + }
|
|||
|
|
||||
|
||||
error: this `else { if .. }` block can be collapsed
|
||||
--> tests/ui/collapsible_else_if.rs:21:12
|
||||
--> tests/ui/collapsible_else_if.rs:19:12
|
||||
|
|
||||
LL | } else {
|
||||
| ____________^
|
||||
|
@ -37,7 +37,7 @@ LL + }
|
|||
|
|
||||
|
||||
error: this `else { if .. }` block can be collapsed
|
||||
--> tests/ui/collapsible_else_if.rs:29:12
|
||||
--> tests/ui/collapsible_else_if.rs:27:12
|
||||
|
|
||||
LL | } else {
|
||||
| ____________^
|
||||
|
@ -60,7 +60,7 @@ LL + }
|
|||
|
|
||||
|
||||
error: this `else { if .. }` block can be collapsed
|
||||
--> tests/ui/collapsible_else_if.rs:40:12
|
||||
--> tests/ui/collapsible_else_if.rs:38:12
|
||||
|
|
||||
LL | } else {
|
||||
| ____________^
|
||||
|
@ -83,7 +83,7 @@ LL + }
|
|||
|
|
||||
|
||||
error: this `else { if .. }` block can be collapsed
|
||||
--> tests/ui/collapsible_else_if.rs:51:12
|
||||
--> tests/ui/collapsible_else_if.rs:49:12
|
||||
|
|
||||
LL | } else {
|
||||
| ____________^
|
||||
|
@ -106,7 +106,7 @@ LL + }
|
|||
|
|
||||
|
||||
error: this `else { if .. }` block can be collapsed
|
||||
--> tests/ui/collapsible_else_if.rs:62:12
|
||||
--> tests/ui/collapsible_else_if.rs:60:12
|
||||
|
|
||||
LL | } else {
|
||||
| ____________^
|
||||
|
@ -129,7 +129,7 @@ LL + }
|
|||
|
|
||||
|
||||
error: this `else { if .. }` block can be collapsed
|
||||
--> tests/ui/collapsible_else_if.rs:73:12
|
||||
--> tests/ui/collapsible_else_if.rs:71:12
|
||||
|
|
||||
LL | } else {
|
||||
| ____________^
|
||||
|
@ -152,7 +152,7 @@ LL + }
|
|||
|
|
||||
|
||||
error: this `else { if .. }` block can be collapsed
|
||||
--> tests/ui/collapsible_else_if.rs:96:10
|
||||
--> tests/ui/collapsible_else_if.rs:93:10
|
||||
|
|
||||
LL | }else{
|
||||
| __________^
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/// Test for https://github.com/rust-lang/rust-clippy/issues/1698
|
||||
// Test for https://github.com/rust-lang/rust-clippy/issues/1698
|
||||
|
||||
pub trait Trait {
|
||||
const CONSTANT: u8;
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
#[allow(dead_code)]
|
||||
|
||||
/// Test for https://github.com/rust-lang/rust-clippy/issues/478
|
||||
// Test for https://github.com/rust-lang/rust-clippy/issues/478
|
||||
|
||||
enum Baz {
|
||||
One,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/// Test for https://github.com/rust-lang/rust-clippy/issues/11230
|
||||
// Test for https://github.com/rust-lang/rust-clippy/issues/11230
|
||||
|
||||
fn main() {
|
||||
const A: &[for<'a> fn(&'a ())] = &[];
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#![allow(clippy::all)]
|
||||
|
||||
/// Test for https://github.com/rust-lang/rust-clippy/issues/1588
|
||||
// Test for https://github.com/rust-lang/rust-clippy/issues/1588
|
||||
|
||||
fn main() {
|
||||
match 1 {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#![allow(clippy::all)]
|
||||
|
||||
/// Test for https://github.com/rust-lang/rust-clippy/issues/1969
|
||||
// Test for https://github.com/rust-lang/rust-clippy/issues/1969
|
||||
|
||||
fn main() {}
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#![allow(dead_code, clippy::char_lit_as_u8, clippy::needless_bool)]
|
||||
|
||||
/// Should not trigger an ICE in `SpanlessHash` / `consts::constant`
|
||||
///
|
||||
/// Issue: https://github.com/rust-lang/rust-clippy/issues/2499
|
||||
// Should not trigger an ICE in `SpanlessHash` / `consts::constant`
|
||||
//
|
||||
// Issue: https://github.com/rust-lang/rust-clippy/issues/2499
|
||||
|
||||
fn f(s: &[u8]) -> bool {
|
||||
let t = s[0] as char;
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
/// Should not trigger an ICE in `SpanlessHash` / `consts::constant`
|
||||
///
|
||||
/// Issue: https://github.com/rust-lang/rust-clippy/issues/2594
|
||||
|
||||
fn spanless_hash_ice() {
|
||||
let txt = "something";
|
||||
let empty_header: [u8; 1] = [1; 1];
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/// Test for https://github.com/rust-lang/rust-clippy/issues/2727
|
||||
// Test for https://github.com/rust-lang/rust-clippy/issues/2727
|
||||
|
||||
pub fn f(new: fn()) {
|
||||
new();
|
||||
|
|
|
@ -5,10 +5,10 @@
|
|||
dead_code
|
||||
)]
|
||||
|
||||
/// This should not compile-fail with:
|
||||
///
|
||||
/// error[E0277]: the trait bound `T: Foo` is not satisfied
|
||||
// See rust-lang/rust-clippy#2760.
|
||||
// This should not compile-fail with:
|
||||
//
|
||||
// error[E0277]: the trait bound `T: Foo` is not satisfied
|
||||
// See https://github.com/rust-lang/rust-clippy/issues/2760
|
||||
|
||||
trait Foo {
|
||||
type Bar;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/// Test for https://github.com/rust-lang/rust-clippy/issues/2862
|
||||
// Test for https://github.com/rust-lang/rust-clippy/issues/2862
|
||||
|
||||
pub trait FooMap {
|
||||
fn map<B, F: Fn() -> B>(&self, f: F) -> B;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#![allow(dead_code, clippy::extra_unused_lifetimes)]
|
||||
|
||||
/// Test for https://github.com/rust-lang/rust-clippy/issues/2865
|
||||
// Test for https://github.com/rust-lang/rust-clippy/issues/2865
|
||||
|
||||
struct Ice {
|
||||
size: String,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/// Test for https://github.com/rust-lang/rust-clippy/issues/3151
|
||||
// Test for https://github.com/rust-lang/rust-clippy/issues/3151
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct HashMap<V, S> {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#![allow(clippy::disallowed_names, clippy::equatable_if_let, clippy::needless_if)]
|
||||
#![allow(unused)]
|
||||
|
||||
/// Test for https://github.com/rust-lang/rust-clippy/issues/3462
|
||||
// Test for https://github.com/rust-lang/rust-clippy/issues/3462
|
||||
|
||||
enum Foo {
|
||||
Bar,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/// Test for https://github.com/rust-lang/rust-clippy/issues/3747
|
||||
// Test for https://github.com/rust-lang/rust-clippy/issues/3747
|
||||
|
||||
macro_rules! a {
|
||||
( $pub:tt $($attr:tt)* ) => {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#![deny(clippy::all)]
|
||||
|
||||
/// Test for https://github.com/rust-lang/rust-clippy/issues/700
|
||||
// Test for https://github.com/rust-lang/rust-clippy/issues/700
|
||||
|
||||
fn core() {}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#![deny(clippy::all)]
|
||||
|
||||
/// Test for https://github.com/rust-lang/rust-clippy/issues/1336
|
||||
// Test for https://github.com/rust-lang/rust-clippy/issues/1336
|
||||
|
||||
#[allow(dead_code)]
|
||||
struct Foo;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#![allow(clippy::comparison_chain)]
|
||||
#![deny(clippy::if_same_then_else)]
|
||||
|
||||
/// Test for https://github.com/rust-lang/rust-clippy/issues/2426
|
||||
// Test for https://github.com/rust-lang/rust-clippy/issues/2426
|
||||
|
||||
fn main() {}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#![deny(clippy::multiple_inherent_impl)]
|
||||
|
||||
/// Test for https://github.com/rust-lang/rust-clippy/issues/4578
|
||||
// Test for https://github.com/rust-lang/rust-clippy/issues/4578
|
||||
|
||||
macro_rules! impl_foo {
|
||||
($struct:ident) => {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#![allow(warnings)]
|
||||
|
||||
/// Test for https://github.com/rust-lang/rust-clippy/issues/825
|
||||
// Test for https://github.com/rust-lang/rust-clippy/issues/825
|
||||
|
||||
// this should compile in a reasonable amount of time
|
||||
fn rust_type_id(name: &str) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#![deny(clippy::match_same_arms)]
|
||||
|
||||
/// Test for https://github.com/rust-lang/rust-clippy/issues/2427
|
||||
// Test for https://github.com/rust-lang/rust-clippy/issues/2427
|
||||
|
||||
const PRICE_OF_SWEETS: u32 = 5;
|
||||
const PRICE_OF_KINDNESS: u32 = 0;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/// Test for https://github.com/rust-lang/rust-clippy/issues/1346
|
||||
// Test for https://github.com/rust-lang/rust-clippy/issues/1346
|
||||
|
||||
#[deny(warnings)]
|
||||
fn cfg_return() -> i32 {
|
||||
|
|
|
@ -1,47 +0,0 @@
|
|||
// https://github.com/rust-lang/rust-clippy/issues/12917
|
||||
#![warn(clippy::doc_lazy_continuation)]
|
||||
|
||||
/// This is a constant.
|
||||
///
|
||||
/// The meaning of which should not be explained.
|
||||
pub const A: i32 = 42;
|
||||
|
||||
/// This is another constant, no longer used.
|
||||
///
|
||||
/// This block of documentation has a long
|
||||
/// explanation and derivation to explain
|
||||
/// why it is what it is, and how it's used.
|
||||
///
|
||||
/// It is left here for historical reasons, and
|
||||
/// for reference.
|
||||
///
|
||||
/// Reasons it's great:
|
||||
/// - First reason
|
||||
/// - Second reason
|
||||
///
|
||||
//pub const B: i32 = 1337;
|
||||
|
||||
/// This is yet another constant.
|
||||
///
|
||||
/// This has a similar fate as `B`.
|
||||
///
|
||||
/// Reasons it's useful:
|
||||
/// 1. First reason
|
||||
/// 2. Second reason
|
||||
///
|
||||
//pub const C: i32 = 8008;
|
||||
|
||||
/// This is still in use.
|
||||
pub const D: i32 = 20;
|
||||
|
||||
/// > blockquote code path
|
||||
///
|
||||
|
||||
/// bottom text
|
||||
pub const E: i32 = 20;
|
||||
|
||||
/// > blockquote code path
|
||||
///
|
||||
#[repr(C)]
|
||||
/// bottom text
|
||||
pub struct Foo(i32);
|
|
@ -1,43 +0,0 @@
|
|||
// https://github.com/rust-lang/rust-clippy/issues/12917
|
||||
#![warn(clippy::doc_lazy_continuation)]
|
||||
|
||||
/// This is a constant.
|
||||
///
|
||||
/// The meaning of which should not be explained.
|
||||
pub const A: i32 = 42;
|
||||
|
||||
/// This is another constant, no longer used.
|
||||
///
|
||||
/// This block of documentation has a long
|
||||
/// explanation and derivation to explain
|
||||
/// why it is what it is, and how it's used.
|
||||
///
|
||||
/// It is left here for historical reasons, and
|
||||
/// for reference.
|
||||
///
|
||||
/// Reasons it's great:
|
||||
/// - First reason
|
||||
/// - Second reason
|
||||
//pub const B: i32 = 1337;
|
||||
|
||||
/// This is yet another constant.
|
||||
///
|
||||
/// This has a similar fate as `B`.
|
||||
///
|
||||
/// Reasons it's useful:
|
||||
/// 1. First reason
|
||||
/// 2. Second reason
|
||||
//pub const C: i32 = 8008;
|
||||
|
||||
/// This is still in use.
|
||||
pub const D: i32 = 20;
|
||||
|
||||
/// > blockquote code path
|
||||
|
||||
/// bottom text
|
||||
pub const E: i32 = 20;
|
||||
|
||||
/// > blockquote code path
|
||||
#[repr(C)]
|
||||
/// bottom text
|
||||
pub struct Foo(i32);
|
|
@ -1,56 +0,0 @@
|
|||
error: doc list item without indentation
|
||||
--> tests/ui/doc/doc_lazy_blank_line.rs:23:5
|
||||
|
|
||||
LL | /// This is yet another constant.
|
||||
| ^
|
||||
|
|
||||
= help: if this is intended to be part of the list, indent 3 spaces
|
||||
= note: `-D clippy::doc-lazy-continuation` implied by `-D warnings`
|
||||
= help: to override `-D warnings` add `#[allow(clippy::doc_lazy_continuation)]`
|
||||
help: if this should be its own paragraph, add a blank doc comment line
|
||||
|
|
||||
LL ~ /// - Second reason
|
||||
LL + ///
|
||||
|
|
||||
|
||||
error: doc list item without indentation
|
||||
--> tests/ui/doc/doc_lazy_blank_line.rs:32:5
|
||||
|
|
||||
LL | /// This is still in use.
|
||||
| ^
|
||||
|
|
||||
= help: if this is intended to be part of the list, indent 4 spaces
|
||||
help: if this should be its own paragraph, add a blank doc comment line
|
||||
|
|
||||
LL ~ /// 2. Second reason
|
||||
LL + ///
|
||||
|
|
||||
|
||||
error: doc quote line without `>` marker
|
||||
--> tests/ui/doc/doc_lazy_blank_line.rs:37:5
|
||||
|
|
||||
LL | /// bottom text
|
||||
| ^
|
||||
|
|
||||
= help: if this not intended to be a quote at all, escape it with `\>`
|
||||
help: if this should be its own paragraph, add a blank doc comment line
|
||||
|
|
||||
LL ~ /// > blockquote code path
|
||||
LL + ///
|
||||
|
|
||||
|
||||
error: doc quote line without `>` marker
|
||||
--> tests/ui/doc/doc_lazy_blank_line.rs:42:5
|
||||
|
|
||||
LL | /// bottom text
|
||||
| ^
|
||||
|
|
||||
= help: if this not intended to be a quote at all, escape it with `\>`
|
||||
help: if this should be its own paragraph, add a blank doc comment line
|
||||
|
|
||||
LL ~ /// > blockquote code path
|
||||
LL + ///
|
||||
|
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
|
@ -7,9 +7,8 @@ fn one() {}
|
|||
|
||||
/// 1. first line
|
||||
/// lazy list continuations don't make warnings with this lint
|
||||
///
|
||||
//~^ ERROR: doc list item without indentation
|
||||
/// because they don't have the
|
||||
/// because they don't have the
|
||||
//~^ ERROR: doc list item without indentation
|
||||
fn two() {}
|
||||
|
||||
|
@ -20,9 +19,8 @@ fn three() {}
|
|||
|
||||
/// - first line
|
||||
/// lazy list continuations don't make warnings with this lint
|
||||
///
|
||||
//~^ ERROR: doc list item without indentation
|
||||
/// because they don't have the
|
||||
/// because they don't have the
|
||||
//~^ ERROR: doc list item without indentation
|
||||
fn four() {}
|
||||
|
||||
|
@ -33,9 +31,8 @@ fn five() {}
|
|||
|
||||
/// - - first line
|
||||
/// this will warn on the lazy continuation
|
||||
///
|
||||
//~^ ERROR: doc list item without indentation
|
||||
/// and so should this
|
||||
/// and so should this
|
||||
//~^ ERROR: doc list item without indentation
|
||||
fn six() {}
|
||||
|
||||
|
|
|
@ -30,12 +30,11 @@ error: doc list item without indentation
|
|||
LL | /// because they don't have the
|
||||
| ^
|
||||
|
|
||||
= help: if this is intended to be part of the list, indent 3 spaces
|
||||
help: if this should be its own paragraph, add a blank doc comment line
|
||||
|
|
||||
LL ~ /// lazy list continuations don't make warnings with this lint
|
||||
LL + ///
|
||||
= help: if this is supposed to be its own paragraph, add a blank line
|
||||
help: indent this line
|
||||
|
|
||||
LL | /// because they don't have the
|
||||
| +++
|
||||
|
||||
error: doc list item without indentation
|
||||
--> tests/ui/doc/doc_lazy_list.rs:16:5
|
||||
|
@ -67,12 +66,11 @@ error: doc list item without indentation
|
|||
LL | /// because they don't have the
|
||||
| ^
|
||||
|
|
||||
= help: if this is intended to be part of the list, indent 4 spaces
|
||||
help: if this should be its own paragraph, add a blank doc comment line
|
||||
|
|
||||
LL ~ /// lazy list continuations don't make warnings with this lint
|
||||
LL + ///
|
||||
= help: if this is supposed to be its own paragraph, add a blank line
|
||||
help: indent this line
|
||||
|
|
||||
LL | /// because they don't have the
|
||||
| ++++
|
||||
|
||||
error: doc list item without indentation
|
||||
--> tests/ui/doc/doc_lazy_list.rs:28:5
|
||||
|
@ -104,12 +102,11 @@ error: doc list item without indentation
|
|||
LL | /// and so should this
|
||||
| ^^^^
|
||||
|
|
||||
= help: if this is intended to be part of the list, indent 2 spaces
|
||||
help: if this should be its own paragraph, add a blank doc comment line
|
||||
|
|
||||
LL ~ /// this will warn on the lazy continuation
|
||||
LL + ///
|
||||
= help: if this is supposed to be its own paragraph, add a blank line
|
||||
help: indent this line
|
||||
|
|
||||
LL | /// and so should this
|
||||
| ++
|
||||
|
||||
error: doc list item without indentation
|
||||
--> tests/ui/doc/doc_lazy_list.rs:56:5
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#![warn(clippy::duplicate_underscore_argument)]
|
||||
#[allow(dead_code, unused)]
|
||||
|
||||
fn join_the_dark_side(darth: i32, _darth: i32) {}
|
||||
//~^ ERROR: `darth` already exists, having another argument having almost the same name ma
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
error: `darth` already exists, having another argument having almost the same name makes code comprehension and documentation more difficult
|
||||
--> tests/ui/duplicate_underscore_argument.rs:4:23
|
||||
--> tests/ui/duplicate_underscore_argument.rs:3:23
|
||||
|
|
||||
LL | fn join_the_dark_side(darth: i32, _darth: i32) {}
|
||||
| ^^^^^
|
||||
|
|
135
tests/ui/empty_line_after/doc_comments.1.fixed
Normal file
135
tests/ui/empty_line_after/doc_comments.1.fixed
Normal file
|
@ -0,0 +1,135 @@
|
|||
#![warn(clippy::empty_line_after_outer_attr, clippy::empty_line_after_doc_comments)]
|
||||
|
||||
//~vvv empty_line_after_doc_comments
|
||||
/// Meant to be an
|
||||
/// inner doc comment
|
||||
/// for the crate
|
||||
fn first_in_crate() {}
|
||||
|
||||
mod m {
|
||||
//~vvv empty_line_after_doc_comments
|
||||
/// Meant to be an
|
||||
/// inner doc comment
|
||||
/// for the module
|
||||
fn first_in_module() {}
|
||||
}
|
||||
|
||||
mod some_mod {
|
||||
//! This doc comment should *NOT* produce a warning
|
||||
|
||||
mod some_inner_mod {
|
||||
fn some_noop() {}
|
||||
}
|
||||
|
||||
//~v empty_line_after_doc_comments
|
||||
/// # Indented
|
||||
/// Blank line
|
||||
fn indented() {}
|
||||
}
|
||||
|
||||
//~v empty_line_after_doc_comments
|
||||
/// This should produce a warning
|
||||
fn with_doc_and_newline() {}
|
||||
|
||||
// This should *NOT* produce a warning
|
||||
#[crate_type = "lib"]
|
||||
/// some comment
|
||||
fn with_no_newline_and_comment() {}
|
||||
|
||||
//~v empty_line_after_doc_comments
|
||||
/// This doc comment should produce a warning
|
||||
/** This is also a doc comment and is part of the warning
|
||||
*/
|
||||
#[allow(non_camel_case_types)]
|
||||
#[allow(missing_docs)]
|
||||
#[allow(dead_code)]
|
||||
fn three_attributes() {}
|
||||
|
||||
mod misattributed {
|
||||
//~v empty_line_after_doc_comments
|
||||
/// docs for `old_code`
|
||||
// fn old_code() {}
|
||||
fn new_code() {}
|
||||
|
||||
//~vv empty_line_after_doc_comments
|
||||
/// Docs
|
||||
/// for OldA
|
||||
// struct OldA;
|
||||
/// Docs
|
||||
/// for OldB
|
||||
// struct OldB;
|
||||
/// Docs
|
||||
/// for Multiple
|
||||
#[allow(dead_code)]
|
||||
struct Multiple;
|
||||
}
|
||||
|
||||
mod block_comments {
|
||||
//~v empty_line_after_doc_comments
|
||||
/**
|
||||
* Meant to be inner doc comment
|
||||
*/
|
||||
fn first_in_module() {}
|
||||
|
||||
//~v empty_line_after_doc_comments
|
||||
/**
|
||||
* Docs for `old_code`
|
||||
*/
|
||||
/* fn old_code() {} */
|
||||
/**
|
||||
* Docs for `new_code`
|
||||
*/
|
||||
fn new_code() {}
|
||||
|
||||
//~v empty_line_after_doc_comments
|
||||
/// Docs for `old_code2`
|
||||
/* fn old_code2() {} */
|
||||
/// Docs for `new_code2`
|
||||
fn new_code2() {}
|
||||
}
|
||||
|
||||
// This should *NOT* produce a warning
|
||||
#[doc = "
|
||||
Returns the escaped value of the textual representation of
|
||||
|
||||
"]
|
||||
pub fn function() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
// This should *NOT* produce a warning
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum FooFighter {
|
||||
Bar1,
|
||||
|
||||
Bar2,
|
||||
|
||||
Bar3,
|
||||
|
||||
Bar4,
|
||||
}
|
||||
|
||||
/// Should not lint
|
||||
// some line comment
|
||||
/// gaps without an empty line
|
||||
struct LineComment;
|
||||
|
||||
/// This should *NOT* produce a warning because the empty line is inside a block comment
|
||||
/*
|
||||
|
||||
*/
|
||||
pub struct EmptyInBlockComment;
|
||||
|
||||
/// This should *NOT* produce a warning
|
||||
/* test */
|
||||
pub struct BlockComment;
|
||||
|
||||
/// Ignore the empty line inside a cfg_attr'd out attribute
|
||||
#[cfg_attr(any(), multiline(
|
||||
foo = 1
|
||||
|
||||
bar = 2
|
||||
))]
|
||||
fn empty_line_in_cfg_attr() {}
|
||||
|
||||
fn main() {}
|
144
tests/ui/empty_line_after/doc_comments.2.fixed
Normal file
144
tests/ui/empty_line_after/doc_comments.2.fixed
Normal file
|
@ -0,0 +1,144 @@
|
|||
#![warn(clippy::empty_line_after_outer_attr, clippy::empty_line_after_doc_comments)]
|
||||
|
||||
//~vvv empty_line_after_doc_comments
|
||||
//! Meant to be an
|
||||
//! inner doc comment
|
||||
//! for the crate
|
||||
|
||||
fn first_in_crate() {}
|
||||
|
||||
mod m {
|
||||
//~vvv empty_line_after_doc_comments
|
||||
//! Meant to be an
|
||||
//! inner doc comment
|
||||
//! for the module
|
||||
|
||||
fn first_in_module() {}
|
||||
}
|
||||
|
||||
mod some_mod {
|
||||
//! This doc comment should *NOT* produce a warning
|
||||
|
||||
mod some_inner_mod {
|
||||
fn some_noop() {}
|
||||
}
|
||||
|
||||
//~v empty_line_after_doc_comments
|
||||
/// # Indented
|
||||
///
|
||||
/// Blank line
|
||||
fn indented() {}
|
||||
}
|
||||
|
||||
//~v empty_line_after_doc_comments
|
||||
/// This should produce a warning
|
||||
fn with_doc_and_newline() {}
|
||||
|
||||
// This should *NOT* produce a warning
|
||||
#[crate_type = "lib"]
|
||||
/// some comment
|
||||
fn with_no_newline_and_comment() {}
|
||||
|
||||
//~v empty_line_after_doc_comments
|
||||
/// This doc comment should produce a warning
|
||||
/** This is also a doc comment and is part of the warning
|
||||
*/
|
||||
#[allow(non_camel_case_types)]
|
||||
#[allow(missing_docs)]
|
||||
#[allow(dead_code)]
|
||||
fn three_attributes() {}
|
||||
|
||||
mod misattributed {
|
||||
//~v empty_line_after_doc_comments
|
||||
// /// docs for `old_code`
|
||||
// fn old_code() {}
|
||||
|
||||
fn new_code() {}
|
||||
|
||||
//~vv empty_line_after_doc_comments
|
||||
// /// Docs
|
||||
// /// for OldA
|
||||
// struct OldA;
|
||||
|
||||
// /// Docs
|
||||
// /// for OldB
|
||||
// struct OldB;
|
||||
|
||||
/// Docs
|
||||
/// for Multiple
|
||||
#[allow(dead_code)]
|
||||
struct Multiple;
|
||||
}
|
||||
|
||||
mod block_comments {
|
||||
//~v empty_line_after_doc_comments
|
||||
/*!
|
||||
* Meant to be inner doc comment
|
||||
*/
|
||||
|
||||
fn first_in_module() {}
|
||||
|
||||
//~v empty_line_after_doc_comments
|
||||
/*
|
||||
* Docs for `old_code`
|
||||
*/
|
||||
/* fn old_code() {} */
|
||||
|
||||
/**
|
||||
* Docs for `new_code`
|
||||
*/
|
||||
fn new_code() {}
|
||||
|
||||
//~v empty_line_after_doc_comments
|
||||
// /// Docs for `old_code2`
|
||||
/* fn old_code2() {} */
|
||||
|
||||
/// Docs for `new_code2`
|
||||
fn new_code2() {}
|
||||
}
|
||||
|
||||
// This should *NOT* produce a warning
|
||||
#[doc = "
|
||||
Returns the escaped value of the textual representation of
|
||||
|
||||
"]
|
||||
pub fn function() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
// This should *NOT* produce a warning
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum FooFighter {
|
||||
Bar1,
|
||||
|
||||
Bar2,
|
||||
|
||||
Bar3,
|
||||
|
||||
Bar4,
|
||||
}
|
||||
|
||||
/// Should not lint
|
||||
// some line comment
|
||||
/// gaps without an empty line
|
||||
struct LineComment;
|
||||
|
||||
/// This should *NOT* produce a warning because the empty line is inside a block comment
|
||||
/*
|
||||
|
||||
*/
|
||||
pub struct EmptyInBlockComment;
|
||||
|
||||
/// This should *NOT* produce a warning
|
||||
/* test */
|
||||
pub struct BlockComment;
|
||||
|
||||
/// Ignore the empty line inside a cfg_attr'd out attribute
|
||||
#[cfg_attr(any(), multiline(
|
||||
foo = 1
|
||||
|
||||
bar = 2
|
||||
))]
|
||||
fn empty_line_in_cfg_attr() {}
|
||||
|
||||
fn main() {}
|
147
tests/ui/empty_line_after/doc_comments.rs
Normal file
147
tests/ui/empty_line_after/doc_comments.rs
Normal file
|
@ -0,0 +1,147 @@
|
|||
#![warn(clippy::empty_line_after_outer_attr, clippy::empty_line_after_doc_comments)]
|
||||
|
||||
//~vvv empty_line_after_doc_comments
|
||||
/// Meant to be an
|
||||
/// inner doc comment
|
||||
/// for the crate
|
||||
|
||||
fn first_in_crate() {}
|
||||
|
||||
mod m {
|
||||
//~vvv empty_line_after_doc_comments
|
||||
/// Meant to be an
|
||||
/// inner doc comment
|
||||
/// for the module
|
||||
|
||||
fn first_in_module() {}
|
||||
}
|
||||
|
||||
mod some_mod {
|
||||
//! This doc comment should *NOT* produce a warning
|
||||
|
||||
mod some_inner_mod {
|
||||
fn some_noop() {}
|
||||
}
|
||||
|
||||
//~v empty_line_after_doc_comments
|
||||
/// # Indented
|
||||
|
||||
/// Blank line
|
||||
fn indented() {}
|
||||
}
|
||||
|
||||
//~v empty_line_after_doc_comments
|
||||
/// This should produce a warning
|
||||
|
||||
fn with_doc_and_newline() {}
|
||||
|
||||
// This should *NOT* produce a warning
|
||||
#[crate_type = "lib"]
|
||||
/// some comment
|
||||
fn with_no_newline_and_comment() {}
|
||||
|
||||
//~v empty_line_after_doc_comments
|
||||
/// This doc comment should produce a warning
|
||||
|
||||
/** This is also a doc comment and is part of the warning
|
||||
*/
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
#[allow(missing_docs)]
|
||||
#[allow(dead_code)]
|
||||
fn three_attributes() {}
|
||||
|
||||
mod misattributed {
|
||||
//~v empty_line_after_doc_comments
|
||||
/// docs for `old_code`
|
||||
// fn old_code() {}
|
||||
|
||||
fn new_code() {}
|
||||
|
||||
//~vv empty_line_after_doc_comments
|
||||
/// Docs
|
||||
/// for OldA
|
||||
// struct OldA;
|
||||
|
||||
/// Docs
|
||||
/// for OldB
|
||||
// struct OldB;
|
||||
|
||||
/// Docs
|
||||
/// for Multiple
|
||||
#[allow(dead_code)]
|
||||
struct Multiple;
|
||||
}
|
||||
|
||||
mod block_comments {
|
||||
//~v empty_line_after_doc_comments
|
||||
/**
|
||||
* Meant to be inner doc comment
|
||||
*/
|
||||
|
||||
fn first_in_module() {}
|
||||
|
||||
//~v empty_line_after_doc_comments
|
||||
/**
|
||||
* Docs for `old_code`
|
||||
*/
|
||||
/* fn old_code() {} */
|
||||
|
||||
/**
|
||||
* Docs for `new_code`
|
||||
*/
|
||||
fn new_code() {}
|
||||
|
||||
//~v empty_line_after_doc_comments
|
||||
/// Docs for `old_code2`
|
||||
/* fn old_code2() {} */
|
||||
|
||||
/// Docs for `new_code2`
|
||||
fn new_code2() {}
|
||||
}
|
||||
|
||||
// This should *NOT* produce a warning
|
||||
#[doc = "
|
||||
Returns the escaped value of the textual representation of
|
||||
|
||||
"]
|
||||
pub fn function() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
// This should *NOT* produce a warning
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum FooFighter {
|
||||
Bar1,
|
||||
|
||||
Bar2,
|
||||
|
||||
Bar3,
|
||||
|
||||
Bar4,
|
||||
}
|
||||
|
||||
/// Should not lint
|
||||
// some line comment
|
||||
/// gaps without an empty line
|
||||
struct LineComment;
|
||||
|
||||
/// This should *NOT* produce a warning because the empty line is inside a block comment
|
||||
/*
|
||||
|
||||
*/
|
||||
pub struct EmptyInBlockComment;
|
||||
|
||||
/// This should *NOT* produce a warning
|
||||
/* test */
|
||||
pub struct BlockComment;
|
||||
|
||||
/// Ignore the empty line inside a cfg_attr'd out attribute
|
||||
#[cfg_attr(any(), multiline(
|
||||
foo = 1
|
||||
|
||||
bar = 2
|
||||
))]
|
||||
fn empty_line_in_cfg_attr() {}
|
||||
|
||||
fn main() {}
|
176
tests/ui/empty_line_after/doc_comments.stderr
Normal file
176
tests/ui/empty_line_after/doc_comments.stderr
Normal file
|
@ -0,0 +1,176 @@
|
|||
error: empty line after doc comment
|
||||
--> tests/ui/empty_line_after/doc_comments.rs:6:1
|
||||
|
|
||||
LL | / /// for the crate
|
||||
LL | |
|
||||
| |_
|
||||
LL | fn first_in_crate() {}
|
||||
| ------------------- the comment documents this function
|
||||
|
|
||||
= note: `-D clippy::empty-line-after-doc-comments` implied by `-D warnings`
|
||||
= help: to override `-D warnings` add `#[allow(clippy::empty_line_after_doc_comments)]`
|
||||
= help: if the empty line is unintentional remove it
|
||||
help: if the comment should document the crate use an inner doc comment
|
||||
|
|
||||
LL ~ //! Meant to be an
|
||||
LL ~ //! inner doc comment
|
||||
LL ~ //! for the crate
|
||||
|
|
||||
|
||||
error: empty line after doc comment
|
||||
--> tests/ui/empty_line_after/doc_comments.rs:14:5
|
||||
|
|
||||
LL | / /// for the module
|
||||
LL | |
|
||||
| |_
|
||||
LL | fn first_in_module() {}
|
||||
| -------------------- the comment documents this function
|
||||
|
|
||||
= help: if the empty line is unintentional remove it
|
||||
help: if the comment should document the parent module use an inner doc comment
|
||||
|
|
||||
LL ~ //! Meant to be an
|
||||
LL ~ //! inner doc comment
|
||||
LL ~ //! for the module
|
||||
|
|
||||
|
||||
error: empty line after doc comment
|
||||
--> tests/ui/empty_line_after/doc_comments.rs:27:5
|
||||
|
|
||||
LL | / /// # Indented
|
||||
LL | |
|
||||
| |_
|
||||
LL | /// Blank line
|
||||
LL | fn indented() {}
|
||||
| ------------- the comment documents this function
|
||||
|
|
||||
= help: if the empty line is unintentional remove it
|
||||
help: if the documentation should include the empty line include it in the comment
|
||||
|
|
||||
LL | ///
|
||||
|
|
||||
|
||||
error: empty line after doc comment
|
||||
--> tests/ui/empty_line_after/doc_comments.rs:34:1
|
||||
|
|
||||
LL | / /// This should produce a warning
|
||||
LL | |
|
||||
| |_
|
||||
LL | fn with_doc_and_newline() {}
|
||||
| ------------------------- the comment documents this function
|
||||
|
|
||||
= help: if the empty line is unintentional remove it
|
||||
|
||||
error: empty lines after doc comment
|
||||
--> tests/ui/empty_line_after/doc_comments.rs:44:1
|
||||
|
|
||||
LL | / /// This doc comment should produce a warning
|
||||
LL | |
|
||||
LL | | /** This is also a doc comment and is part of the warning
|
||||
LL | | */
|
||||
LL | |
|
||||
| |_
|
||||
...
|
||||
LL | fn three_attributes() {}
|
||||
| --------------------- the comment documents this function
|
||||
|
|
||||
= help: if the empty lines are unintentional remove them
|
||||
|
||||
error: empty line after doc comment
|
||||
--> tests/ui/empty_line_after/doc_comments.rs:56:5
|
||||
|
|
||||
LL | / /// docs for `old_code`
|
||||
LL | | // fn old_code() {}
|
||||
LL | |
|
||||
| |_
|
||||
LL | fn new_code() {}
|
||||
| ------------- the comment documents this function
|
||||
|
|
||||
= help: if the empty line is unintentional remove it
|
||||
help: if the doc comment should not document `new_code` comment it out
|
||||
|
|
||||
LL | // /// docs for `old_code`
|
||||
| ++
|
||||
|
||||
error: empty lines after doc comment
|
||||
--> tests/ui/empty_line_after/doc_comments.rs:63:5
|
||||
|
|
||||
LL | / /// for OldA
|
||||
LL | | // struct OldA;
|
||||
LL | |
|
||||
LL | | /// Docs
|
||||
LL | | /// for OldB
|
||||
LL | | // struct OldB;
|
||||
LL | |
|
||||
| |_
|
||||
...
|
||||
LL | struct Multiple;
|
||||
| --------------- the comment documents this struct
|
||||
|
|
||||
= help: if the empty lines are unintentional remove them
|
||||
help: if the doc comment should not document `Multiple` comment it out
|
||||
|
|
||||
LL ~ // /// Docs
|
||||
LL ~ // /// for OldA
|
||||
LL | // struct OldA;
|
||||
LL |
|
||||
LL ~ // /// Docs
|
||||
LL ~ // /// for OldB
|
||||
|
|
||||
|
||||
error: empty line after doc comment
|
||||
--> tests/ui/empty_line_after/doc_comments.rs:78:5
|
||||
|
|
||||
LL | / /**
|
||||
LL | | * Meant to be inner doc comment
|
||||
LL | | */
|
||||
LL | |
|
||||
| |_
|
||||
LL | fn first_in_module() {}
|
||||
| -------------------- the comment documents this function
|
||||
|
|
||||
= help: if the empty line is unintentional remove it
|
||||
help: if the comment should document the parent module use an inner doc comment
|
||||
|
|
||||
LL | /*!
|
||||
| ~
|
||||
|
||||
error: empty line after doc comment
|
||||
--> tests/ui/empty_line_after/doc_comments.rs:85:5
|
||||
|
|
||||
LL | / /**
|
||||
LL | | * Docs for `old_code`
|
||||
LL | | */
|
||||
LL | | /* fn old_code() {} */
|
||||
LL | |
|
||||
| |_
|
||||
...
|
||||
LL | fn new_code() {}
|
||||
| ------------- the comment documents this function
|
||||
|
|
||||
= help: if the empty line is unintentional remove it
|
||||
help: if the doc comment should not document `new_code` comment it out
|
||||
|
|
||||
LL - /**
|
||||
LL + /*
|
||||
|
|
||||
|
||||
error: empty line after doc comment
|
||||
--> tests/ui/empty_line_after/doc_comments.rs:96:5
|
||||
|
|
||||
LL | / /// Docs for `old_code2`
|
||||
LL | | /* fn old_code2() {} */
|
||||
LL | |
|
||||
| |_
|
||||
LL | /// Docs for `new_code2`
|
||||
LL | fn new_code2() {}
|
||||
| -------------- the comment documents this function
|
||||
|
|
||||
= help: if the empty line is unintentional remove it
|
||||
help: if the doc comment should not document `new_code2` comment it out
|
||||
|
|
||||
LL | // /// Docs for `old_code2`
|
||||
| ++
|
||||
|
||||
error: aborting due to 10 previous errors
|
||||
|
103
tests/ui/empty_line_after/outer_attribute.1.fixed
Normal file
103
tests/ui/empty_line_after/outer_attribute.1.fixed
Normal file
|
@ -0,0 +1,103 @@
|
|||
//@aux-build:../auxiliary/proc_macro_attr.rs
|
||||
#![warn(clippy::empty_line_after_outer_attr, clippy::empty_line_after_doc_comments)]
|
||||
|
||||
//~v empty_line_after_outer_attr
|
||||
#[crate_type = "lib"]
|
||||
fn first_in_crate() {}
|
||||
|
||||
#[macro_use]
|
||||
extern crate proc_macro_attr;
|
||||
|
||||
//~v empty_line_after_outer_attr
|
||||
#[inline]
|
||||
/// some comment
|
||||
fn with_one_newline_and_comment() {}
|
||||
|
||||
#[inline]
|
||||
/// some comment
|
||||
fn with_no_newline_and_comment() {}
|
||||
|
||||
//~v empty_line_after_outer_attr
|
||||
#[inline]
|
||||
fn with_one_newline() {}
|
||||
|
||||
#[rustfmt::skip]
|
||||
mod two_lines {
|
||||
//~v empty_line_after_outer_attr
|
||||
#[crate_type = "lib"]
|
||||
fn with_two_newlines() {}
|
||||
}
|
||||
|
||||
//~v empty_line_after_outer_attr
|
||||
#[doc = "doc attributes should be considered attributes"]
|
||||
enum Baz {
|
||||
One,
|
||||
Two,
|
||||
}
|
||||
|
||||
//~v empty_line_after_outer_attr
|
||||
#[repr(C)]
|
||||
struct Foo {
|
||||
one: isize,
|
||||
two: isize,
|
||||
}
|
||||
|
||||
//~v empty_line_after_outer_attr
|
||||
#[allow(dead_code)]
|
||||
mod foo {}
|
||||
|
||||
//~v empty_line_after_outer_attr
|
||||
#[inline]
|
||||
// Still lint cases where the empty line does not immediately follow the attribute
|
||||
fn comment_before_empty_line() {}
|
||||
|
||||
#[doc = "
|
||||
Returns the escaped value of the textual representation of
|
||||
|
||||
"]
|
||||
pub fn function() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum FooFighter {
|
||||
Bar1,
|
||||
|
||||
Bar2,
|
||||
|
||||
Bar3,
|
||||
|
||||
Bar4,
|
||||
}
|
||||
|
||||
#[crate_type = "lib"]
|
||||
/*
|
||||
|
||||
*/
|
||||
pub struct EmptyLineInBlockComment;
|
||||
|
||||
#[crate_type = "lib"]
|
||||
/* test */
|
||||
pub struct BlockComment;
|
||||
|
||||
// See https://github.com/rust-lang/rust-clippy/issues/5567
|
||||
#[rustfmt::skip]
|
||||
#[fake_async_trait]
|
||||
pub trait Bazz {
|
||||
fn foo() -> Vec<u8> {
|
||||
let _i = "";
|
||||
|
||||
|
||||
|
||||
vec![]
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
#[dummy(string = "first line
|
||||
|
||||
second line
|
||||
")]
|
||||
pub struct Args;
|
||||
|
||||
fn main() {}
|
106
tests/ui/empty_line_after/outer_attribute.2.fixed
Normal file
106
tests/ui/empty_line_after/outer_attribute.2.fixed
Normal file
|
@ -0,0 +1,106 @@
|
|||
//@aux-build:../auxiliary/proc_macro_attr.rs
|
||||
#![warn(clippy::empty_line_after_outer_attr, clippy::empty_line_after_doc_comments)]
|
||||
|
||||
//~v empty_line_after_outer_attr
|
||||
#![crate_type = "lib"]
|
||||
|
||||
fn first_in_crate() {}
|
||||
|
||||
#[macro_use]
|
||||
extern crate proc_macro_attr;
|
||||
|
||||
//~v empty_line_after_outer_attr
|
||||
#[inline]
|
||||
/// some comment
|
||||
fn with_one_newline_and_comment() {}
|
||||
|
||||
#[inline]
|
||||
/// some comment
|
||||
fn with_no_newline_and_comment() {}
|
||||
|
||||
//~v empty_line_after_outer_attr
|
||||
#[inline]
|
||||
fn with_one_newline() {}
|
||||
|
||||
#[rustfmt::skip]
|
||||
mod two_lines {
|
||||
//~v empty_line_after_outer_attr
|
||||
#![crate_type = "lib"]
|
||||
|
||||
|
||||
fn with_two_newlines() {}
|
||||
}
|
||||
|
||||
//~v empty_line_after_outer_attr
|
||||
#[doc = "doc attributes should be considered attributes"]
|
||||
enum Baz {
|
||||
One,
|
||||
Two,
|
||||
}
|
||||
|
||||
//~v empty_line_after_outer_attr
|
||||
#[repr(C)]
|
||||
struct Foo {
|
||||
one: isize,
|
||||
two: isize,
|
||||
}
|
||||
|
||||
//~v empty_line_after_outer_attr
|
||||
#[allow(dead_code)]
|
||||
mod foo {}
|
||||
|
||||
//~v empty_line_after_outer_attr
|
||||
#[inline]
|
||||
// Still lint cases where the empty line does not immediately follow the attribute
|
||||
fn comment_before_empty_line() {}
|
||||
|
||||
#[doc = "
|
||||
Returns the escaped value of the textual representation of
|
||||
|
||||
"]
|
||||
pub fn function() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum FooFighter {
|
||||
Bar1,
|
||||
|
||||
Bar2,
|
||||
|
||||
Bar3,
|
||||
|
||||
Bar4,
|
||||
}
|
||||
|
||||
#[crate_type = "lib"]
|
||||
/*
|
||||
|
||||
*/
|
||||
pub struct EmptyLineInBlockComment;
|
||||
|
||||
#[crate_type = "lib"]
|
||||
/* test */
|
||||
pub struct BlockComment;
|
||||
|
||||
// See https://github.com/rust-lang/rust-clippy/issues/5567
|
||||
#[rustfmt::skip]
|
||||
#[fake_async_trait]
|
||||
pub trait Bazz {
|
||||
fn foo() -> Vec<u8> {
|
||||
let _i = "";
|
||||
|
||||
|
||||
|
||||
vec![]
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
#[dummy(string = "first line
|
||||
|
||||
second line
|
||||
")]
|
||||
pub struct Args;
|
||||
|
||||
fn main() {}
|
112
tests/ui/empty_line_after/outer_attribute.rs
Normal file
112
tests/ui/empty_line_after/outer_attribute.rs
Normal file
|
@ -0,0 +1,112 @@
|
|||
//@aux-build:../auxiliary/proc_macro_attr.rs
|
||||
#![warn(clippy::empty_line_after_outer_attr, clippy::empty_line_after_doc_comments)]
|
||||
|
||||
//~v empty_line_after_outer_attr
|
||||
#[crate_type = "lib"]
|
||||
|
||||
fn first_in_crate() {}
|
||||
|
||||
#[macro_use]
|
||||
extern crate proc_macro_attr;
|
||||
|
||||
//~v empty_line_after_outer_attr
|
||||
#[inline]
|
||||
|
||||
/// some comment
|
||||
fn with_one_newline_and_comment() {}
|
||||
|
||||
#[inline]
|
||||
/// some comment
|
||||
fn with_no_newline_and_comment() {}
|
||||
|
||||
//~v empty_line_after_outer_attr
|
||||
#[inline]
|
||||
|
||||
fn with_one_newline() {}
|
||||
|
||||
#[rustfmt::skip]
|
||||
mod two_lines {
|
||||
//~v empty_line_after_outer_attr
|
||||
#[crate_type = "lib"]
|
||||
|
||||
|
||||
fn with_two_newlines() {}
|
||||
}
|
||||
|
||||
//~v empty_line_after_outer_attr
|
||||
#[doc = "doc attributes should be considered attributes"]
|
||||
|
||||
enum Baz {
|
||||
One,
|
||||
Two,
|
||||
}
|
||||
|
||||
//~v empty_line_after_outer_attr
|
||||
#[repr(C)]
|
||||
|
||||
struct Foo {
|
||||
one: isize,
|
||||
two: isize,
|
||||
}
|
||||
|
||||
//~v empty_line_after_outer_attr
|
||||
#[allow(dead_code)]
|
||||
|
||||
mod foo {}
|
||||
|
||||
//~v empty_line_after_outer_attr
|
||||
#[inline]
|
||||
// Still lint cases where the empty line does not immediately follow the attribute
|
||||
|
||||
fn comment_before_empty_line() {}
|
||||
|
||||
#[doc = "
|
||||
Returns the escaped value of the textual representation of
|
||||
|
||||
"]
|
||||
pub fn function() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum FooFighter {
|
||||
Bar1,
|
||||
|
||||
Bar2,
|
||||
|
||||
Bar3,
|
||||
|
||||
Bar4,
|
||||
}
|
||||
|
||||
#[crate_type = "lib"]
|
||||
/*
|
||||
|
||||
*/
|
||||
pub struct EmptyLineInBlockComment;
|
||||
|
||||
#[crate_type = "lib"]
|
||||
/* test */
|
||||
pub struct BlockComment;
|
||||
|
||||
// See https://github.com/rust-lang/rust-clippy/issues/5567
|
||||
#[rustfmt::skip]
|
||||
#[fake_async_trait]
|
||||
pub trait Bazz {
|
||||
fn foo() -> Vec<u8> {
|
||||
let _i = "";
|
||||
|
||||
|
||||
|
||||
vec![]
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
#[dummy(string = "first line
|
||||
|
||||
second line
|
||||
")]
|
||||
pub struct Args;
|
||||
|
||||
fn main() {}
|
103
tests/ui/empty_line_after/outer_attribute.stderr
Normal file
103
tests/ui/empty_line_after/outer_attribute.stderr
Normal file
|
@ -0,0 +1,103 @@
|
|||
error: empty line after outer attribute
|
||||
--> tests/ui/empty_line_after/outer_attribute.rs:5:1
|
||||
|
|
||||
LL | / #[crate_type = "lib"]
|
||||
LL | |
|
||||
| |_
|
||||
LL | fn first_in_crate() {}
|
||||
| ------------------- the attribute applies to this function
|
||||
|
|
||||
= note: `-D clippy::empty-line-after-outer-attr` implied by `-D warnings`
|
||||
= help: to override `-D warnings` add `#[allow(clippy::empty_line_after_outer_attr)]`
|
||||
= help: if the empty line is unintentional remove it
|
||||
help: if the attribute should apply to the crate use an inner attribute
|
||||
|
|
||||
LL | #![crate_type = "lib"]
|
||||
| +
|
||||
|
||||
error: empty line after outer attribute
|
||||
--> tests/ui/empty_line_after/outer_attribute.rs:13:1
|
||||
|
|
||||
LL | / #[inline]
|
||||
LL | |
|
||||
| |_
|
||||
LL | /// some comment
|
||||
LL | fn with_one_newline_and_comment() {}
|
||||
| --------------------------------- the attribute applies to this function
|
||||
|
|
||||
= help: if the empty line is unintentional remove it
|
||||
|
||||
error: empty line after outer attribute
|
||||
--> tests/ui/empty_line_after/outer_attribute.rs:23:1
|
||||
|
|
||||
LL | / #[inline]
|
||||
LL | |
|
||||
| |_
|
||||
LL | fn with_one_newline() {}
|
||||
| --------------------- the attribute applies to this function
|
||||
|
|
||||
= help: if the empty line is unintentional remove it
|
||||
|
||||
error: empty lines after outer attribute
|
||||
--> tests/ui/empty_line_after/outer_attribute.rs:30:5
|
||||
|
|
||||
LL | / #[crate_type = "lib"]
|
||||
LL | |
|
||||
LL | |
|
||||
| |_
|
||||
LL | fn with_two_newlines() {}
|
||||
| ---------------------- the attribute applies to this function
|
||||
|
|
||||
= help: if the empty lines are unintentional remove them
|
||||
help: if the attribute should apply to the parent module use an inner attribute
|
||||
|
|
||||
LL | #![crate_type = "lib"]
|
||||
| +
|
||||
|
||||
error: empty line after outer attribute
|
||||
--> tests/ui/empty_line_after/outer_attribute.rs:37:1
|
||||
|
|
||||
LL | / #[doc = "doc attributes should be considered attributes"]
|
||||
LL | |
|
||||
| |_
|
||||
LL | enum Baz {
|
||||
| -------- the attribute applies to this enum
|
||||
|
|
||||
= help: if the empty line is unintentional remove it
|
||||
|
||||
error: empty line after outer attribute
|
||||
--> tests/ui/empty_line_after/outer_attribute.rs:45:1
|
||||
|
|
||||
LL | / #[repr(C)]
|
||||
LL | |
|
||||
| |_
|
||||
LL | struct Foo {
|
||||
| ---------- the attribute applies to this struct
|
||||
|
|
||||
= help: if the empty line is unintentional remove it
|
||||
|
||||
error: empty line after outer attribute
|
||||
--> tests/ui/empty_line_after/outer_attribute.rs:53:1
|
||||
|
|
||||
LL | / #[allow(dead_code)]
|
||||
LL | |
|
||||
| |_
|
||||
LL | mod foo {}
|
||||
| ------- the attribute applies to this module
|
||||
|
|
||||
= help: if the empty line is unintentional remove it
|
||||
|
||||
error: empty line after outer attribute
|
||||
--> tests/ui/empty_line_after/outer_attribute.rs:58:1
|
||||
|
|
||||
LL | / #[inline]
|
||||
LL | | // Still lint cases where the empty line does not immediately follow the attribute
|
||||
LL | |
|
||||
| |_
|
||||
LL | fn comment_before_empty_line() {}
|
||||
| ------------------------------ the attribute applies to this function
|
||||
|
|
||||
= help: if the empty line is unintentional remove it
|
||||
|
||||
error: aborting due to 8 previous errors
|
||||
|
|
@ -1,132 +0,0 @@
|
|||
//@aux-build:proc_macro_attr.rs
|
||||
#![warn(clippy::empty_line_after_doc_comments)]
|
||||
#![allow(clippy::assertions_on_constants, clippy::duplicated_attributes)]
|
||||
#![feature(custom_inner_attributes)]
|
||||
#![rustfmt::skip]
|
||||
|
||||
#[macro_use]
|
||||
extern crate proc_macro_attr;
|
||||
|
||||
mod some_mod {
|
||||
//! This doc comment should *NOT* produce a warning
|
||||
|
||||
mod some_inner_mod {
|
||||
fn some_noop() {}
|
||||
}
|
||||
}
|
||||
|
||||
/// This should produce a warning
|
||||
|
||||
fn with_doc_and_newline() { assert!(true)}
|
||||
|
||||
// This should *NOT* produce a warning
|
||||
#[crate_type = "lib"]
|
||||
|
||||
/// some comment
|
||||
fn with_one_newline_and_comment() { assert!(true) }
|
||||
|
||||
// This should *NOT* produce a warning
|
||||
#[crate_type = "lib"]
|
||||
/// some comment
|
||||
fn with_no_newline_and_comment() { assert!(true) }
|
||||
|
||||
|
||||
// This should *NOT* produce a warning
|
||||
#[crate_type = "lib"]
|
||||
|
||||
fn with_one_newline() { assert!(true) }
|
||||
|
||||
// This should *NOT* produce a warning
|
||||
#[crate_type = "lib"]
|
||||
|
||||
|
||||
fn with_two_newlines() { assert!(true) }
|
||||
|
||||
|
||||
// This should *NOT* produce a warning
|
||||
#[crate_type = "lib"]
|
||||
|
||||
enum Baz {
|
||||
One,
|
||||
Two
|
||||
}
|
||||
|
||||
// This should *NOT* produce a warning
|
||||
#[crate_type = "lib"]
|
||||
|
||||
struct Foo {
|
||||
one: isize,
|
||||
two: isize
|
||||
}
|
||||
|
||||
// This should *NOT* produce a warning
|
||||
#[crate_type = "lib"]
|
||||
|
||||
mod foo {
|
||||
}
|
||||
|
||||
/// This doc comment should produce a warning
|
||||
|
||||
/** This is also a doc comment and should produce a warning
|
||||
*/
|
||||
|
||||
// This should *NOT* produce a warning
|
||||
#[allow(non_camel_case_types)]
|
||||
#[allow(missing_docs)]
|
||||
#[allow(missing_docs)]
|
||||
fn three_attributes() { assert!(true) }
|
||||
|
||||
// This should *NOT* produce a warning
|
||||
#[doc = "
|
||||
Returns the escaped value of the textual representation of
|
||||
|
||||
"]
|
||||
pub fn function() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
// This should *NOT* produce a warning
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum FooFighter {
|
||||
Bar1,
|
||||
|
||||
Bar2,
|
||||
|
||||
Bar3,
|
||||
|
||||
Bar4
|
||||
}
|
||||
|
||||
// This should *NOT* produce a warning because the empty line is inside a block comment
|
||||
#[crate_type = "lib"]
|
||||
/*
|
||||
|
||||
*/
|
||||
pub struct S;
|
||||
|
||||
// This should *NOT* produce a warning
|
||||
#[crate_type = "lib"]
|
||||
/* test */
|
||||
pub struct T;
|
||||
|
||||
// This should *NOT* produce a warning
|
||||
// See https://github.com/rust-lang/rust-clippy/issues/5567
|
||||
#[fake_async_trait]
|
||||
pub trait Bazz {
|
||||
fn foo() -> Vec<u8> {
|
||||
let _i = "";
|
||||
|
||||
|
||||
|
||||
vec![]
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
#[dummy(string = "first line
|
||||
|
||||
second line
|
||||
")]
|
||||
pub struct Args;
|
||||
|
||||
fn main() {}
|
|
@ -1,37 +0,0 @@
|
|||
error: found an empty line after a doc comment. Perhaps you need to use `//!` to make a comment on a module, remove the empty line, or make a regular comment with `//`?
|
||||
--> tests/ui/empty_line_after_doc_comments.rs:18:1
|
||||
|
|
||||
LL | / /// This should produce a warning
|
||||
LL | |
|
||||
LL | | fn with_doc_and_newline() { assert!(true)}
|
||||
| |_
|
||||
|
|
||||
= note: `-D clippy::empty-line-after-doc-comments` implied by `-D warnings`
|
||||
= help: to override `-D warnings` add `#[allow(clippy::empty_line_after_doc_comments)]`
|
||||
|
||||
error: found an empty line after a doc comment. Perhaps you need to use `//!` to make a comment on a module, remove the empty line, or make a regular comment with `//`?
|
||||
--> tests/ui/empty_line_after_doc_comments.rs:68:1
|
||||
|
|
||||
LL | / /// This doc comment should produce a warning
|
||||
LL | |
|
||||
LL | | /** This is also a doc comment and should produce a warning
|
||||
LL | | */
|
||||
... |
|
||||
LL | | #[allow(missing_docs)]
|
||||
LL | | fn three_attributes() { assert!(true) }
|
||||
| |_
|
||||
|
||||
error: found an empty line after a doc comment. Perhaps you need to use `//!` to make a comment on a module, remove the empty line, or make a regular comment with `//`?
|
||||
--> tests/ui/empty_line_after_doc_comments.rs:70:1
|
||||
|
|
||||
LL | / /** This is also a doc comment and should produce a warning
|
||||
LL | | */
|
||||
LL | |
|
||||
LL | | // This should *NOT* produce a warning
|
||||
... |
|
||||
LL | | #[allow(missing_docs)]
|
||||
LL | | fn three_attributes() { assert!(true) }
|
||||
| |_
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
|
@ -1,120 +0,0 @@
|
|||
//@aux-build:proc_macro_attr.rs
|
||||
#![warn(clippy::empty_line_after_outer_attr)]
|
||||
#![allow(clippy::assertions_on_constants, clippy::duplicated_attributes)]
|
||||
#![feature(custom_inner_attributes)]
|
||||
#![rustfmt::skip]
|
||||
|
||||
#[macro_use]
|
||||
extern crate proc_macro_attr;
|
||||
|
||||
// This should produce a warning
|
||||
#[crate_type = "lib"]
|
||||
|
||||
/// some comment
|
||||
fn with_one_newline_and_comment() { assert!(true) }
|
||||
|
||||
// This should not produce a warning
|
||||
#[crate_type = "lib"]
|
||||
/// some comment
|
||||
fn with_no_newline_and_comment() { assert!(true) }
|
||||
|
||||
|
||||
// This should produce a warning
|
||||
#[crate_type = "lib"]
|
||||
|
||||
fn with_one_newline() { assert!(true) }
|
||||
|
||||
// This should produce a warning, too
|
||||
#[crate_type = "lib"]
|
||||
|
||||
|
||||
fn with_two_newlines() { assert!(true) }
|
||||
|
||||
|
||||
// This should produce a warning
|
||||
#[crate_type = "lib"]
|
||||
|
||||
enum Baz {
|
||||
One,
|
||||
Two
|
||||
}
|
||||
|
||||
// This should produce a warning
|
||||
#[crate_type = "lib"]
|
||||
|
||||
struct Foo {
|
||||
one: isize,
|
||||
two: isize
|
||||
}
|
||||
|
||||
// This should produce a warning
|
||||
#[crate_type = "lib"]
|
||||
|
||||
mod foo {
|
||||
}
|
||||
|
||||
/// This doc comment should not produce a warning
|
||||
|
||||
/** This is also a doc comment and should not produce a warning
|
||||
*/
|
||||
|
||||
// This should not produce a warning
|
||||
#[allow(non_camel_case_types)]
|
||||
#[allow(missing_docs)]
|
||||
#[allow(missing_docs)]
|
||||
fn three_attributes() { assert!(true) }
|
||||
|
||||
// This should not produce a warning
|
||||
#[doc = "
|
||||
Returns the escaped value of the textual representation of
|
||||
|
||||
"]
|
||||
pub fn function() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
// This should not produce a warning
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum FooFighter {
|
||||
Bar1,
|
||||
|
||||
Bar2,
|
||||
|
||||
Bar3,
|
||||
|
||||
Bar4
|
||||
}
|
||||
|
||||
// This should not produce a warning because the empty line is inside a block comment
|
||||
#[crate_type = "lib"]
|
||||
/*
|
||||
|
||||
*/
|
||||
pub struct S;
|
||||
|
||||
// This should not produce a warning
|
||||
#[crate_type = "lib"]
|
||||
/* test */
|
||||
pub struct T;
|
||||
|
||||
// This should not produce a warning
|
||||
// See https://github.com/rust-lang/rust-clippy/issues/5567
|
||||
#[fake_async_trait]
|
||||
pub trait Bazz {
|
||||
fn foo() -> Vec<u8> {
|
||||
let _i = "";
|
||||
|
||||
|
||||
|
||||
vec![]
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
#[dummy(string = "first line
|
||||
|
||||
second line
|
||||
")]
|
||||
pub struct Args;
|
||||
|
||||
fn main() {}
|
|
@ -1,54 +0,0 @@
|
|||
error: found an empty line after an outer attribute. Perhaps you forgot to add a `!` to make it an inner attribute?
|
||||
--> tests/ui/empty_line_after_outer_attribute.rs:11:1
|
||||
|
|
||||
LL | / #[crate_type = "lib"]
|
||||
LL | |
|
||||
LL | | /// some comment
|
||||
LL | | fn with_one_newline_and_comment() { assert!(true) }
|
||||
| |_
|
||||
|
|
||||
= note: `-D clippy::empty-line-after-outer-attr` implied by `-D warnings`
|
||||
= help: to override `-D warnings` add `#[allow(clippy::empty_line_after_outer_attr)]`
|
||||
|
||||
error: found an empty line after an outer attribute. Perhaps you forgot to add a `!` to make it an inner attribute?
|
||||
--> tests/ui/empty_line_after_outer_attribute.rs:23:1
|
||||
|
|
||||
LL | / #[crate_type = "lib"]
|
||||
LL | |
|
||||
LL | | fn with_one_newline() { assert!(true) }
|
||||
| |_
|
||||
|
||||
error: found an empty line after an outer attribute. Perhaps you forgot to add a `!` to make it an inner attribute?
|
||||
--> tests/ui/empty_line_after_outer_attribute.rs:28:1
|
||||
|
|
||||
LL | / #[crate_type = "lib"]
|
||||
... |
|
||||
LL | | fn with_two_newlines() { assert!(true) }
|
||||
| |_
|
||||
|
||||
error: found an empty line after an outer attribute. Perhaps you forgot to add a `!` to make it an inner attribute?
|
||||
--> tests/ui/empty_line_after_outer_attribute.rs:35:1
|
||||
|
|
||||
LL | / #[crate_type = "lib"]
|
||||
LL | |
|
||||
LL | | enum Baz {
|
||||
| |_
|
||||
|
||||
error: found an empty line after an outer attribute. Perhaps you forgot to add a `!` to make it an inner attribute?
|
||||
--> tests/ui/empty_line_after_outer_attribute.rs:43:1
|
||||
|
|
||||
LL | / #[crate_type = "lib"]
|
||||
LL | |
|
||||
LL | | struct Foo {
|
||||
| |_
|
||||
|
||||
error: found an empty line after an outer attribute. Perhaps you forgot to add a `!` to make it an inner attribute?
|
||||
--> tests/ui/empty_line_after_outer_attribute.rs:51:1
|
||||
|
|
||||
LL | / #[crate_type = "lib"]
|
||||
LL | |
|
||||
LL | | mod foo {
|
||||
| |_
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
#[warn(clippy::exit)]
|
||||
#![warn(clippy::exit)]
|
||||
|
||||
fn not_main() {
|
||||
if true {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#[warn(clippy::exit)]
|
||||
#![warn(clippy::exit)]
|
||||
|
||||
fn also_not_main() {
|
||||
std::process::exit(3);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#[warn(clippy::exit)]
|
||||
#![warn(clippy::exit)]
|
||||
|
||||
fn main() {
|
||||
if true {
|
||||
|
|
|
@ -5,8 +5,6 @@
|
|||
clippy::unnecessary_literal_unwrap
|
||||
)]
|
||||
|
||||
/// Checks implementation of the `EXPECT_FUN_CALL` lint
|
||||
|
||||
macro_rules! one {
|
||||
() => {
|
||||
1
|
||||
|
|
|
@ -5,8 +5,6 @@
|
|||
clippy::unnecessary_literal_unwrap
|
||||
)]
|
||||
|
||||
/// Checks implementation of the `EXPECT_FUN_CALL` lint
|
||||
|
||||
macro_rules! one {
|
||||
() => {
|
||||
1
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
error: use of `expect` followed by a function call
|
||||
--> tests/ui/expect_fun_call.rs:37:26
|
||||
--> tests/ui/expect_fun_call.rs:35:26
|
||||
|
|
||||
LL | with_none_and_format.expect(&format!("Error {}: fake error", error_code));
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!("Error {}: fake error", error_code))`
|
||||
|
@ -8,85 +8,85 @@ LL | with_none_and_format.expect(&format!("Error {}: fake error", error_code
|
|||
= help: to override `-D warnings` add `#[allow(clippy::expect_fun_call)]`
|
||||
|
||||
error: use of `expect` followed by a function call
|
||||
--> tests/ui/expect_fun_call.rs:40:26
|
||||
--> tests/ui/expect_fun_call.rs:38:26
|
||||
|
|
||||
LL | with_none_and_as_str.expect(format!("Error {}: fake error", error_code).as_str());
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!("Error {}: fake error", error_code))`
|
||||
|
||||
error: use of `expect` followed by a function call
|
||||
--> tests/ui/expect_fun_call.rs:43:37
|
||||
--> tests/ui/expect_fun_call.rs:41:37
|
||||
|
|
||||
LL | with_none_and_format_with_macro.expect(format!("Error {}: fake error", one!()).as_str());
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!("Error {}: fake error", one!()))`
|
||||
|
||||
error: use of `expect` followed by a function call
|
||||
--> tests/ui/expect_fun_call.rs:53:25
|
||||
--> tests/ui/expect_fun_call.rs:51:25
|
||||
|
|
||||
LL | with_err_and_format.expect(&format!("Error {}: fake error", error_code));
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|_| panic!("Error {}: fake error", error_code))`
|
||||
|
||||
error: use of `expect` followed by a function call
|
||||
--> tests/ui/expect_fun_call.rs:56:25
|
||||
--> tests/ui/expect_fun_call.rs:54:25
|
||||
|
|
||||
LL | with_err_and_as_str.expect(format!("Error {}: fake error", error_code).as_str());
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|_| panic!("Error {}: fake error", error_code))`
|
||||
|
||||
error: use of `expect` followed by a function call
|
||||
--> tests/ui/expect_fun_call.rs:68:17
|
||||
--> tests/ui/expect_fun_call.rs:66:17
|
||||
|
|
||||
LL | Some("foo").expect(format!("{} {}", 1, 2).as_ref());
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!("{} {}", 1, 2))`
|
||||
|
||||
error: use of `expect` followed by a function call
|
||||
--> tests/ui/expect_fun_call.rs:89:21
|
||||
--> tests/ui/expect_fun_call.rs:87:21
|
||||
|
|
||||
LL | Some("foo").expect(&get_string());
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| { panic!("{}", get_string()) })`
|
||||
|
||||
error: use of `expect` followed by a function call
|
||||
--> tests/ui/expect_fun_call.rs:90:21
|
||||
--> tests/ui/expect_fun_call.rs:88:21
|
||||
|
|
||||
LL | Some("foo").expect(get_string().as_ref());
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| { panic!("{}", get_string()) })`
|
||||
|
||||
error: use of `expect` followed by a function call
|
||||
--> tests/ui/expect_fun_call.rs:91:21
|
||||
--> tests/ui/expect_fun_call.rs:89:21
|
||||
|
|
||||
LL | Some("foo").expect(get_string().as_str());
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| { panic!("{}", get_string()) })`
|
||||
|
||||
error: use of `expect` followed by a function call
|
||||
--> tests/ui/expect_fun_call.rs:93:21
|
||||
--> tests/ui/expect_fun_call.rs:91:21
|
||||
|
|
||||
LL | Some("foo").expect(get_static_str());
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| { panic!("{}", get_static_str()) })`
|
||||
|
||||
error: use of `expect` followed by a function call
|
||||
--> tests/ui/expect_fun_call.rs:94:21
|
||||
--> tests/ui/expect_fun_call.rs:92:21
|
||||
|
|
||||
LL | Some("foo").expect(get_non_static_str(&0));
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| { panic!("{}", get_non_static_str(&0).to_string()) })`
|
||||
|
||||
error: use of `expect` followed by a function call
|
||||
--> tests/ui/expect_fun_call.rs:98:16
|
||||
--> tests/ui/expect_fun_call.rs:96:16
|
||||
|
|
||||
LL | Some(true).expect(&format!("key {}, {}", 1, 2));
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!("key {}, {}", 1, 2))`
|
||||
|
||||
error: use of `expect` followed by a function call
|
||||
--> tests/ui/expect_fun_call.rs:104:17
|
||||
--> tests/ui/expect_fun_call.rs:102:17
|
||||
|
|
||||
LL | opt_ref.expect(&format!("{:?}", opt_ref));
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!("{:?}", opt_ref))`
|
||||
|
||||
error: use of `expect` followed by a function call
|
||||
--> tests/ui/expect_fun_call.rs:108:20
|
||||
--> tests/ui/expect_fun_call.rs:106:20
|
||||
|
|
||||
LL | format_capture.expect(&format!("{error_code}"));
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!("{error_code}"))`
|
||||
|
||||
error: use of `expect` followed by a function call
|
||||
--> tests/ui/expect_fun_call.rs:111:30
|
||||
--> tests/ui/expect_fun_call.rs:109:30
|
||||
|
|
||||
LL | format_capture_and_value.expect(&format!("{error_code}, {}", 1));
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!("{error_code}, {}", 1))`
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
#![allow(clippy::redundant_pattern_matching)]
|
||||
#![allow(clippy::if_same_then_else, clippy::equatable_if_let, clippy::needless_if)]
|
||||
|
||||
/// Tests for match_overlapping_arm
|
||||
|
||||
fn overlapping() {
|
||||
const FOO: u64 = 2;
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
error: some ranges overlap
|
||||
--> tests/ui/match_overlapping_arm.rs:11:9
|
||||
--> tests/ui/match_overlapping_arm.rs:9:9
|
||||
|
|
||||
LL | 0..=10 => println!("0..=10"),
|
||||
| ^^^^^^
|
||||
|
|
||||
note: overlaps with this
|
||||
--> tests/ui/match_overlapping_arm.rs:13:9
|
||||
--> tests/ui/match_overlapping_arm.rs:11:9
|
||||
|
|
||||
LL | 0..=11 => println!("0..=11"),
|
||||
| ^^^^^^
|
||||
|
@ -13,85 +13,85 @@ LL | 0..=11 => println!("0..=11"),
|
|||
= help: to override `-D warnings` add `#[allow(clippy::match_overlapping_arm)]`
|
||||
|
||||
error: some ranges overlap
|
||||
--> tests/ui/match_overlapping_arm.rs:18:9
|
||||
--> tests/ui/match_overlapping_arm.rs:16:9
|
||||
|
|
||||
LL | 0..=5 => println!("0..=5"),
|
||||
| ^^^^^
|
||||
|
|
||||
note: overlaps with this
|
||||
--> tests/ui/match_overlapping_arm.rs:21:9
|
||||
--> tests/ui/match_overlapping_arm.rs:19:9
|
||||
|
|
||||
LL | FOO..=11 => println!("FOO..=11"),
|
||||
| ^^^^^^^^
|
||||
|
||||
error: some ranges overlap
|
||||
--> tests/ui/match_overlapping_arm.rs:56:9
|
||||
--> tests/ui/match_overlapping_arm.rs:54:9
|
||||
|
|
||||
LL | 0..11 => println!("0..11"),
|
||||
| ^^^^^
|
||||
|
|
||||
note: overlaps with this
|
||||
--> tests/ui/match_overlapping_arm.rs:58:9
|
||||
--> tests/ui/match_overlapping_arm.rs:56:9
|
||||
|
|
||||
LL | 0..=11 => println!("0..=11"),
|
||||
| ^^^^^^
|
||||
|
||||
error: some ranges overlap
|
||||
--> tests/ui/match_overlapping_arm.rs:82:9
|
||||
--> tests/ui/match_overlapping_arm.rs:80:9
|
||||
|
|
||||
LL | 0..=10 => println!("0..=10"),
|
||||
| ^^^^^^
|
||||
|
|
||||
note: overlaps with this
|
||||
--> tests/ui/match_overlapping_arm.rs:81:9
|
||||
--> tests/ui/match_overlapping_arm.rs:79:9
|
||||
|
|
||||
LL | 5..14 => println!("5..14"),
|
||||
| ^^^^^
|
||||
|
||||
error: some ranges overlap
|
||||
--> tests/ui/match_overlapping_arm.rs:88:9
|
||||
--> tests/ui/match_overlapping_arm.rs:86:9
|
||||
|
|
||||
LL | 0..7 => println!("0..7"),
|
||||
| ^^^^
|
||||
|
|
||||
note: overlaps with this
|
||||
--> tests/ui/match_overlapping_arm.rs:90:9
|
||||
--> tests/ui/match_overlapping_arm.rs:88:9
|
||||
|
|
||||
LL | 0..=10 => println!("0..=10"),
|
||||
| ^^^^^^
|
||||
|
||||
error: some ranges overlap
|
||||
--> tests/ui/match_overlapping_arm.rs:101:9
|
||||
--> tests/ui/match_overlapping_arm.rs:99:9
|
||||
|
|
||||
LL | ..=23 => println!("..=23"),
|
||||
| ^^^^^
|
||||
|
|
||||
note: overlaps with this
|
||||
--> tests/ui/match_overlapping_arm.rs:103:9
|
||||
--> tests/ui/match_overlapping_arm.rs:101:9
|
||||
|
|
||||
LL | ..26 => println!("..26"),
|
||||
| ^^^^
|
||||
|
||||
error: some ranges overlap
|
||||
--> tests/ui/match_overlapping_arm.rs:111:9
|
||||
--> tests/ui/match_overlapping_arm.rs:109:9
|
||||
|
|
||||
LL | 21..=30 => (),
|
||||
| ^^^^^^^
|
||||
|
|
||||
note: overlaps with this
|
||||
--> tests/ui/match_overlapping_arm.rs:113:9
|
||||
--> tests/ui/match_overlapping_arm.rs:111:9
|
||||
|
|
||||
LL | 21..=40 => (),
|
||||
| ^^^^^^^
|
||||
|
||||
error: some ranges overlap
|
||||
--> tests/ui/match_overlapping_arm.rs:126:9
|
||||
--> tests/ui/match_overlapping_arm.rs:124:9
|
||||
|
|
||||
LL | 0..=0x0000_0000_0000_00ff => (),
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: overlaps with this
|
||||
--> tests/ui/match_overlapping_arm.rs:128:9
|
||||
--> tests/ui/match_overlapping_arm.rs:126:9
|
||||
|
|
||||
LL | 0..=0x0000_0000_0000_ffff => (),
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use std::borrow::Cow;
|
||||
#![warn(clippy::string_slice)]
|
||||
#![allow(clippy::no_effect)]
|
||||
|
||||
#[warn(clippy::string_slice)]
|
||||
#[allow(clippy::no_effect)]
|
||||
use std::borrow::Cow;
|
||||
|
||||
fn main() {
|
||||
&"Ölkanne"[1..];
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#![warn(clippy::tabs_in_doc_comments)]
|
||||
#[allow(dead_code)]
|
||||
|
||||
///
|
||||
/// Struct to hold two strings:
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#![warn(clippy::tabs_in_doc_comments)]
|
||||
#[allow(dead_code)]
|
||||
|
||||
///
|
||||
/// Struct to hold two strings:
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
error: using tabs in doc comments is not recommended
|
||||
--> tests/ui/tabs_in_doc_comments.rs:6:5
|
||||
--> tests/ui/tabs_in_doc_comments.rs:5:5
|
||||
|
|
||||
LL | /// - first one
|
||||
| ^^^^ help: consider using four spaces per tab
|
||||
|
@ -8,43 +8,43 @@ LL | /// - first one
|
|||
= help: to override `-D warnings` add `#[allow(clippy::tabs_in_doc_comments)]`
|
||||
|
||||
error: using tabs in doc comments is not recommended
|
||||
--> tests/ui/tabs_in_doc_comments.rs:6:13
|
||||
--> tests/ui/tabs_in_doc_comments.rs:5:13
|
||||
|
|
||||
LL | /// - first one
|
||||
| ^^^^^^^^ help: consider using four spaces per tab
|
||||
|
||||
error: using tabs in doc comments is not recommended
|
||||
--> tests/ui/tabs_in_doc_comments.rs:7:5
|
||||
--> tests/ui/tabs_in_doc_comments.rs:6:5
|
||||
|
|
||||
LL | /// - second one
|
||||
| ^^^^ help: consider using four spaces per tab
|
||||
|
||||
error: using tabs in doc comments is not recommended
|
||||
--> tests/ui/tabs_in_doc_comments.rs:7:14
|
||||
--> tests/ui/tabs_in_doc_comments.rs:6:14
|
||||
|
|
||||
LL | /// - second one
|
||||
| ^^^^ help: consider using four spaces per tab
|
||||
|
||||
error: using tabs in doc comments is not recommended
|
||||
--> tests/ui/tabs_in_doc_comments.rs:10:9
|
||||
--> tests/ui/tabs_in_doc_comments.rs:9:9
|
||||
|
|
||||
LL | /// - First String:
|
||||
| ^^^^ help: consider using four spaces per tab
|
||||
|
||||
error: using tabs in doc comments is not recommended
|
||||
--> tests/ui/tabs_in_doc_comments.rs:11:9
|
||||
--> tests/ui/tabs_in_doc_comments.rs:10:9
|
||||
|
|
||||
LL | /// - needs to be inside here
|
||||
| ^^^^^^^^ help: consider using four spaces per tab
|
||||
|
||||
error: using tabs in doc comments is not recommended
|
||||
--> tests/ui/tabs_in_doc_comments.rs:14:9
|
||||
--> tests/ui/tabs_in_doc_comments.rs:13:9
|
||||
|
|
||||
LL | /// - Second String:
|
||||
| ^^^^ help: consider using four spaces per tab
|
||||
|
||||
error: using tabs in doc comments is not recommended
|
||||
--> tests/ui/tabs_in_doc_comments.rs:15:9
|
||||
--> tests/ui/tabs_in_doc_comments.rs:14:9
|
||||
|
|
||||
LL | /// - needs to be inside here
|
||||
| ^^^^^^^^ help: consider using four spaces per tab
|
||||
|
|
Loading…
Reference in a new issue