Merge branch 'master' into fix-4437

This commit is contained in:
Michael Wright
2019-08-29 08:17:36 +02:00
59 changed files with 680 additions and 181 deletions
+17 -1
View File
@@ -145,13 +145,28 @@ using that version of Rust.
You can use [rustup-toolchain-install-master][rtim] to do that:
```
```bash
cargo install rustup-toolchain-install-master
rustup-toolchain-install-master -n master --force
rustup override set master
cargo test
```
After fixing the build failure on this repository, we can submit a pull request
to [`rust-lang/rust`] to fix the toolstate.
To submit a pull request, you should follow these steps:
```bash
# Assuming you already cloned the rust-lang/rust repo and you're in the correct directory
git submodule update --remote src/tools/clippy
cargo update -p clippy
git add -u
git commit -m "Update Clippy"
./x.py test -i --stage 1 src/tools/clippy # This is optional and should succeed anyway
# Open a PR in rust-lang/rust
```
## Issue and PR triage
Clippy is following the [Rust triage procedure][triage] for issues and pull
@@ -211,3 +226,4 @@ or the [MIT](http://opensource.org/licenses/MIT) license.
[homu]: https://github.com/servo/homu
[homu_instructions]: https://buildbot2.rust-lang.org/homu/
[homu_queue]: https://buildbot2.rust-lang.org/homu/queue/clippy
[`rust-lang/rust`]: https://github.com/rust-lang/rust
+2 -2
View File
@@ -47,8 +47,8 @@ fn check_expr(&mut self, cx: &LateContext<'_, '_>, expr: &Expr) {
then {
let body = cx.tcx.hir().body(body_id);
if_chain! {
if body.arguments.len() == 1;
if let Some(argname) = get_pat_name(&body.arguments[0].pat);
if body.params.len() == 1;
if let Some(argname) = get_pat_name(&body.params[0].pat);
if let ExprKind::Binary(ref op, ref l, ref r) = body.value.node;
if op.node == BinOpKind::Eq;
if match_type(cx,
+1 -1
View File
@@ -108,7 +108,7 @@ fn is_argument(map: &hir::map::Map<'_>, id: HirId) -> bool {
}
match map.find(map.get_parent_node(id)) {
Some(Node::Arg(_)) => true,
Some(Node::Param(_)) => true,
_ => false,
}
}
+4 -1
View File
@@ -202,7 +202,10 @@ fn get_type_name(cx: &LateContext<'_, '_>, ty: Ty<'_>) -> String {
}
}
fn compare_inputs(closure_inputs: &mut dyn Iterator<Item = &Arg>, call_args: &mut dyn Iterator<Item = &Expr>) -> bool {
fn compare_inputs(
closure_inputs: &mut dyn Iterator<Item = &Param>,
call_args: &mut dyn Iterator<Item = &Expr>,
) -> bool {
for (closure_input, function_arg) in closure_inputs.zip(call_args) {
if let PatKind::Binding(_, _, ident, _) = closure_input.pat.node {
// XXXManishearth Should I be checking the binding mode here?
+1 -1
View File
@@ -280,7 +280,7 @@ fn check_raw_ptr(
}
}
fn raw_ptr_arg(arg: &hir::Arg, ty: &hir::Ty) -> Option<hir::HirId> {
fn raw_ptr_arg(arg: &hir::Param, ty: &hir::Ty) -> Option<hir::HirId> {
if let (&hir::PatKind::Binding(_, id, _, _), &hir::TyKind::Ptr(_)) = (&arg.pat.node, &ty.node) {
Some(id)
} else {
+1
View File
@@ -104,6 +104,7 @@ fn check_impl_item(&mut self, cx: &LateContext<'a, 'tcx>, impl_item: &'tcx ImplI
if impl_item.ident.name.as_str() == "to_string";
let decl = &signature.decl;
if decl.implicit_self.has_implicit_self();
if decl.inputs.len() == 1;
// Check if return type is String
if match_type(cx, return_ty(cx, impl_item.hir_id), &paths::STRING);
+8
View File
@@ -312,6 +312,14 @@
/// for i in 0..v.len() { foo(v[i]); }
/// for i in 0..v.len() { bar(i, v[i]); }
/// ```
/// Could be written as
/// ```rust
/// # let v = vec![1];
/// # fn foo(bar: usize) {}
/// # fn bar(bar: usize, baz: usize) {}
/// for item in &v { foo(*item); }
/// for (i, item) in v.iter().enumerate() { bar(i, *item); }
/// ```
pub EXPLICIT_COUNTER_LOOP,
complexity,
"for-looping with an explicit counter when `_.enumerate()` would do"
+1 -1
View File
@@ -57,7 +57,7 @@ fn check_expr(&mut self, cx: &LateContext<'_, '_>, e: &hir::Expr) {
let closure_body = cx.tcx.hir().body(body_id);
let closure_expr = remove_blocks(&closure_body.value);
then {
match closure_body.arguments[0].pat.node {
match closure_body.params[0].pat.node {
hir::PatKind::Ref(ref inner, _) => if let hir::PatKind::Binding(
hir::BindingAnnotation::Unannotated, .., name, None
) = inner.node {
+4 -1
View File
@@ -161,7 +161,10 @@ fn reduce_unit_expression<'a>(cx: &LateContext<'_, '_>, expr: &'a hir::Expr) ->
}
}
fn unit_closure<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'a hir::Expr) -> Option<(&'tcx hir::Arg, &'a hir::Expr)> {
fn unit_closure<'a, 'tcx>(
cx: &LateContext<'a, 'tcx>,
expr: &'a hir::Expr,
) -> Option<(&'tcx hir::Param, &'a hir::Expr)> {
if let hir::ExprKind::Closure(_, ref decl, inner_expr_id, _, _) = expr.node {
let body = cx.tcx.hir().body(inner_expr_id);
let body_expr = &body.value;
+28 -6
View File
@@ -302,6 +302,11 @@
/// # let vec = vec![1];
/// vec.iter().filter(|x| **x == 0).next();
/// ```
/// Could be written as
/// ```rust
/// # let vec = vec![1];
/// vec.iter().find(|x| **x == 0);
/// ```
pub FILTER_NEXT,
complexity,
"using `filter(p).next()`, which is more succinctly expressed as `.find(p)`"
@@ -425,6 +430,11 @@
/// # let vec = vec![1];
/// vec.iter().find(|x| **x == 0).is_some();
/// ```
/// Could be written as
/// ```rust
/// # let vec = vec![1];
/// vec.iter().any(|x| *x == 0);
/// ```
pub SEARCH_IS_SOME,
complexity,
"using an iterator search followed by `is_some()`, which is more succinctly expressed as a call to `any()`"
@@ -442,7 +452,12 @@
/// **Example:**
/// ```rust
/// let name = "foo";
/// name.chars().next() == Some('_');
/// if name.chars().next() == Some('_') {};
/// ```
/// Could be written as
/// ```rust
/// let name = "foo";
/// if name.starts_with('_') {};
/// ```
pub CHARS_NEXT_CMP,
complexity,
@@ -889,6 +904,10 @@
/// ```rust
/// let _ = [1, 2, 3].into_iter().map(|x| *x).collect::<Vec<u32>>();
/// ```
/// Could be written as:
/// ```rust
/// let _ = [1, 2, 3].iter().map(|x| *x).collect::<Vec<u32>>();
/// ```
pub INTO_ITER_ON_ARRAY,
correctness,
"using `.into_iter()` on an array"
@@ -1713,8 +1732,8 @@ fn check_fold_with_op(
if bin_op.node == op;
// Extract the names of the two arguments to the closure
if let Some(first_arg_ident) = get_arg_name(&closure_body.arguments[0].pat);
if let Some(second_arg_ident) = get_arg_name(&closure_body.arguments[1].pat);
if let Some(first_arg_ident) = get_arg_name(&closure_body.params[0].pat);
if let Some(second_arg_ident) = get_arg_name(&closure_body.params[1].pat);
if match_var(&*left_expr, first_arg_ident);
if replacement_has_args || match_var(&*right_expr, second_arg_ident);
@@ -2326,7 +2345,7 @@ fn lint_flat_map_identity<'a, 'tcx>(
if let hir::ExprKind::Closure(_, _, body_id, _, _) = arg_node;
let body = cx.tcx.hir().body(*body_id);
if let hir::PatKind::Binding(_, _, binding_ident, _) = body.arguments[0].pat.node;
if let hir::PatKind::Binding(_, _, binding_ident, _) = body.params[0].pat.node;
if let hir::ExprKind::Path(hir::QPath::Resolved(_, ref path)) = body.value.node;
if path.segments.len() == 1;
@@ -2371,7 +2390,7 @@ fn lint_search_is_some<'a, 'tcx>(
if search_method == "find";
if let hir::ExprKind::Closure(_, _, body_id, ..) = search_args[1].node;
let closure_body = cx.tcx.hir().body(body_id);
if let Some(closure_arg) = closure_body.arguments.get(0);
if let Some(closure_arg) = closure_body.params.get(0);
if let hir::PatKind::Ref(..) = closure_arg.pat.node;
then {
Some(search_snippet.replacen('&', "", 1))
@@ -2781,7 +2800,10 @@ fn matches_ref<'a>(
hir::Mutability::MutMutable => &paths::ASMUT_TRAIT,
};
let trait_def_id = get_trait_def_id(cx, trait_path).expect("trait def id not found");
let trait_def_id = match get_trait_def_id(cx, trait_path) {
Some(did) => did,
None => return false,
};
implements_trait(cx, ty, trait_def_id, &[parent_ty.into()])
}
@@ -17,7 +17,7 @@ pub(super) fn lint(cx: &LateContext<'_, '_>, expr: &hir::Expr, args: &[hir::Expr
if let hir::ExprKind::Closure(_, _, body_id, ..) = args[1].node {
let body = cx.tcx.hir().body(body_id);
let arg_id = body.arguments[0].pat.hir_id;
let arg_id = body.params[0].pat.hir_id;
let mutates_arg = match mutated_variables(&body.value, cx) {
Some(used_mutably) => used_mutably.contains(&arg_id),
None => true,
+6
View File
@@ -105,6 +105,12 @@
/// # let y = String::from("foo");
/// if x.to_owned() == y {}
/// ```
/// Could be written as
/// ```rust
/// # let x = "foo";
/// # let y = String::from("foo");
/// if x == y {}
/// ```
pub CMP_OWNED,
perf,
"creating owned instances for comparing with others, e.g., `x == \"foo\".to_string()`"
+73 -73
View File
@@ -6,7 +6,6 @@
use rustc::{declare_lint_pass, declare_tool_lint};
use rustc_data_structures::fx::FxHashMap;
use rustc_errors::Applicability;
use std::char;
use syntax::ast::*;
use syntax::source_map::Span;
use syntax::visit::{walk_expr, FnKind, Visitor};
@@ -391,92 +390,93 @@ fn check_block(&mut self, cx: &EarlyContext<'_>, block: &Block) {
impl MiscEarlyLints {
fn check_lit(self, cx: &EarlyContext<'_>, lit: &Lit) {
if_chain! {
if let LitKind::Int(value, ..) = lit.node;
if let Some(src) = snippet_opt(cx, lit.span);
if let Some(firstch) = src.chars().next();
if char::to_digit(firstch, 10).is_some();
then {
let mut prev = '\0';
for (idx, ch) in src.chars().enumerate() {
if ch == 'i' || ch == 'u' {
if prev != '_' {
span_lint_and_sugg(
cx,
UNSEPARATED_LITERAL_SUFFIX,
lit.span,
"integer type suffix should be separated by an underscore",
"add an underscore",
format!("{}_{}", &src[0..idx], &src[idx..]),
Applicability::MachineApplicable,
);
}
break;
}
prev = ch;
// The `line!()` macro is compiler built-in and a special case for these lints.
let lit_snip = match snippet_opt(cx, lit.span) {
Some(snip) => {
if snip.contains('!') {
return;
}
if src.starts_with("0x") {
let mut seen = (false, false);
for ch in src.chars() {
match ch {
'a' ..= 'f' => seen.0 = true,
'A' ..= 'F' => seen.1 = true,
'i' | 'u' => break, // start of suffix already
_ => ()
}
snip
},
_ => return,
};
if let LitKind::Int(value, lit_int_type) = lit.node {
let suffix = match lit_int_type {
LitIntType::Signed(ty) => ty.ty_to_string(),
LitIntType::Unsigned(ty) => ty.ty_to_string(),
LitIntType::Unsuffixed => "",
};
let maybe_last_sep_idx = lit_snip.len() - suffix.len() - 1;
// Do not lint when literal is unsuffixed.
if !suffix.is_empty() && lit_snip.as_bytes()[maybe_last_sep_idx] != b'_' {
span_lint_and_sugg(
cx,
UNSEPARATED_LITERAL_SUFFIX,
lit.span,
"integer type suffix should be separated by an underscore",
"add an underscore",
format!("{}_{}", &lit_snip[..=maybe_last_sep_idx], suffix),
Applicability::MachineApplicable,
);
}
if lit_snip.starts_with("0x") {
let mut seen = (false, false);
for ch in lit_snip.as_bytes()[2..=maybe_last_sep_idx].iter() {
match ch {
b'a'..=b'f' => seen.0 = true,
b'A'..=b'F' => seen.1 = true,
_ => {},
}
if seen.0 && seen.1 {
span_lint(cx, MIXED_CASE_HEX_LITERALS, lit.span,
"inconsistent casing in hexadecimal literal");
span_lint(
cx,
MIXED_CASE_HEX_LITERALS,
lit.span,
"inconsistent casing in hexadecimal literal",
);
break;
}
} else if src.starts_with("0b") || src.starts_with("0o") {
/* nothing to do */
} else if value != 0 && src.starts_with('0') {
span_lint_and_then(cx,
ZERO_PREFIXED_LITERAL,
lit.span,
"this is a decimal constant",
|db| {
}
} else if lit_snip.starts_with("0b") || lit_snip.starts_with("0o") {
/* nothing to do */
} else if value != 0 && lit_snip.starts_with('0') {
span_lint_and_then(
cx,
ZERO_PREFIXED_LITERAL,
lit.span,
"this is a decimal constant",
|db| {
db.span_suggestion(
lit.span,
"if you mean to use a decimal constant, remove the `0` to remove confusion",
src.trim_start_matches(|c| c == '_' || c == '0').to_string(),
"if you mean to use a decimal constant, remove the `0` to avoid confusion",
lit_snip.trim_start_matches(|c| c == '_' || c == '0').to_string(),
Applicability::MaybeIncorrect,
);
db.span_suggestion(
lit.span,
"if you mean to use an octal constant, use `0o`",
format!("0o{}", src.trim_start_matches(|c| c == '_' || c == '0')),
format!("0o{}", lit_snip.trim_start_matches(|c| c == '_' || c == '0')),
Applicability::MaybeIncorrect,
);
});
}
},
);
}
}
if_chain! {
if let LitKind::Float(..) = lit.node;
if let Some(src) = snippet_opt(cx, lit.span);
if let Some(firstch) = src.chars().next();
if char::to_digit(firstch, 10).is_some();
then {
let mut prev = '\0';
for (idx, ch) in src.chars().enumerate() {
if ch == 'f' {
if prev != '_' {
span_lint_and_sugg(
cx,
UNSEPARATED_LITERAL_SUFFIX,
lit.span,
"float type suffix should be separated by an underscore",
"add an underscore",
format!("{}_{}", &src[0..idx], &src[idx..]),
Applicability::MachineApplicable,
);
}
break;
}
prev = ch;
}
} else if let LitKind::Float(_, float_ty) = lit.node {
let suffix = float_ty.ty_to_string();
let maybe_last_sep_idx = lit_snip.len() - suffix.len() - 1;
if lit_snip.as_bytes()[maybe_last_sep_idx] != b'_' {
span_lint_and_sugg(
cx,
UNSEPARATED_LITERAL_SUFFIX,
lit.span,
"float type suffix should be separated by an underscore",
"add an underscore",
format!("{}_{}", &lit_snip[..=maybe_last_sep_idx], suffix),
Applicability::MachineApplicable,
);
}
}
}
+1 -1
View File
@@ -196,7 +196,7 @@ fn check_struct_field(&mut self, cx: &LateContext<'a, 'tcx>, sf: &'tcx hir::Stru
}
}
fn check_variant(&mut self, cx: &LateContext<'a, 'tcx>, v: &'tcx hir::Variant, _: &hir::Generics) {
fn check_variant(&mut self, cx: &LateContext<'a, 'tcx>, v: &'tcx hir::Variant) {
self.check_missing_docs_attrs(cx, &v.attrs, v.span, "a variant");
}
}
+4
View File
@@ -31,6 +31,10 @@
/// true
/// }
/// ```
/// Could be written as
/// ```rust,ignore
/// !x
/// ```
pub NEEDLESS_BOOL,
complexity,
"if-statements with plain booleans in the then- and else-clause, e.g., `if p { true } else { false }`"
+1 -1
View File
@@ -152,7 +152,7 @@ fn check_fn(
let fn_sig = cx.tcx.fn_sig(fn_def_id);
let fn_sig = cx.tcx.erase_late_bound_regions(&fn_sig);
for (idx, ((input, &ty), arg)) in decl.inputs.iter().zip(fn_sig.inputs()).zip(&body.arguments).enumerate() {
for (idx, ((input, &ty), arg)) in decl.inputs.iter().zip(fn_sig.inputs()).zip(&body.params).enumerate() {
// All spans generated from a proc-macro invocation are the same...
if span == input.span {
return;
+13
View File
@@ -43,6 +43,11 @@
/// # let x = vec![1];
/// x.iter().zip(0..x.len());
/// ```
/// Could be written as
/// ```rust
/// # let x = vec![1];
/// x.iter().enumerate();
/// ```
pub RANGE_ZIP_WITH_LEN,
complexity,
"zipping iterator with a range when `enumerate()` would do"
@@ -64,6 +69,10 @@
/// ```rust,ignore
/// for x..(y+1) { .. }
/// ```
/// Could be written as
/// ```rust,ignore
/// for x..=y { .. }
/// ```
pub RANGE_PLUS_ONE,
complexity,
"`x..(y+1)` reads better as `x..=y`"
@@ -82,6 +91,10 @@
/// ```rust,ignore
/// for x..=(y-1) { .. }
/// ```
/// Could be written as
/// ```rust,ignore
/// for x..y { .. }
/// ```
pub RANGE_MINUS_ONE,
complexity,
"`x..=(y-1)` reads better as `x..y`"
+1 -1
View File
@@ -277,7 +277,7 @@ fn check_block(&mut self, cx: &EarlyContext<'_>, block: &ast::Block) {
if_chain! {
if let Some(ref stmt) = block.stmts.last();
if let ast::StmtKind::Expr(ref expr) = stmt.node;
if is_unit_expr(expr) && !expr.span.from_expansion();
if is_unit_expr(expr) && !stmt.span.from_expansion();
then {
let sp = expr.span;
span_lint_and_then(cx, UNUSED_UNIT, sp, "unneeded unit expression", |db| {
+6
View File
@@ -52,6 +52,12 @@
/// a = b;
/// b = a;
/// ```
/// Could be written as:
/// ```rust
/// # let mut a = 1;
/// # let mut b = 2;
/// std::mem::swap(&mut a, &mut b);
/// ```
pub ALMOST_SWAPPED,
correctness,
"`foo = bar; bar = foo` sequence"
+1 -1
View File
@@ -2056,7 +2056,7 @@ fn suggestion<'a, 'tcx>(
continue;
}
let generics_suggestion_span = generics.span.substitute_dummy({
let pos = snippet_opt(cx, item.span.until(body.arguments[0].pat.span))
let pos = snippet_opt(cx, item.span.until(body.params[0].pat.span))
.and_then(|snip| {
let i = snip.find("fn")?;
Some(item.span.lo() + BytePos((i + (&snip[i..]).find('(')?) as u32))
+2 -2
View File
@@ -90,12 +90,12 @@ fn check_trait_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx hir::Trai
done();
}
fn check_variant(&mut self, cx: &LateContext<'a, 'tcx>, var: &'tcx hir::Variant, generics: &hir::Generics) {
fn check_variant(&mut self, cx: &LateContext<'a, 'tcx>, var: &'tcx hir::Variant) {
if !has_attr(cx.sess(), &var.attrs) {
return;
}
prelude();
PrintVisitor::new("var").visit_variant(var, generics, hir::DUMMY_HIR_ID);
PrintVisitor::new("var").visit_variant(var, &hir::Generics::empty(), hir::DUMMY_HIR_ID);
done();
}
+6 -4
View File
@@ -261,6 +261,7 @@ pub fn path_to_res(cx: &LateContext<'_, '_>, path: &[&str]) -> Option<(def::Res)
}
/// Convenience function to get the `DefId` of a trait by path.
/// It could be a trait or trait alias.
pub fn get_trait_def_id(cx: &LateContext<'_, '_>, path: &[&str]) -> Option<DefId> {
let res = match path_to_res(cx, path) {
Some(res) => res,
@@ -268,7 +269,8 @@ pub fn get_trait_def_id(cx: &LateContext<'_, '_>, path: &[&str]) -> Option<DefId
};
match res {
def::Res::Def(DefKind::Trait, trait_id) => Some(trait_id),
Res::Def(DefKind::Trait, trait_id) | Res::Def(DefKind::TraitAlias, trait_id) => Some(trait_id),
Res::Err => unreachable!("this trait resolution is impossible: {:?}", &path),
_ => None,
}
}
@@ -833,7 +835,7 @@ pub fn remove_blocks(expr: &Expr) -> &Expr {
}
}
pub fn is_self(slf: &Arg) -> bool {
pub fn is_self(slf: &Param) -> bool {
if let PatKind::Binding(.., name, _) = slf.pat.node {
name.name == kw::SelfLower
} else {
@@ -853,8 +855,8 @@ pub fn is_self_ty(slf: &hir::Ty) -> bool {
false
}
pub fn iter_input_pats<'tcx>(decl: &FnDecl, body: &'tcx Body) -> impl Iterator<Item = &'tcx Arg> {
(0..decl.inputs.len()).map(move |i| &body.arguments[i])
pub fn iter_input_pats<'tcx>(decl: &FnDecl, body: &'tcx Body) -> impl Iterator<Item = &'tcx Param> {
(0..decl.inputs.len()).map(move |i| &body.params[i])
}
/// Checks if a given expression is a match expression expanded from the `?`
+2 -2
View File
@@ -13,7 +13,7 @@ pub fn get_spans(
replacements: &[(&'static str, &'static str)],
) -> Option<Vec<(Span, Cow<'static, str>)>> {
if let Some(body) = opt_body_id.map(|id| cx.tcx.hir().body(id)) {
get_binding_name(&body.arguments[idx]).map_or_else(
get_binding_name(&body.params[idx]).map_or_else(
|| Some(vec![]),
|name| extract_clone_suggestions(cx, name, replacements, body),
)
@@ -80,6 +80,6 @@ fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
}
}
fn get_binding_name(arg: &Arg) -> Option<Name> {
fn get_binding_name(arg: &Param) -> Option<Name> {
get_pat_name(&arg.pat)
}
+2
View File
@@ -86,6 +86,8 @@ test. That allows us to check if the output is turning into what we want.
Once we are satisfied with the output, we need to run
`tests/ui/update-all-references.sh` to update the `.stderr` file for our lint.
Please note that, we should run `TESTNAME=ui/foo_functions cargo uitest`
every time before running `tests/ui/update-all-references.sh`.
Running `TESTNAME=ui/foo_functions cargo uitest` should pass then. When we
commit our lint, we need to commit the generated `.stderr` files, too.
View File
View File
+72
View File
@@ -0,0 +1,72 @@
// run-rustfix
#[warn(clippy::cmp_owned)]
#[allow(clippy::unnecessary_operation, clippy::no_effect, unused_must_use, clippy::eq_op)]
fn main() {
fn with_to_string(x: &str) {
x != "foo";
"foo" != x;
}
let x = "oh";
with_to_string(x);
x != "foo";
x != "foo";
42.to_string() == "42";
Foo == Foo;
"abc".chars().filter(|c| *c != 'X');
"abc".chars().filter(|c| *c != 'X');
}
struct Foo;
impl PartialEq for Foo {
// Allow this here, because it emits the lint
// without a suggestion. This is tested in
// `tests/ui/cmp_owned/without_suggestion.rs`
#[allow(clippy::cmp_owned)]
fn eq(&self, other: &Self) -> bool {
self.to_owned() == *other
}
}
impl ToOwned for Foo {
type Owned = Bar;
fn to_owned(&self) -> Bar {
Bar
}
}
#[derive(PartialEq)]
struct Bar;
impl PartialEq<Foo> for Bar {
fn eq(&self, _: &Foo) -> bool {
true
}
}
impl std::borrow::Borrow<Foo> for Bar {
fn borrow(&self) -> &Foo {
static FOO: Foo = Foo;
&FOO
}
}
#[derive(PartialEq)]
struct Baz;
impl ToOwned for Baz {
type Owned = Baz;
fn to_owned(&self) -> Baz {
Baz
}
}
@@ -1,5 +1,7 @@
// run-rustfix
#[warn(clippy::cmp_owned)]
#[allow(clippy::unnecessary_operation)]
#[allow(clippy::unnecessary_operation, clippy::no_effect, unused_must_use, clippy::eq_op)]
fn main() {
fn with_to_string(x: &str) {
x != "foo".to_string();
@@ -22,21 +24,15 @@ fn with_to_string(x: &str) {
"abc".chars().filter(|c| c.to_owned() != 'X');
"abc".chars().filter(|c| *c != 'X');
let x = &Baz;
let y = &Baz;
y.to_owned() == *x;
let x = &&Baz;
let y = &Baz;
y.to_owned() == **x;
}
struct Foo;
impl PartialEq for Foo {
// Allow this here, because it emits the lint
// without a suggestion. This is tested in
// `tests/ui/cmp_owned/without_suggestion.rs`
#[allow(clippy::cmp_owned)]
fn eq(&self, other: &Self) -> bool {
self.to_owned() == *other
}
@@ -1,5 +1,5 @@
error: this creates an owned instance just for comparison
--> $DIR/cmp_owned.rs:5:14
--> $DIR/with_suggestion.rs:7:14
|
LL | x != "foo".to_string();
| ^^^^^^^^^^^^^^^^^ help: try: `"foo"`
@@ -7,52 +7,34 @@ LL | x != "foo".to_string();
= note: `-D clippy::cmp-owned` implied by `-D warnings`
error: this creates an owned instance just for comparison
--> $DIR/cmp_owned.rs:7:9
--> $DIR/with_suggestion.rs:9:9
|
LL | "foo".to_string() != x;
| ^^^^^^^^^^^^^^^^^ help: try: `"foo"`
error: this creates an owned instance just for comparison
--> $DIR/cmp_owned.rs:14:10
--> $DIR/with_suggestion.rs:16:10
|
LL | x != "foo".to_owned();
| ^^^^^^^^^^^^^^^^ help: try: `"foo"`
error: this creates an owned instance just for comparison
--> $DIR/cmp_owned.rs:16:10
--> $DIR/with_suggestion.rs:18:10
|
LL | x != String::from("foo");
| ^^^^^^^^^^^^^^^^^^^ help: try: `"foo"`
error: this creates an owned instance just for comparison
--> $DIR/cmp_owned.rs:20:5
--> $DIR/with_suggestion.rs:22:5
|
LL | Foo.to_owned() == Foo;
| ^^^^^^^^^^^^^^ help: try: `Foo`
error: this creates an owned instance just for comparison
--> $DIR/cmp_owned.rs:22:30
--> $DIR/with_suggestion.rs:24:30
|
LL | "abc".chars().filter(|c| c.to_owned() != 'X');
| ^^^^^^^^^^^^ help: try: `*c`
error: this creates an owned instance just for comparison
--> $DIR/cmp_owned.rs:29:5
|
LL | y.to_owned() == *x;
| ^^^^^^^^^^^^^^^^^^ try implementing the comparison without allocating
error: this creates an owned instance just for comparison
--> $DIR/cmp_owned.rs:34:5
|
LL | y.to_owned() == **x;
| ^^^^^^^^^^^^^^^^^^^ try implementing the comparison without allocating
error: this creates an owned instance just for comparison
--> $DIR/cmp_owned.rs:41:9
|
LL | self.to_owned() == *other
| ^^^^^^^^^^^^^^^^^^^^^^^^^ try implementing the comparison without allocating
error: aborting due to 9 previous errors
error: aborting due to 6 previous errors
+52
View File
@@ -0,0 +1,52 @@
#[allow(clippy::unnecessary_operation)]
fn main() {
let x = &Baz;
let y = &Baz;
y.to_owned() == *x;
let x = &&Baz;
let y = &Baz;
y.to_owned() == **x;
}
struct Foo;
impl PartialEq for Foo {
fn eq(&self, other: &Self) -> bool {
self.to_owned() == *other
}
}
impl ToOwned for Foo {
type Owned = Bar;
fn to_owned(&self) -> Bar {
Bar
}
}
#[derive(PartialEq)]
struct Baz;
impl ToOwned for Baz {
type Owned = Baz;
fn to_owned(&self) -> Baz {
Baz
}
}
#[derive(PartialEq)]
struct Bar;
impl PartialEq<Foo> for Bar {
fn eq(&self, _: &Foo) -> bool {
true
}
}
impl std::borrow::Borrow<Foo> for Bar {
fn borrow(&self) -> &Foo {
static FOO: Foo = Foo;
&FOO
}
}
@@ -0,0 +1,22 @@
error: this creates an owned instance just for comparison
--> $DIR/without_suggestion.rs:6:5
|
LL | y.to_owned() == *x;
| ^^^^^^^^^^^^^^^^^^ try implementing the comparison without allocating
|
= note: `-D clippy::cmp-owned` implied by `-D warnings`
error: this creates an owned instance just for comparison
--> $DIR/without_suggestion.rs:10:5
|
LL | y.to_owned() == **x;
| ^^^^^^^^^^^^^^^^^^^ try implementing the comparison without allocating
error: this creates an owned instance just for comparison
--> $DIR/without_suggestion.rs:17:9
|
LL | self.to_owned() == *other
| ^^^^^^^^^^^^^^^^^^^^^^^^^ try implementing the comparison without allocating
error: aborting due to 3 previous errors
+29
View File
@@ -0,0 +1,29 @@
// ignore-windows
// ignore-macos
#![feature(no_core, lang_items, start)]
#![no_core]
#[link(name = "c")]
extern "C" {}
#[lang = "sized"]
pub trait Sized {}
#[lang = "copy"]
pub trait Copy {}
#[lang = "freeze"]
pub unsafe trait Freeze {}
#[lang = "start"]
#[start]
fn start(_argc: isize, _argv: *const *const u8) -> isize {
0
}
pub struct A;
impl A {
pub fn as_ref(self) -> &'static str {
"A"
}
}
+10
View File
@@ -0,0 +1,10 @@
error: methods called `as_*` usually take self by reference or self by mutable reference; consider choosing a less ambiguous name
--> $DIR/def_id_nocore.rs:26:19
|
LL | pub fn as_ref(self) -> &'static str {
| ^^^^
|
= note: `-D clippy::wrong-self-convention` implied by `-D warnings`
error: aborting due to previous error
View File
+12
View File
@@ -1,5 +1,6 @@
#![warn(clippy::inherent_to_string)]
#![deny(clippy::inherent_to_string_shadow_display)]
#![allow(clippy::many_single_char_names)]
use std::fmt;
@@ -12,6 +13,7 @@ trait FalsePositive {
struct C;
struct D;
struct E;
struct F;
impl A {
// Should be detected; emit warning
@@ -64,6 +66,13 @@ fn to_string() -> String {
}
}
impl F {
// Should not be detected, as it does not match the function signature
fn to_string(&self, _i: i32) -> String {
"F.to_string()".to_string()
}
}
fn main() {
let a = A;
a.to_string();
@@ -81,4 +90,7 @@ fn main() {
d.to_string();
E::to_string();
let f = F;
f.to_string(1);
}
+2 -2
View File
@@ -1,5 +1,5 @@
error: implementation of inherent method `to_string(&self) -> String` for type `A`
--> $DIR/inherent_to_string.rs:18:5
--> $DIR/inherent_to_string.rs:20:5
|
LL | / fn to_string(&self) -> String {
LL | | "A.to_string()".to_string()
@@ -10,7 +10,7 @@ LL | | }
= help: implement trait `Display` for type `A` instead
error: type `C` implements inherent method `to_string(&self) -> String` which shadows the implementation of `Display`
--> $DIR/inherent_to_string.rs:42:5
--> $DIR/inherent_to_string.rs:44:5
|
LL | / fn to_string(&self) -> String {
LL | | "C.to_string()".to_string()
+2 -2
View File
@@ -25,7 +25,7 @@ LL | let fail_multi_zero = 000_123usize;
| ^^^^^^^^^^^^
|
= note: `-D clippy::zero-prefixed-literal` implied by `-D warnings`
help: if you mean to use a decimal constant, remove the `0` to remove confusion
help: if you mean to use a decimal constant, remove the `0` to avoid confusion
|
LL | let fail_multi_zero = 123usize;
| ^^^^^^^^
@@ -39,7 +39,7 @@ error: this is a decimal constant
|
LL | let fail8 = 0123;
| ^^^^
help: if you mean to use a decimal constant, remove the `0` to remove confusion
help: if you mean to use a decimal constant, remove the `0` to avoid confusion
|
LL | let fail8 = 123;
| ^^^
+102
View File
@@ -0,0 +1,102 @@
// run-rustfix
#![warn(clippy::or_fun_call)]
#![allow(dead_code)]
use std::collections::BTreeMap;
use std::collections::HashMap;
use std::time::Duration;
/// Checks implementation of the `OR_FUN_CALL` lint.
fn or_fun_call() {
struct Foo;
impl Foo {
fn new() -> Foo {
Foo
}
}
enum Enum {
A(i32),
}
fn make<T>() -> T {
unimplemented!();
}
let with_enum = Some(Enum::A(1));
with_enum.unwrap_or(Enum::A(5));
let with_const_fn = Some(Duration::from_secs(1));
with_const_fn.unwrap_or(Duration::from_secs(5));
let with_constructor = Some(vec![1]);
with_constructor.unwrap_or_else(make);
let with_new = Some(vec![1]);
with_new.unwrap_or_default();
let with_const_args = Some(vec![1]);
with_const_args.unwrap_or_else(|| Vec::with_capacity(12));
let with_err: Result<_, ()> = Ok(vec![1]);
with_err.unwrap_or_else(|_| make());
let with_err_args: Result<_, ()> = Ok(vec![1]);
with_err_args.unwrap_or_else(|_| Vec::with_capacity(12));
let with_default_trait = Some(1);
with_default_trait.unwrap_or_default();
let with_default_type = Some(1);
with_default_type.unwrap_or_default();
let with_vec = Some(vec![1]);
with_vec.unwrap_or_else(|| vec![]);
// FIXME #944: ~|SUGGESTION with_vec.unwrap_or_else(|| vec![]);
let without_default = Some(Foo);
without_default.unwrap_or_else(Foo::new);
let mut map = HashMap::<u64, String>::new();
map.entry(42).or_insert_with(String::new);
let mut btree = BTreeMap::<u64, String>::new();
btree.entry(42).or_insert_with(String::new);
let stringy = Some(String::from(""));
let _ = stringy.unwrap_or_else(|| "".to_owned());
let opt = Some(1);
let hello = "Hello";
let _ = opt.ok_or_else(|| format!("{} world.", hello));
}
struct Foo(u8);
struct Bar(String, Duration);
#[rustfmt::skip]
fn test_or_with_ctors() {
let opt = Some(1);
let opt_opt = Some(Some(1));
// we also test for const promotion, this makes sure we don't hit that
let two = 2;
let _ = opt_opt.unwrap_or(Some(2));
let _ = opt_opt.unwrap_or(Some(two));
let _ = opt.ok_or(Some(2));
let _ = opt.ok_or(Some(two));
let _ = opt.ok_or(Foo(2));
let _ = opt.ok_or(Foo(two));
let _ = opt.or(Some(2));
let _ = opt.or(Some(two));
let _ = Some("a".to_string()).or_else(|| Some("b".to_string()));
let b = "b".to_string();
let _ = Some(Bar("a".to_string(), Duration::from_secs(1)))
.or(Some(Bar(b, Duration::from_secs(2))));
}
fn main() {}
+3
View File
@@ -1,4 +1,7 @@
// run-rustfix
#![warn(clippy::or_fun_call)]
#![allow(dead_code)]
use std::collections::BTreeMap;
use std::collections::HashMap;
+14 -14
View File
@@ -1,5 +1,5 @@
error: use of `unwrap_or` followed by a function call
--> $DIR/or_fun_call.rs:32:22
--> $DIR/or_fun_call.rs:35:22
|
LL | with_constructor.unwrap_or(make());
| ^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(make)`
@@ -7,79 +7,79 @@ LL | with_constructor.unwrap_or(make());
= note: `-D clippy::or-fun-call` implied by `-D warnings`
error: use of `unwrap_or` followed by a call to `new`
--> $DIR/or_fun_call.rs:35:5
--> $DIR/or_fun_call.rs:38:5
|
LL | with_new.unwrap_or(Vec::new());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `with_new.unwrap_or_default()`
error: use of `unwrap_or` followed by a function call
--> $DIR/or_fun_call.rs:38:21
--> $DIR/or_fun_call.rs:41:21
|
LL | with_const_args.unwrap_or(Vec::with_capacity(12));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| Vec::with_capacity(12))`
error: use of `unwrap_or` followed by a function call
--> $DIR/or_fun_call.rs:41:14
--> $DIR/or_fun_call.rs:44:14
|
LL | with_err.unwrap_or(make());
| ^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|_| make())`
error: use of `unwrap_or` followed by a function call
--> $DIR/or_fun_call.rs:44:19
--> $DIR/or_fun_call.rs:47:19
|
LL | with_err_args.unwrap_or(Vec::with_capacity(12));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|_| Vec::with_capacity(12))`
error: use of `unwrap_or` followed by a call to `default`
--> $DIR/or_fun_call.rs:47:5
--> $DIR/or_fun_call.rs:50:5
|
LL | with_default_trait.unwrap_or(Default::default());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `with_default_trait.unwrap_or_default()`
error: use of `unwrap_or` followed by a call to `default`
--> $DIR/or_fun_call.rs:50:5
--> $DIR/or_fun_call.rs:53:5
|
LL | with_default_type.unwrap_or(u64::default());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `with_default_type.unwrap_or_default()`
error: use of `unwrap_or` followed by a function call
--> $DIR/or_fun_call.rs:53:14
--> $DIR/or_fun_call.rs:56:14
|
LL | with_vec.unwrap_or(vec![]);
| ^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| vec![])`
error: use of `unwrap_or` followed by a function call
--> $DIR/or_fun_call.rs:58:21
--> $DIR/or_fun_call.rs:61:21
|
LL | without_default.unwrap_or(Foo::new());
| ^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(Foo::new)`
error: use of `or_insert` followed by a function call
--> $DIR/or_fun_call.rs:61:19
--> $DIR/or_fun_call.rs:64:19
|
LL | map.entry(42).or_insert(String::new());
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `or_insert_with(String::new)`
error: use of `or_insert` followed by a function call
--> $DIR/or_fun_call.rs:64:21
--> $DIR/or_fun_call.rs:67:21
|
LL | btree.entry(42).or_insert(String::new());
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `or_insert_with(String::new)`
error: use of `unwrap_or` followed by a function call
--> $DIR/or_fun_call.rs:67:21
--> $DIR/or_fun_call.rs:70:21
|
LL | let _ = stringy.unwrap_or("".to_owned());
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| "".to_owned())`
error: use of `ok_or` followed by a function call
--> $DIR/or_fun_call.rs:71:17
--> $DIR/or_fun_call.rs:74:17
|
LL | let _ = opt.ok_or(format!("{} world.", hello));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `ok_or_else(|| format!("{} world.", hello))`
error: use of `or` followed by a function call
--> $DIR/or_fun_call.rs:92:35
--> $DIR/or_fun_call.rs:95:35
|
LL | let _ = Some("a".to_string()).or(Some("b".to_string()));
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `or_else(|| Some("b".to_string()))`
Executable → Regular
View File
+37
View File
@@ -0,0 +1,37 @@
// run-rustfix
#![allow(unused_parens)]
fn f() -> usize {
42
}
#[warn(clippy::range_plus_one)]
fn main() {
for _ in 0..2 {}
for _ in 0..=2 {}
for _ in 0..=3 {}
for _ in 0..=3 + 1 {}
for _ in 0..=5 {}
for _ in 0..=1 + 5 {}
for _ in 1..=1 {}
for _ in 1..=1 + 1 {}
for _ in 0..13 + 13 {}
for _ in 0..=13 - 7 {}
for _ in 0..=f() {}
for _ in 0..=(1 + f()) {}
let _ = ..11 - 1;
let _ = ..11;
let _ = ..11;
let _ = (1..=11);
let _ = ((f() + 1)..=f());
let mut vec: Vec<()> = std::vec::Vec::new();
vec.drain(..);
}
+4
View File
@@ -1,3 +1,7 @@
// run-rustfix
#![allow(unused_parens)]
fn f() -> usize {
42
}
+8 -8
View File
@@ -1,5 +1,5 @@
error: an inclusive range would be more readable
--> $DIR/range_plus_minus_one.rs:10:14
--> $DIR/range_plus_minus_one.rs:14:14
|
LL | for _ in 0..3 + 1 {}
| ^^^^^^^^ help: use: `0..=3`
@@ -7,25 +7,25 @@ LL | for _ in 0..3 + 1 {}
= note: `-D clippy::range-plus-one` implied by `-D warnings`
error: an inclusive range would be more readable
--> $DIR/range_plus_minus_one.rs:13:14
--> $DIR/range_plus_minus_one.rs:17:14
|
LL | for _ in 0..1 + 5 {}
| ^^^^^^^^ help: use: `0..=5`
error: an inclusive range would be more readable
--> $DIR/range_plus_minus_one.rs:16:14
--> $DIR/range_plus_minus_one.rs:20:14
|
LL | for _ in 1..1 + 1 {}
| ^^^^^^^^ help: use: `1..=1`
error: an inclusive range would be more readable
--> $DIR/range_plus_minus_one.rs:22:14
--> $DIR/range_plus_minus_one.rs:26:14
|
LL | for _ in 0..(1 + f()) {}
| ^^^^^^^^^^^^ help: use: `0..=f()`
error: an exclusive range would be more readable
--> $DIR/range_plus_minus_one.rs:26:13
--> $DIR/range_plus_minus_one.rs:30:13
|
LL | let _ = ..=11 - 1;
| ^^^^^^^^^ help: use: `..11`
@@ -33,19 +33,19 @@ LL | let _ = ..=11 - 1;
= note: `-D clippy::range-minus-one` implied by `-D warnings`
error: an exclusive range would be more readable
--> $DIR/range_plus_minus_one.rs:27:13
--> $DIR/range_plus_minus_one.rs:31:13
|
LL | let _ = ..=(11 - 1);
| ^^^^^^^^^^^ help: use: `..11`
error: an inclusive range would be more readable
--> $DIR/range_plus_minus_one.rs:28:13
--> $DIR/range_plus_minus_one.rs:32:13
|
LL | let _ = (1..11 + 1);
| ^^^^^^^^^^^ help: use: `(1..=11)`
error: an inclusive range would be more readable
--> $DIR/range_plus_minus_one.rs:29:13
--> $DIR/range_plus_minus_one.rs:33:13
|
LL | let _ = (f() + 1)..(f() + 1);
| ^^^^^^^^^^^^^^^^^^^^ help: use: `((f() + 1)..=f())`
+18
View File
@@ -0,0 +1,18 @@
// run-rustfix
#![warn(clippy::short_circuit_statement)]
#![allow(clippy::nonminimal_bool)]
fn main() {
if f() { g(); }
if !f() { g(); }
if !(1 == 2) { g(); }
}
fn f() -> bool {
true
}
fn g() -> bool {
false
}
+3
View File
@@ -1,4 +1,7 @@
// run-rustfix
#![warn(clippy::short_circuit_statement)]
#![allow(clippy::nonminimal_bool)]
fn main() {
f() && g();
+3 -3
View File
@@ -1,5 +1,5 @@
error: boolean short circuit operator in statement may be clearer using an explicit test
--> $DIR/short_circuit_statement.rs:4:5
--> $DIR/short_circuit_statement.rs:7:5
|
LL | f() && g();
| ^^^^^^^^^^^ help: replace it with: `if f() { g(); }`
@@ -7,13 +7,13 @@ LL | f() && g();
= note: `-D clippy::short-circuit-statement` implied by `-D warnings`
error: boolean short circuit operator in statement may be clearer using an explicit test
--> $DIR/short_circuit_statement.rs:5:5
--> $DIR/short_circuit_statement.rs:8:5
|
LL | f() || g();
| ^^^^^^^^^^^ help: replace it with: `if !f() { g(); }`
error: boolean short circuit operator in statement may be clearer using an explicit test
--> $DIR/short_circuit_statement.rs:6:5
--> $DIR/short_circuit_statement.rs:9:5
|
LL | 1 == 2 || g();
| ^^^^^^^^^^^^^^ help: replace it with: `if !(1 == 2) { g(); }`
View File
@@ -3,6 +3,12 @@
#![warn(clippy::unseparated_literal_suffix)]
#![allow(dead_code)]
macro_rules! lit_from_macro {
() => {
42_usize
};
}
fn main() {
let _ok1 = 1234_i32;
let _ok2 = 1234_isize;
@@ -17,4 +23,12 @@ fn main() {
let _okf2 = 1_f32;
let _failf1 = 1.5_f32;
let _failf2 = 1_f32;
// Test for macro
let _ = lit_from_macro!();
// Counter example
let _ = line!();
// Because `assert!` contains `line!()` macro.
assert_eq!(4897_u32, 32223);
}
+14
View File
@@ -3,6 +3,12 @@
#![warn(clippy::unseparated_literal_suffix)]
#![allow(dead_code)]
macro_rules! lit_from_macro {
() => {
42usize
};
}
fn main() {
let _ok1 = 1234_i32;
let _ok2 = 1234_isize;
@@ -17,4 +23,12 @@ fn main() {
let _okf2 = 1_f32;
let _failf1 = 1.5f32;
let _failf2 = 1f32;
// Test for macro
let _ = lit_from_macro!();
// Counter example
let _ = line!();
// Because `assert!` contains `line!()` macro.
assert_eq!(4897u32, 32223);
}
+23 -8
View File
@@ -1,5 +1,5 @@
error: integer type suffix should be separated by an underscore
--> $DIR/unseparated_prefix_literals.rs:10:18
--> $DIR/unseparated_prefix_literals.rs:16:18
|
LL | let _fail1 = 1234i32;
| ^^^^^^^ help: add an underscore: `1234_i32`
@@ -7,40 +7,55 @@ LL | let _fail1 = 1234i32;
= note: `-D clippy::unseparated-literal-suffix` implied by `-D warnings`
error: integer type suffix should be separated by an underscore
--> $DIR/unseparated_prefix_literals.rs:11:18
--> $DIR/unseparated_prefix_literals.rs:17:18
|
LL | let _fail2 = 1234u32;
| ^^^^^^^ help: add an underscore: `1234_u32`
error: integer type suffix should be separated by an underscore
--> $DIR/unseparated_prefix_literals.rs:12:18
--> $DIR/unseparated_prefix_literals.rs:18:18
|
LL | let _fail3 = 1234isize;
| ^^^^^^^^^ help: add an underscore: `1234_isize`
error: integer type suffix should be separated by an underscore
--> $DIR/unseparated_prefix_literals.rs:13:18
--> $DIR/unseparated_prefix_literals.rs:19:18
|
LL | let _fail4 = 1234usize;
| ^^^^^^^^^ help: add an underscore: `1234_usize`
error: integer type suffix should be separated by an underscore
--> $DIR/unseparated_prefix_literals.rs:14:18
--> $DIR/unseparated_prefix_literals.rs:20:18
|
LL | let _fail5 = 0x123isize;
| ^^^^^^^^^^ help: add an underscore: `0x123_isize`
error: float type suffix should be separated by an underscore
--> $DIR/unseparated_prefix_literals.rs:18:19
--> $DIR/unseparated_prefix_literals.rs:24:19
|
LL | let _failf1 = 1.5f32;
| ^^^^^^ help: add an underscore: `1.5_f32`
error: float type suffix should be separated by an underscore
--> $DIR/unseparated_prefix_literals.rs:19:19
--> $DIR/unseparated_prefix_literals.rs:25:19
|
LL | let _failf2 = 1f32;
| ^^^^ help: add an underscore: `1_f32`
error: aborting due to 7 previous errors
error: integer type suffix should be separated by an underscore
--> $DIR/unseparated_prefix_literals.rs:8:9
|
LL | 42usize
| ^^^^^^^ help: add an underscore: `42_usize`
...
LL | let _ = lit_from_macro!();
| ----------------- in this macro invocation
error: integer type suffix should be separated by an underscore
--> $DIR/unseparated_prefix_literals.rs:33:16
|
LL | assert_eq!(4897u32, 32223);
| ^^^^^^^ help: add an underscore: `4897_u32`
error: aborting due to 9 previous errors
+14
View File
@@ -10,6 +10,7 @@
#![rustfmt::skip]
#![deny(clippy::unused_unit)]
#![allow(dead_code)]
struct Unitter;
impl Unitter {
@@ -42,3 +43,16 @@ fn main() {
}
return;
}
// https://github.com/rust-lang/rust-clippy/issues/4076
fn foo() {
macro_rules! foo {
(recv($r:expr) -> $res:pat => $body:expr) => {
$body
}
}
foo! {
recv(rx) -> _x => ()
}
}
+14
View File
@@ -10,6 +10,7 @@
#![rustfmt::skip]
#![deny(clippy::unused_unit)]
#![allow(dead_code)]
struct Unitter;
impl Unitter {
@@ -43,3 +44,16 @@ fn main() {
}
return();
}
// https://github.com/rust-lang/rust-clippy/issues/4076
fn foo() {
macro_rules! foo {
(recv($r:expr) -> $res:pat => $body:expr) => {
$body
}
}
foo! {
recv(rx) -> _x => ()
}
}
+7 -7
View File
@@ -1,5 +1,5 @@
error: unneeded unit return type
--> $DIR/unused_unit.rs:18:59
--> $DIR/unused_unit.rs:19:59
|
LL | pub fn get_unit<F: Fn() -> (), G>(&self, f: F, _g: G) ->
| ___________________________________________________________^
@@ -13,37 +13,37 @@ LL | #![deny(clippy::unused_unit)]
| ^^^^^^^^^^^^^^^^^^^
error: unneeded unit return type
--> $DIR/unused_unit.rs:28:19
--> $DIR/unused_unit.rs:29:19
|
LL | fn into(self) -> () {
| ^^^^^ help: remove the `-> ()`
error: unneeded unit expression
--> $DIR/unused_unit.rs:29:9
--> $DIR/unused_unit.rs:30:9
|
LL | ()
| ^^ help: remove the final `()`
error: unneeded unit return type
--> $DIR/unused_unit.rs:33:18
--> $DIR/unused_unit.rs:34:18
|
LL | fn return_unit() -> () { () }
| ^^^^^ help: remove the `-> ()`
error: unneeded unit expression
--> $DIR/unused_unit.rs:33:26
--> $DIR/unused_unit.rs:34:26
|
LL | fn return_unit() -> () { () }
| ^^ help: remove the final `()`
error: unneeded `()`
--> $DIR/unused_unit.rs:42:14
--> $DIR/unused_unit.rs:43:14
|
LL | break();
| ^^ help: remove the `()`
error: unneeded `()`
--> $DIR/unused_unit.rs:44:11
--> $DIR/unused_unit.rs:45:11
|
LL | return();
| ^^ help: remove the `()`
View File
+1 -1
View File
@@ -11,7 +11,7 @@ last=$2
IFS='
'
for pr in $(git log --oneline --grep "Merge #" --grep "Merge pull request" --grep "Auto merge of" "$first...$last" | sort -rn | uniq); do
for pr in $(git log --oneline --grep "Merge #" --grep "Merge pull request" --grep "Auto merge of" --grep "Rollup merge of" "$first...$last" | sort -rn | uniq); do
id=$(echo $pr | rg -o '#[0-9]{3,5}' | cut -c 2-)
commit=$(echo $pr | cut -d' ' -f 1)
message=$(git --no-pager show --pretty=medium $commit)