mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-23 21:23:20 +00:00
Merge branch 'master' of github.com:Manishearth/rust-clippy into fold_any
This commit is contained in:
commit
70302595a4
@ -4,7 +4,7 @@ rust: nightly
|
|||||||
|
|
||||||
os:
|
os:
|
||||||
- linux
|
- linux
|
||||||
- osx
|
# - osx # doesn't even start atm. Not sure what travis is up to. Disabling to reduce the noise
|
||||||
|
|
||||||
sudo: false
|
sudo: false
|
||||||
|
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
# Change Log
|
# Change Log
|
||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
|
## 0.0.180
|
||||||
|
* Rustup to *rustc 1.25.0-nightly (3f92e8d89 2018-01-14)*
|
||||||
|
|
||||||
## 0.0.179
|
## 0.0.179
|
||||||
* Rustup to *rustc 1.25.0-nightly (61452e506 2018-01-09)*
|
* Rustup to *rustc 1.25.0-nightly (61452e506 2018-01-09)*
|
||||||
|
|
||||||
@ -580,6 +583,7 @@ All notable changes to this project will be documented in this file.
|
|||||||
[`ineffective_bit_mask`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#ineffective_bit_mask
|
[`ineffective_bit_mask`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#ineffective_bit_mask
|
||||||
[`infinite_iter`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#infinite_iter
|
[`infinite_iter`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#infinite_iter
|
||||||
[`inline_always`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#inline_always
|
[`inline_always`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#inline_always
|
||||||
|
[`inline_fn_without_body`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#inline_fn_without_body
|
||||||
[`int_plus_one`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#int_plus_one
|
[`int_plus_one`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#int_plus_one
|
||||||
[`integer_arithmetic`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#integer_arithmetic
|
[`integer_arithmetic`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#integer_arithmetic
|
||||||
[`invalid_ref`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#invalid_ref
|
[`invalid_ref`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#invalid_ref
|
||||||
@ -670,6 +674,7 @@ All notable changes to this project will be documented in this file.
|
|||||||
[`redundant_closure_call`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#redundant_closure_call
|
[`redundant_closure_call`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#redundant_closure_call
|
||||||
[`redundant_pattern`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#redundant_pattern
|
[`redundant_pattern`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#redundant_pattern
|
||||||
[`regex_macro`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#regex_macro
|
[`regex_macro`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#regex_macro
|
||||||
|
[`replace_consts`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#replace_consts
|
||||||
[`result_map_unwrap_or_else`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#result_map_unwrap_or_else
|
[`result_map_unwrap_or_else`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#result_map_unwrap_or_else
|
||||||
[`result_unwrap_used`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#result_unwrap_used
|
[`result_unwrap_used`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#result_unwrap_used
|
||||||
[`reverse_range_loop`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#reverse_range_loop
|
[`reverse_range_loop`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#reverse_range_loop
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "clippy"
|
name = "clippy"
|
||||||
version = "0.0.179"
|
version = "0.0.180"
|
||||||
authors = [
|
authors = [
|
||||||
"Manish Goregaokar <manishsmail@gmail.com>",
|
"Manish Goregaokar <manishsmail@gmail.com>",
|
||||||
"Andre Bogus <bogusandre@gmail.com>",
|
"Andre Bogus <bogusandre@gmail.com>",
|
||||||
@ -37,13 +37,13 @@ path = "src/driver.rs"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
# begin automatic update
|
# begin automatic update
|
||||||
clippy_lints = { version = "0.0.179", path = "clippy_lints" }
|
clippy_lints = { version = "0.0.180", path = "clippy_lints" }
|
||||||
# end automatic update
|
# end automatic update
|
||||||
cargo_metadata = "0.2"
|
cargo_metadata = "0.2"
|
||||||
regex = "0.2"
|
regex = "0.2"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
compiletest_rs = "0.3"
|
compiletest_rs = "0.3.5"
|
||||||
duct = "0.8.2"
|
duct = "0.8.2"
|
||||||
lazy_static = "1.0"
|
lazy_static = "1.0"
|
||||||
serde_derive = "1.0"
|
serde_derive = "1.0"
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "clippy_lints"
|
name = "clippy_lints"
|
||||||
# begin automatic update
|
# begin automatic update
|
||||||
version = "0.0.179"
|
version = "0.0.180"
|
||||||
# end automatic update
|
# end automatic update
|
||||||
authors = [
|
authors = [
|
||||||
"Manish Goregaokar <manishsmail@gmail.com>",
|
"Manish Goregaokar <manishsmail@gmail.com>",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use syntax::ast::{Item, ItemKind, Ty, TyKind};
|
use syntax::ast::{Item, ItemKind, Ty, TyKind};
|
||||||
use rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintPass};
|
use rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintPass};
|
||||||
use utils::{in_macro, span_lint_and_then};
|
use utils::{in_macro, snippet, span_lint_and_then};
|
||||||
|
|
||||||
/// **What it does:** Checks for constants with an explicit `'static` lifetime.
|
/// **What it does:** Checks for constants with an explicit `'static` lifetime.
|
||||||
///
|
///
|
||||||
@ -51,14 +51,15 @@ impl StaticConst {
|
|||||||
TyKind::Path(..) | TyKind::Slice(..) | TyKind::Array(..) |
|
TyKind::Path(..) | TyKind::Slice(..) | TyKind::Array(..) |
|
||||||
TyKind::Tup(..) => {
|
TyKind::Tup(..) => {
|
||||||
if lifetime.ident.name == "'static" {
|
if lifetime.ident.name == "'static" {
|
||||||
let mut sug: String = String::new();
|
let snip = snippet(cx, borrow_type.ty.span, "<type>");
|
||||||
|
let sugg = format!("&{}", snip);
|
||||||
span_lint_and_then(
|
span_lint_and_then(
|
||||||
cx,
|
cx,
|
||||||
CONST_STATIC_LIFETIME,
|
CONST_STATIC_LIFETIME,
|
||||||
lifetime.span,
|
lifetime.span,
|
||||||
"Constants have by default a `'static` lifetime",
|
"Constants have by default a `'static` lifetime",
|
||||||
|db| {
|
|db| {
|
||||||
db.span_suggestion(lifetime.span, "consider removing `'static`", sug);
|
db.span_suggestion(ty.span, "consider removing `'static`", sugg);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
70
clippy_lints/src/else_if_without_else.rs
Normal file
70
clippy_lints/src/else_if_without_else.rs
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
//! lint on if expressions with an else if, but without a final else branch
|
||||||
|
|
||||||
|
use rustc::lint::*;
|
||||||
|
use syntax::ast::*;
|
||||||
|
|
||||||
|
use utils::{in_external_macro, span_lint_and_sugg};
|
||||||
|
|
||||||
|
/// **What it does:** Checks for usage of if expressions with an `else if` branch,
|
||||||
|
/// but without a final `else` branch.
|
||||||
|
///
|
||||||
|
/// **Why is this bad?** Some coding guidelines require this (e.g. MISRA-C:2004 Rule 14.10).
|
||||||
|
///
|
||||||
|
/// **Known problems:** None.
|
||||||
|
///
|
||||||
|
/// **Example:**
|
||||||
|
/// ```rust
|
||||||
|
/// if x.is_positive() {
|
||||||
|
/// a();
|
||||||
|
/// } else if x.is_negative() {
|
||||||
|
/// b();
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// Could be written:
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// if x.is_positive() {
|
||||||
|
/// a();
|
||||||
|
/// } else if x.is_negative() {
|
||||||
|
/// b();
|
||||||
|
/// } else {
|
||||||
|
/// // we don't care about zero
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
declare_restriction_lint! {
|
||||||
|
pub ELSE_IF_WITHOUT_ELSE,
|
||||||
|
"if expression with an `else if`, but without a final `else` branch"
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
pub struct ElseIfWithoutElse;
|
||||||
|
|
||||||
|
impl LintPass for ElseIfWithoutElse {
|
||||||
|
fn get_lints(&self) -> LintArray {
|
||||||
|
lint_array!(ELSE_IF_WITHOUT_ELSE)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EarlyLintPass for ElseIfWithoutElse {
|
||||||
|
fn check_expr(&mut self, cx: &EarlyContext, mut item: &Expr) {
|
||||||
|
if in_external_macro(cx, item.span) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while let ExprKind::If(_, _, Some(ref els)) = item.node {
|
||||||
|
if let ExprKind::If(_, _, None) = els.node {
|
||||||
|
span_lint_and_sugg(
|
||||||
|
cx,
|
||||||
|
ELSE_IF_WITHOUT_ELSE,
|
||||||
|
els.span,
|
||||||
|
"if expression with an `else if`, but without a final `else`",
|
||||||
|
"add an `else` block here",
|
||||||
|
"".to_string()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
item = els;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -86,7 +86,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Functions {
|
|||||||
use rustc::hir::map::Node::*;
|
use rustc::hir::map::Node::*;
|
||||||
|
|
||||||
let is_impl = if let Some(NodeItem(item)) = cx.tcx.hir.find(cx.tcx.hir.get_parent_node(nodeid)) {
|
let is_impl = if let Some(NodeItem(item)) = cx.tcx.hir.find(cx.tcx.hir.get_parent_node(nodeid)) {
|
||||||
matches!(item.node, hir::ItemImpl(_, _, _, _, Some(_), _, _) | hir::ItemAutoImpl(..))
|
matches!(item.node, hir::ItemImpl(_, _, _, _, Some(_), _, _))
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
};
|
};
|
||||||
|
65
clippy_lints/src/inline_fn_without_body.rs
Normal file
65
clippy_lints/src/inline_fn_without_body.rs
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
//! checks for `#[inline]` on trait methods without bodies
|
||||||
|
|
||||||
|
use rustc::lint::*;
|
||||||
|
use rustc::hir::*;
|
||||||
|
use syntax::ast::{Attribute, Name};
|
||||||
|
use utils::span_lint_and_then;
|
||||||
|
use utils::sugg::DiagnosticBuilderExt;
|
||||||
|
|
||||||
|
/// **What it does:** Checks for `#[inline]` on trait methods without bodies
|
||||||
|
///
|
||||||
|
/// **Why is this bad?** Only implementations of trait methods may be inlined.
|
||||||
|
/// The inline attribute is ignored for trait methods without bodies.
|
||||||
|
///
|
||||||
|
/// **Known problems:** None.
|
||||||
|
///
|
||||||
|
/// **Example:**
|
||||||
|
/// ```rust
|
||||||
|
/// trait Animal {
|
||||||
|
/// #[inline]
|
||||||
|
/// fn name(&self) -> &'static str;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
declare_lint! {
|
||||||
|
pub INLINE_FN_WITHOUT_BODY,
|
||||||
|
Warn,
|
||||||
|
"use of `#[inline]` on trait methods without bodies"
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
pub struct Pass;
|
||||||
|
|
||||||
|
impl LintPass for Pass {
|
||||||
|
fn get_lints(&self) -> LintArray {
|
||||||
|
lint_array!(INLINE_FN_WITHOUT_BODY)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
||||||
|
fn check_trait_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx TraitItem) {
|
||||||
|
match item.node {
|
||||||
|
TraitItemKind::Method(_, TraitMethod::Required(_)) => {
|
||||||
|
check_attrs(cx, &item.name, &item.attrs);
|
||||||
|
},
|
||||||
|
_ => {},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn check_attrs(cx: &LateContext, name: &Name, attrs: &[Attribute]) {
|
||||||
|
for attr in attrs {
|
||||||
|
if attr.name().map_or(true, |n| n != "inline") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
span_lint_and_then(
|
||||||
|
cx,
|
||||||
|
INLINE_FN_WITHOUT_BODY,
|
||||||
|
attr.span,
|
||||||
|
&format!("use of `#[inline]` on trait method `{}` which has no body", name),
|
||||||
|
|db| {
|
||||||
|
db.suggest_remove_item(cx, attr.span, "remove");
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -1,140 +0,0 @@
|
|||||||
use rustc::lint::*;
|
|
||||||
use syntax::ast::*;
|
|
||||||
use syntax::ext::quote::rt::Span;
|
|
||||||
use utils::{span_lint, span_note_and_lint};
|
|
||||||
|
|
||||||
/// **What it does:** Checks for
|
|
||||||
/// - () being assigned to a variable
|
|
||||||
/// - () being passed to a function
|
|
||||||
///
|
|
||||||
/// **Why is this bad?** It is extremely unlikely that a user intended to
|
|
||||||
/// assign '()' to valiable. Instead,
|
|
||||||
/// Unit is what a block evaluates to when it returns nothing. This is
|
|
||||||
/// typically caused by a trailing
|
|
||||||
/// unintended semicolon.
|
|
||||||
///
|
|
||||||
/// **Known problems:** None.
|
|
||||||
///
|
|
||||||
/// **Example:**
|
|
||||||
/// * `let x = {"foo" ;}` when the user almost certainly intended `let x
|
|
||||||
/// ={"foo"}`
|
|
||||||
declare_lint! {
|
|
||||||
pub UNIT_EXPR,
|
|
||||||
Warn,
|
|
||||||
"unintended assignment or use of a unit typed value"
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
|
||||||
enum UnitCause {
|
|
||||||
SemiColon,
|
|
||||||
EmptyBlock,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
|
||||||
pub struct UnitExpr;
|
|
||||||
|
|
||||||
impl LintPass for UnitExpr {
|
|
||||||
fn get_lints(&self) -> LintArray {
|
|
||||||
lint_array!(UNIT_EXPR)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl EarlyLintPass for UnitExpr {
|
|
||||||
fn check_expr(&mut self, cx: &EarlyContext, expr: &Expr) {
|
|
||||||
if let ExprKind::Assign(ref _left, ref right) = expr.node {
|
|
||||||
check_for_unit(cx, right);
|
|
||||||
}
|
|
||||||
if let ExprKind::MethodCall(ref _left, ref args) = expr.node {
|
|
||||||
for arg in args {
|
|
||||||
check_for_unit(cx, arg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if let ExprKind::Call(_, ref args) = expr.node {
|
|
||||||
for arg in args {
|
|
||||||
check_for_unit(cx, arg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn check_stmt(&mut self, cx: &EarlyContext, stmt: &Stmt) {
|
|
||||||
if let StmtKind::Local(ref local) = stmt.node {
|
|
||||||
if local.pat.node == PatKind::Wild {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if let Some(ref expr) = local.init {
|
|
||||||
check_for_unit(cx, expr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn check_for_unit(cx: &EarlyContext, expr: &Expr) {
|
|
||||||
match is_unit_expr(expr) {
|
|
||||||
Some((span, UnitCause::SemiColon)) => span_note_and_lint(
|
|
||||||
cx,
|
|
||||||
UNIT_EXPR,
|
|
||||||
expr.span,
|
|
||||||
"This expression evaluates to the Unit type ()",
|
|
||||||
span,
|
|
||||||
"Consider removing the trailing semicolon",
|
|
||||||
),
|
|
||||||
Some((_span, UnitCause::EmptyBlock)) => span_lint(
|
|
||||||
cx,
|
|
||||||
UNIT_EXPR,
|
|
||||||
expr.span,
|
|
||||||
"This expression evaluates to the Unit type ()",
|
|
||||||
),
|
|
||||||
None => (),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_unit_expr(expr: &Expr) -> Option<(Span, UnitCause)> {
|
|
||||||
match expr.node {
|
|
||||||
ExprKind::Block(ref block) => match check_last_stmt_in_block(block) {
|
|
||||||
Some(UnitCause::SemiColon) =>
|
|
||||||
Some((block.stmts[block.stmts.len() - 1].span, UnitCause::SemiColon)),
|
|
||||||
Some(UnitCause::EmptyBlock) =>
|
|
||||||
Some((block.span, UnitCause::EmptyBlock)),
|
|
||||||
None => None
|
|
||||||
}
|
|
||||||
ExprKind::If(_, ref then, ref else_) => {
|
|
||||||
let check_then = check_last_stmt_in_block(then);
|
|
||||||
if let Some(ref else_) = *else_ {
|
|
||||||
let check_else = is_unit_expr(else_);
|
|
||||||
if let Some(ref expr_else) = check_else {
|
|
||||||
return Some(*expr_else);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
match check_then {
|
|
||||||
Some(c) => Some((expr.span, c)),
|
|
||||||
None => None,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
ExprKind::Match(ref _pattern, ref arms) => {
|
|
||||||
for arm in arms {
|
|
||||||
if let Some(r) = is_unit_expr(&arm.body) {
|
|
||||||
return Some(r);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None
|
|
||||||
},
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn check_last_stmt_in_block(block: &Block) -> Option<UnitCause> {
|
|
||||||
if block.stmts.is_empty() { return Some(UnitCause::EmptyBlock); }
|
|
||||||
let final_stmt = &block.stmts[block.stmts.len() - 1];
|
|
||||||
|
|
||||||
|
|
||||||
// Made a choice here to risk false positives on divergent macro invocations
|
|
||||||
// like `panic!()`
|
|
||||||
match final_stmt.node {
|
|
||||||
StmtKind::Expr(_) => None,
|
|
||||||
StmtKind::Semi(ref expr) => match expr.node {
|
|
||||||
ExprKind::Break(_, _) | ExprKind::Continue(_) | ExprKind::Ret(_) => None,
|
|
||||||
_ => Some(UnitCause::SemiColon),
|
|
||||||
},
|
|
||||||
_ => Some(UnitCause::SemiColon), // not sure what's happening here
|
|
||||||
}
|
|
||||||
}
|
|
@ -88,6 +88,7 @@ pub mod derive;
|
|||||||
pub mod doc;
|
pub mod doc;
|
||||||
pub mod double_parens;
|
pub mod double_parens;
|
||||||
pub mod drop_forget_ref;
|
pub mod drop_forget_ref;
|
||||||
|
pub mod else_if_without_else;
|
||||||
pub mod empty_enum;
|
pub mod empty_enum;
|
||||||
pub mod entry;
|
pub mod entry;
|
||||||
pub mod enum_clike;
|
pub mod enum_clike;
|
||||||
@ -108,9 +109,9 @@ pub mod identity_op;
|
|||||||
pub mod if_let_redundant_pattern_matching;
|
pub mod if_let_redundant_pattern_matching;
|
||||||
pub mod if_not_else;
|
pub mod if_not_else;
|
||||||
pub mod infinite_iter;
|
pub mod infinite_iter;
|
||||||
|
pub mod inline_fn_without_body;
|
||||||
pub mod int_plus_one;
|
pub mod int_plus_one;
|
||||||
pub mod invalid_ref;
|
pub mod invalid_ref;
|
||||||
pub mod is_unit_expr;
|
|
||||||
pub mod items_after_statements;
|
pub mod items_after_statements;
|
||||||
pub mod large_enum_variant;
|
pub mod large_enum_variant;
|
||||||
pub mod len_zero;
|
pub mod len_zero;
|
||||||
@ -247,6 +248,10 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) {
|
|||||||
"string_to_string",
|
"string_to_string",
|
||||||
"using `string::to_string` is common even today and specialization will likely happen soon",
|
"using `string::to_string` is common even today and specialization will likely happen soon",
|
||||||
);
|
);
|
||||||
|
store.register_removed(
|
||||||
|
"unit_expr",
|
||||||
|
"superseded by `let_unit_value` and `unit_arg`",
|
||||||
|
);
|
||||||
// end deprecated lints, do not remove this comment, it’s used in `update_lints`
|
// end deprecated lints, do not remove this comment, it’s used in `update_lints`
|
||||||
|
|
||||||
reg.register_late_lint_pass(box serde_api::Serde);
|
reg.register_late_lint_pass(box serde_api::Serde);
|
||||||
@ -267,7 +272,6 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) {
|
|||||||
reg.register_late_lint_pass(box approx_const::Pass);
|
reg.register_late_lint_pass(box approx_const::Pass);
|
||||||
reg.register_late_lint_pass(box misc::Pass);
|
reg.register_late_lint_pass(box misc::Pass);
|
||||||
reg.register_early_lint_pass(box precedence::Precedence);
|
reg.register_early_lint_pass(box precedence::Precedence);
|
||||||
reg.register_early_lint_pass(box is_unit_expr::UnitExpr);
|
|
||||||
reg.register_early_lint_pass(box needless_continue::NeedlessContinue);
|
reg.register_early_lint_pass(box needless_continue::NeedlessContinue);
|
||||||
reg.register_late_lint_pass(box eta_reduction::EtaPass);
|
reg.register_late_lint_pass(box eta_reduction::EtaPass);
|
||||||
reg.register_late_lint_pass(box identity_op::IdentityOp);
|
reg.register_late_lint_pass(box identity_op::IdentityOp);
|
||||||
@ -329,6 +333,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) {
|
|||||||
reg.register_early_lint_pass(box formatting::Formatting);
|
reg.register_early_lint_pass(box formatting::Formatting);
|
||||||
reg.register_late_lint_pass(box swap::Swap);
|
reg.register_late_lint_pass(box swap::Swap);
|
||||||
reg.register_early_lint_pass(box if_not_else::IfNotElse);
|
reg.register_early_lint_pass(box if_not_else::IfNotElse);
|
||||||
|
reg.register_early_lint_pass(box else_if_without_else::ElseIfWithoutElse);
|
||||||
reg.register_early_lint_pass(box int_plus_one::IntPlusOne);
|
reg.register_early_lint_pass(box int_plus_one::IntPlusOne);
|
||||||
reg.register_late_lint_pass(box overflow_check_conditional::OverflowCheckConditional);
|
reg.register_late_lint_pass(box overflow_check_conditional::OverflowCheckConditional);
|
||||||
reg.register_late_lint_pass(box unused_label::UnusedLabel);
|
reg.register_late_lint_pass(box unused_label::UnusedLabel);
|
||||||
@ -357,18 +362,21 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) {
|
|||||||
reg.register_late_lint_pass(box use_self::UseSelf);
|
reg.register_late_lint_pass(box use_self::UseSelf);
|
||||||
reg.register_late_lint_pass(box bytecount::ByteCount);
|
reg.register_late_lint_pass(box bytecount::ByteCount);
|
||||||
reg.register_late_lint_pass(box infinite_iter::Pass);
|
reg.register_late_lint_pass(box infinite_iter::Pass);
|
||||||
|
reg.register_late_lint_pass(box inline_fn_without_body::Pass);
|
||||||
reg.register_late_lint_pass(box invalid_ref::InvalidRef);
|
reg.register_late_lint_pass(box invalid_ref::InvalidRef);
|
||||||
reg.register_late_lint_pass(box identity_conversion::IdentityConversion::default());
|
reg.register_late_lint_pass(box identity_conversion::IdentityConversion::default());
|
||||||
reg.register_late_lint_pass(box types::ImplicitHasher);
|
reg.register_late_lint_pass(box types::ImplicitHasher);
|
||||||
reg.register_early_lint_pass(box const_static_lifetime::StaticConst);
|
reg.register_early_lint_pass(box const_static_lifetime::StaticConst);
|
||||||
reg.register_late_lint_pass(box fallible_impl_from::FallibleImplFrom);
|
reg.register_late_lint_pass(box fallible_impl_from::FallibleImplFrom);
|
||||||
reg.register_late_lint_pass(box replace_consts::ReplaceConsts);
|
reg.register_late_lint_pass(box replace_consts::ReplaceConsts);
|
||||||
|
reg.register_late_lint_pass(box types::UnitArg);
|
||||||
|
|
||||||
reg.register_lint_group("clippy_restrictions", vec![
|
reg.register_lint_group("clippy_restrictions", vec![
|
||||||
arithmetic::FLOAT_ARITHMETIC,
|
arithmetic::FLOAT_ARITHMETIC,
|
||||||
arithmetic::INTEGER_ARITHMETIC,
|
arithmetic::INTEGER_ARITHMETIC,
|
||||||
array_indexing::INDEXING_SLICING,
|
array_indexing::INDEXING_SLICING,
|
||||||
assign_ops::ASSIGN_OPS,
|
assign_ops::ASSIGN_OPS,
|
||||||
|
else_if_without_else::ELSE_IF_WITHOUT_ELSE,
|
||||||
misc::FLOAT_CMP_CONST,
|
misc::FLOAT_CMP_CONST,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@ -474,8 +482,8 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) {
|
|||||||
identity_op::IDENTITY_OP,
|
identity_op::IDENTITY_OP,
|
||||||
if_let_redundant_pattern_matching::IF_LET_REDUNDANT_PATTERN_MATCHING,
|
if_let_redundant_pattern_matching::IF_LET_REDUNDANT_PATTERN_MATCHING,
|
||||||
infinite_iter::INFINITE_ITER,
|
infinite_iter::INFINITE_ITER,
|
||||||
|
inline_fn_without_body::INLINE_FN_WITHOUT_BODY,
|
||||||
invalid_ref::INVALID_REF,
|
invalid_ref::INVALID_REF,
|
||||||
is_unit_expr::UNIT_EXPR,
|
|
||||||
large_enum_variant::LARGE_ENUM_VARIANT,
|
large_enum_variant::LARGE_ENUM_VARIANT,
|
||||||
len_zero::LEN_WITHOUT_IS_EMPTY,
|
len_zero::LEN_WITHOUT_IS_EMPTY,
|
||||||
len_zero::LEN_ZERO,
|
len_zero::LEN_ZERO,
|
||||||
@ -602,8 +610,10 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) {
|
|||||||
types::IMPLICIT_HASHER,
|
types::IMPLICIT_HASHER,
|
||||||
types::LET_UNIT_VALUE,
|
types::LET_UNIT_VALUE,
|
||||||
types::LINKEDLIST,
|
types::LINKEDLIST,
|
||||||
|
types::OPTION_OPTION,
|
||||||
types::TYPE_COMPLEXITY,
|
types::TYPE_COMPLEXITY,
|
||||||
types::UNIT_CMP,
|
types::UNIT_CMP,
|
||||||
|
types::UNIT_ARG,
|
||||||
types::UNNECESSARY_CAST,
|
types::UNNECESSARY_CAST,
|
||||||
unicode::ZERO_WIDTH_SPACE,
|
unicode::ZERO_WIDTH_SPACE,
|
||||||
unsafe_removed_from_name::UNSAFE_REMOVED_FROM_NAME,
|
unsafe_removed_from_name::UNSAFE_REMOVED_FROM_NAME,
|
||||||
|
@ -10,7 +10,9 @@ use utils::{get_arg_name, is_adjusted, iter_input_pats, match_qpath, match_trait
|
|||||||
/// **Why is this bad?** It makes the code less readable than using the
|
/// **Why is this bad?** It makes the code less readable than using the
|
||||||
/// `.cloned()` adapter.
|
/// `.cloned()` adapter.
|
||||||
///
|
///
|
||||||
/// **Known problems:** None.
|
/// **Known problems:** Sometimes `.cloned()` requires stricter trait
|
||||||
|
/// bound than `.map(|e| e.clone())` (which works because of the coercion).
|
||||||
|
/// See [#498](https://github.com/rust-lang-nursery/rust-clippy/issues/498).
|
||||||
///
|
///
|
||||||
/// **Example:**
|
/// **Example:**
|
||||||
/// ```rust
|
/// ```rust
|
||||||
|
@ -361,9 +361,8 @@ declare_lint! {
|
|||||||
/// ```rust
|
/// ```rust
|
||||||
/// x.clone()
|
/// x.clone()
|
||||||
/// ```
|
/// ```
|
||||||
declare_lint! {
|
declare_restriction_lint! {
|
||||||
pub CLONE_ON_REF_PTR,
|
pub CLONE_ON_REF_PTR,
|
||||||
Warn,
|
|
||||||
"using 'clone' on a ref-counted pointer"
|
"using 'clone' on a ref-counted pointer"
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1039,24 +1038,26 @@ fn lint_clone_on_copy(cx: &LateContext, expr: &hir::Expr, arg: &hir::Expr, arg_t
|
|||||||
fn lint_clone_on_ref_ptr(cx: &LateContext, expr: &hir::Expr, arg: &hir::Expr) {
|
fn lint_clone_on_ref_ptr(cx: &LateContext, expr: &hir::Expr, arg: &hir::Expr) {
|
||||||
let (obj_ty, _) = walk_ptrs_ty_depth(cx.tables.expr_ty(arg));
|
let (obj_ty, _) = walk_ptrs_ty_depth(cx.tables.expr_ty(arg));
|
||||||
|
|
||||||
let caller_type = if match_type(cx, obj_ty, &paths::RC) {
|
if let ty::TyAdt(_, subst) = obj_ty.sty {
|
||||||
"Rc"
|
let caller_type = if match_type(cx, obj_ty, &paths::RC) {
|
||||||
} else if match_type(cx, obj_ty, &paths::ARC) {
|
"Rc"
|
||||||
"Arc"
|
} else if match_type(cx, obj_ty, &paths::ARC) {
|
||||||
} else if match_type(cx, obj_ty, &paths::WEAK_RC) || match_type(cx, obj_ty, &paths::WEAK_ARC) {
|
"Arc"
|
||||||
"Weak"
|
} else if match_type(cx, obj_ty, &paths::WEAK_RC) || match_type(cx, obj_ty, &paths::WEAK_ARC) {
|
||||||
} else {
|
"Weak"
|
||||||
return;
|
} else {
|
||||||
};
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
span_lint_and_sugg(
|
span_lint_and_sugg(
|
||||||
cx,
|
cx,
|
||||||
CLONE_ON_REF_PTR,
|
CLONE_ON_REF_PTR,
|
||||||
expr.span,
|
expr.span,
|
||||||
"using '.clone()' on a ref-counted pointer",
|
"using '.clone()' on a ref-counted pointer",
|
||||||
"try this",
|
"try this",
|
||||||
format!("{}::clone(&{})", caller_type, snippet(cx, arg.span, "_")),
|
format!("{}::<{}>::clone(&{})", caller_type, subst.type_at(0), snippet(cx, arg.span, "_")),
|
||||||
);
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -124,7 +124,17 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDoc {
|
|||||||
let desc = match it.node {
|
let desc = match it.node {
|
||||||
hir::ItemConst(..) => "a constant",
|
hir::ItemConst(..) => "a constant",
|
||||||
hir::ItemEnum(..) => "an enum",
|
hir::ItemEnum(..) => "an enum",
|
||||||
hir::ItemFn(..) => "a function",
|
hir::ItemFn(..) => {
|
||||||
|
// ignore main()
|
||||||
|
if it.name == "main" {
|
||||||
|
let def_id = cx.tcx.hir.local_def_id(it.id);
|
||||||
|
let def_key = cx.tcx.hir.def_key(def_id);
|
||||||
|
if def_key.parent == Some(hir::def_id::CRATE_DEF_INDEX) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"a function"
|
||||||
|
},
|
||||||
hir::ItemMod(..) => "a module",
|
hir::ItemMod(..) => "a module",
|
||||||
hir::ItemStatic(..) => "a static",
|
hir::ItemStatic(..) => "a static",
|
||||||
hir::ItemStruct(..) => "a struct",
|
hir::ItemStruct(..) => "a struct",
|
||||||
@ -133,7 +143,6 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDoc {
|
|||||||
hir::ItemGlobalAsm(..) => "an assembly blob",
|
hir::ItemGlobalAsm(..) => "an assembly blob",
|
||||||
hir::ItemTy(..) => "a type alias",
|
hir::ItemTy(..) => "a type alias",
|
||||||
hir::ItemUnion(..) => "a union",
|
hir::ItemUnion(..) => "a union",
|
||||||
hir::ItemAutoImpl(..) |
|
|
||||||
hir::ItemExternCrate(..) |
|
hir::ItemExternCrate(..) |
|
||||||
hir::ItemForeignMod(..) |
|
hir::ItemForeignMod(..) |
|
||||||
hir::ItemImpl(..) |
|
hir::ItemImpl(..) |
|
||||||
|
@ -6,6 +6,7 @@ use rustc::ty::{self, RegionKind, TypeFoldable};
|
|||||||
use rustc::traits;
|
use rustc::traits;
|
||||||
use rustc::middle::expr_use_visitor as euv;
|
use rustc::middle::expr_use_visitor as euv;
|
||||||
use rustc::middle::mem_categorization as mc;
|
use rustc::middle::mem_categorization as mc;
|
||||||
|
use syntax::abi::Abi;
|
||||||
use syntax::ast::NodeId;
|
use syntax::ast::NodeId;
|
||||||
use syntax_pos::Span;
|
use syntax_pos::Span;
|
||||||
use syntax::errors::DiagnosticBuilder;
|
use syntax::errors::DiagnosticBuilder;
|
||||||
@ -71,13 +72,18 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessPassByValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
match kind {
|
match kind {
|
||||||
FnKind::ItemFn(.., attrs) => for a in attrs {
|
FnKind::ItemFn(.., abi, _, attrs) => {
|
||||||
if_chain! {
|
if abi != Abi::Rust {
|
||||||
if a.meta_item_list().is_some();
|
return;
|
||||||
if let Some(name) = a.name();
|
}
|
||||||
if name == "proc_macro_derive";
|
for a in attrs {
|
||||||
then {
|
if_chain! {
|
||||||
return;
|
if a.meta_item_list().is_some();
|
||||||
|
if let Some(name) = a.name();
|
||||||
|
if name == "proc_macro_derive";
|
||||||
|
then {
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -87,7 +93,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessPassByValue {
|
|||||||
|
|
||||||
// Exclude non-inherent impls
|
// Exclude non-inherent impls
|
||||||
if let Some(NodeItem(item)) = cx.tcx.hir.find(cx.tcx.hir.get_parent_node(node_id)) {
|
if let Some(NodeItem(item)) = cx.tcx.hir.find(cx.tcx.hir.get_parent_node(node_id)) {
|
||||||
if matches!(item.node, ItemImpl(_, _, _, _, Some(_), _, _) | ItemAutoImpl(..) |
|
if matches!(item.node, ItemImpl(_, _, _, _, Some(_), _, _) |
|
||||||
ItemTrait(..))
|
ItemTrait(..))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@ -96,10 +102,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessPassByValue {
|
|||||||
|
|
||||||
// Allow `Borrow` or functions to be taken by value
|
// Allow `Borrow` or functions to be taken by value
|
||||||
let borrow_trait = need!(get_trait_def_id(cx, &paths::BORROW_TRAIT));
|
let borrow_trait = need!(get_trait_def_id(cx, &paths::BORROW_TRAIT));
|
||||||
let fn_traits = [
|
let whitelisted_traits = [
|
||||||
need!(cx.tcx.lang_items().fn_trait()),
|
need!(cx.tcx.lang_items().fn_trait()),
|
||||||
need!(cx.tcx.lang_items().fn_once_trait()),
|
need!(cx.tcx.lang_items().fn_once_trait()),
|
||||||
need!(cx.tcx.lang_items().fn_mut_trait()),
|
need!(cx.tcx.lang_items().fn_mut_trait()),
|
||||||
|
need!(get_trait_def_id(cx, &paths::RANGE_ARGUMENT_TRAIT))
|
||||||
];
|
];
|
||||||
|
|
||||||
let sized_trait = need!(cx.tcx.lang_items().sized_trait());
|
let sized_trait = need!(cx.tcx.lang_items().sized_trait());
|
||||||
@ -183,7 +190,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessPassByValue {
|
|||||||
if !is_self(arg);
|
if !is_self(arg);
|
||||||
if !ty.is_mutable_pointer();
|
if !ty.is_mutable_pointer();
|
||||||
if !is_copy(cx, ty);
|
if !is_copy(cx, ty);
|
||||||
if !fn_traits.iter().any(|&t| implements_trait(cx, ty, t, &[]));
|
if !whitelisted_traits.iter().any(|&t| implements_trait(cx, ty, t, &[]));
|
||||||
if !implements_borrow_trait;
|
if !implements_borrow_trait;
|
||||||
if !all_borrowable_trait;
|
if !all_borrowable_trait;
|
||||||
|
|
||||||
@ -196,6 +203,15 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessPassByValue {
|
|||||||
|
|
||||||
// Dereference suggestion
|
// Dereference suggestion
|
||||||
let sugg = |db: &mut DiagnosticBuilder| {
|
let sugg = |db: &mut DiagnosticBuilder| {
|
||||||
|
if let ty::TypeVariants::TyAdt(ref def, ..) = ty.sty {
|
||||||
|
if let Some(span) = cx.tcx.hir.span_if_local(def.did) {
|
||||||
|
let param_env = ty::ParamEnv::empty(traits::Reveal::UserFacing);
|
||||||
|
if param_env.can_type_implement_copy(cx.tcx, ty, span).is_ok() {
|
||||||
|
db.span_help(span, "consider marking this type as Copy");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let deref_span = spans_need_deref.get(&canonical_id);
|
let deref_span = spans_need_deref.get(&canonical_id);
|
||||||
if_chain! {
|
if_chain! {
|
||||||
if match_type(cx, ty, &paths::VEC);
|
if match_type(cx, ty, &paths::VEC);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use rustc::lint::*;
|
use rustc::lint::*;
|
||||||
use syntax::ast::*;
|
use syntax::ast::*;
|
||||||
use syntax::codemap::Spanned;
|
use syntax::codemap::Spanned;
|
||||||
use utils::{snippet, span_lint_and_sugg};
|
use utils::{in_macro, snippet, span_lint_and_sugg};
|
||||||
|
|
||||||
/// **What it does:** Checks for operations where precedence may be unclear
|
/// **What it does:** Checks for operations where precedence may be unclear
|
||||||
/// and suggests to add parentheses. Currently it catches the following:
|
/// and suggests to add parentheses. Currently it catches the following:
|
||||||
@ -37,6 +37,10 @@ impl LintPass for Precedence {
|
|||||||
|
|
||||||
impl EarlyLintPass for Precedence {
|
impl EarlyLintPass for Precedence {
|
||||||
fn check_expr(&mut self, cx: &EarlyContext, expr: &Expr) {
|
fn check_expr(&mut self, cx: &EarlyContext, expr: &Expr) {
|
||||||
|
if in_macro(expr.span) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if let ExprKind::Binary(Spanned { node: op, .. }, ref left, ref right) = expr.node {
|
if let ExprKind::Binary(Spanned { node: op, .. }, ref left, ref right) = expr.node {
|
||||||
let span_sugg = |expr: &Expr, sugg| {
|
let span_sugg = |expr: &Expr, sugg| {
|
||||||
span_lint_and_sugg(
|
span_lint_and_sugg(
|
||||||
|
@ -50,6 +50,26 @@ declare_lint! {
|
|||||||
"usage of `Box<Vec<T>>`, vector elements are already on the heap"
|
"usage of `Box<Vec<T>>`, vector elements are already on the heap"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// **What it does:** Checks for use of `Option<Option<_>>` in function signatures and type
|
||||||
|
/// definitions
|
||||||
|
///
|
||||||
|
/// **Why is this bad?** `Option<_>` represents an optional value. `Option<Option<_>>`
|
||||||
|
/// represents an optional optional value which is logically the same thing as an optional
|
||||||
|
/// value but has an unneeded extra level of wrapping.
|
||||||
|
///
|
||||||
|
/// **Known problems:** None.
|
||||||
|
///
|
||||||
|
/// **Example**
|
||||||
|
/// ```rust
|
||||||
|
/// fn x() -> Option<Option<u32>> {
|
||||||
|
/// None
|
||||||
|
/// }
|
||||||
|
declare_lint! {
|
||||||
|
pub OPTION_OPTION,
|
||||||
|
Warn,
|
||||||
|
"usage of `Option<Option<T>>`"
|
||||||
|
}
|
||||||
|
|
||||||
/// **What it does:** Checks for usage of any `LinkedList`, suggesting to use a
|
/// **What it does:** Checks for usage of any `LinkedList`, suggesting to use a
|
||||||
/// `Vec` or a `VecDeque` (formerly called `RingBuf`).
|
/// `Vec` or a `VecDeque` (formerly called `RingBuf`).
|
||||||
///
|
///
|
||||||
@ -111,7 +131,7 @@ declare_lint! {
|
|||||||
|
|
||||||
impl LintPass for TypePass {
|
impl LintPass for TypePass {
|
||||||
fn get_lints(&self) -> LintArray {
|
fn get_lints(&self) -> LintArray {
|
||||||
lint_array!(BOX_VEC, LINKEDLIST, BORROWED_BOX)
|
lint_array!(BOX_VEC, OPTION_OPTION, LINKEDLIST, BORROWED_BOX)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -156,6 +176,23 @@ fn check_fn_decl(cx: &LateContext, decl: &FnDecl) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Check if `qpath` has last segment with type parameter matching `path`
|
||||||
|
fn match_type_parameter(cx: &LateContext, qpath: &QPath, path: &[&str]) -> bool {
|
||||||
|
let last = last_path_segment(qpath);
|
||||||
|
if_chain! {
|
||||||
|
if let Some(ref params) = last.parameters;
|
||||||
|
if !params.parenthesized;
|
||||||
|
if let Some(ty) = params.types.get(0);
|
||||||
|
if let TyPath(ref qpath) = ty.node;
|
||||||
|
if let Some(did) = opt_def_id(cx.tables.qpath_def(qpath, cx.tcx.hir.node_to_hir_id(ty.id)));
|
||||||
|
if match_def_path(cx.tcx, did, path);
|
||||||
|
then {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
/// Recursively check for `TypePass` lints in the given type. Stop at the first
|
/// Recursively check for `TypePass` lints in the given type. Stop at the first
|
||||||
/// lint found.
|
/// lint found.
|
||||||
///
|
///
|
||||||
@ -171,24 +208,26 @@ fn check_ty(cx: &LateContext, ast_ty: &hir::Ty, is_local: bool) {
|
|||||||
let def = cx.tables.qpath_def(qpath, hir_id);
|
let def = cx.tables.qpath_def(qpath, hir_id);
|
||||||
if let Some(def_id) = opt_def_id(def) {
|
if let Some(def_id) = opt_def_id(def) {
|
||||||
if Some(def_id) == cx.tcx.lang_items().owned_box() {
|
if Some(def_id) == cx.tcx.lang_items().owned_box() {
|
||||||
let last = last_path_segment(qpath);
|
if match_type_parameter(cx, qpath, &paths::VEC) {
|
||||||
if_chain! {
|
span_help_and_lint(
|
||||||
if let Some(ref params) = last.parameters;
|
cx,
|
||||||
if !params.parenthesized;
|
BOX_VEC,
|
||||||
if let Some(vec) = params.types.get(0);
|
ast_ty.span,
|
||||||
if let TyPath(ref qpath) = vec.node;
|
"you seem to be trying to use `Box<Vec<T>>`. Consider using just `Vec<T>`",
|
||||||
if let Some(did) = opt_def_id(cx.tables.qpath_def(qpath, cx.tcx.hir.node_to_hir_id(vec.id)));
|
"`Vec<T>` is already on the heap, `Box<Vec<T>>` makes an extra allocation.",
|
||||||
if match_def_path(cx.tcx, did, &paths::VEC);
|
);
|
||||||
then {
|
return; // don't recurse into the type
|
||||||
span_help_and_lint(
|
}
|
||||||
cx,
|
} else if match_def_path(cx.tcx, def_id, &paths::OPTION) {
|
||||||
BOX_VEC,
|
if match_type_parameter(cx, qpath, &paths::OPTION) {
|
||||||
ast_ty.span,
|
span_lint(
|
||||||
"you seem to be trying to use `Box<Vec<T>>`. Consider using just `Vec<T>`",
|
cx,
|
||||||
"`Vec<T>` is already on the heap, `Box<Vec<T>>` makes an extra allocation.",
|
OPTION_OPTION,
|
||||||
);
|
ast_ty.span,
|
||||||
return; // don't recurse into the type
|
"consider using `Option<T>` instead of `Option<Option<T>>` or a custom \
|
||||||
}
|
enum if you need to distinguish all 3 cases",
|
||||||
|
);
|
||||||
|
return; // don't recurse into the type
|
||||||
}
|
}
|
||||||
} else if match_def_path(cx.tcx, def_id, &paths::LINKED_LIST) {
|
} else if match_def_path(cx.tcx, def_id, &paths::LINKED_LIST) {
|
||||||
span_help_and_lint(
|
span_help_and_lint(
|
||||||
@ -322,25 +361,22 @@ declare_lint! {
|
|||||||
|
|
||||||
fn check_let_unit(cx: &LateContext, decl: &Decl) {
|
fn check_let_unit(cx: &LateContext, decl: &Decl) {
|
||||||
if let DeclLocal(ref local) = decl.node {
|
if let DeclLocal(ref local) = decl.node {
|
||||||
match cx.tables.pat_ty(&local.pat).sty {
|
if is_unit(cx.tables.pat_ty(&local.pat)) {
|
||||||
ty::TyTuple(slice, _) if slice.is_empty() => {
|
if in_external_macro(cx, decl.span) || in_macro(local.pat.span) {
|
||||||
if in_external_macro(cx, decl.span) || in_macro(local.pat.span) {
|
return;
|
||||||
return;
|
}
|
||||||
}
|
if higher::is_from_for_desugar(decl) {
|
||||||
if higher::is_from_for_desugar(decl) {
|
return;
|
||||||
return;
|
}
|
||||||
}
|
span_lint(
|
||||||
span_lint(
|
cx,
|
||||||
cx,
|
LET_UNIT_VALUE,
|
||||||
LET_UNIT_VALUE,
|
decl.span,
|
||||||
decl.span,
|
&format!(
|
||||||
&format!(
|
"this let-binding has unit value. Consider omitting `let {} =`",
|
||||||
"this let-binding has unit value. Consider omitting `let {} =`",
|
snippet(cx, local.pat.span, "..")
|
||||||
snippet(cx, local.pat.span, "..")
|
),
|
||||||
),
|
);
|
||||||
);
|
|
||||||
},
|
|
||||||
_ => (),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -395,31 +431,118 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnitCmp {
|
|||||||
}
|
}
|
||||||
if let ExprBinary(ref cmp, ref left, _) = expr.node {
|
if let ExprBinary(ref cmp, ref left, _) = expr.node {
|
||||||
let op = cmp.node;
|
let op = cmp.node;
|
||||||
if op.is_comparison() {
|
if op.is_comparison() && is_unit(cx.tables.expr_ty(left)) {
|
||||||
match cx.tables.expr_ty(left).sty {
|
let result = match op {
|
||||||
ty::TyTuple(slice, _) if slice.is_empty() => {
|
BiEq | BiLe | BiGe => "true",
|
||||||
let result = match op {
|
_ => "false",
|
||||||
BiEq | BiLe | BiGe => "true",
|
};
|
||||||
_ => "false",
|
span_lint(
|
||||||
};
|
cx,
|
||||||
span_lint(
|
UNIT_CMP,
|
||||||
cx,
|
expr.span,
|
||||||
UNIT_CMP,
|
&format!(
|
||||||
expr.span,
|
"{}-comparison of unit values detected. This will always be {}",
|
||||||
&format!(
|
op.as_str(),
|
||||||
"{}-comparison of unit values detected. This will always be {}",
|
result
|
||||||
op.as_str(),
|
),
|
||||||
result
|
);
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
_ => (),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// **What it does:** Checks for passing a unit value as an argument to a function without using a unit literal (`()`).
|
||||||
|
///
|
||||||
|
/// **Why is this bad?** This is likely the result of an accidental semicolon.
|
||||||
|
///
|
||||||
|
/// **Known problems:** None.
|
||||||
|
///
|
||||||
|
/// **Example:**
|
||||||
|
/// ```rust
|
||||||
|
/// foo({
|
||||||
|
/// let a = bar();
|
||||||
|
/// baz(a);
|
||||||
|
/// })
|
||||||
|
/// ```
|
||||||
|
declare_lint! {
|
||||||
|
pub UNIT_ARG,
|
||||||
|
Warn,
|
||||||
|
"passing unit to a function"
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct UnitArg;
|
||||||
|
|
||||||
|
impl LintPass for UnitArg {
|
||||||
|
fn get_lints(&self) -> LintArray {
|
||||||
|
lint_array!(UNIT_ARG)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnitArg {
|
||||||
|
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
|
||||||
|
if in_macro(expr.span) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
match expr.node {
|
||||||
|
ExprCall(_, ref args) | ExprMethodCall(_, _, ref args) => {
|
||||||
|
for arg in args {
|
||||||
|
if is_unit(cx.tables.expr_ty(arg)) && !is_unit_literal(arg) {
|
||||||
|
let map = &cx.tcx.hir;
|
||||||
|
// apparently stuff in the desugaring of `?` can trigger this
|
||||||
|
// so check for that here
|
||||||
|
// only the calls to `Try::from_error` is marked as desugared,
|
||||||
|
// so we need to check both the current Expr and its parent.
|
||||||
|
if !is_questionmark_desugar_marked_call(expr) {
|
||||||
|
if_chain!{
|
||||||
|
let opt_parent_node = map.find(map.get_parent_node(expr.id));
|
||||||
|
if let Some(hir::map::NodeExpr(parent_expr)) = opt_parent_node;
|
||||||
|
if is_questionmark_desugar_marked_call(parent_expr);
|
||||||
|
then {}
|
||||||
|
else {
|
||||||
|
// `expr` and `parent_expr` where _both_ not from
|
||||||
|
// desugaring `?`, so lint
|
||||||
|
span_lint_and_sugg(
|
||||||
|
cx,
|
||||||
|
UNIT_ARG,
|
||||||
|
arg.span,
|
||||||
|
"passing a unit value to a function",
|
||||||
|
"if you intended to pass a unit value, use a unit literal instead",
|
||||||
|
"()".to_string(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_questionmark_desugar_marked_call(expr: &Expr) -> bool {
|
||||||
|
use syntax_pos::hygiene::CompilerDesugaringKind;
|
||||||
|
if let ExprCall(ref callee, _) = expr.node {
|
||||||
|
callee.span.is_compiler_desugaring(CompilerDesugaringKind::QuestionMark)
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_unit(ty: Ty) -> bool {
|
||||||
|
match ty.sty {
|
||||||
|
ty::TyTuple(slice, _) if slice.is_empty() => true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_unit_literal(expr: &Expr) -> bool {
|
||||||
|
match expr.node {
|
||||||
|
ExprTup(ref slice) if slice.is_empty() => true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct CastPass;
|
pub struct CastPass;
|
||||||
|
|
||||||
/// **What it does:** Checks for casts from any numerical to a float type where
|
/// **What it does:** Checks for casts from any numerical to a float type where
|
||||||
@ -1106,6 +1229,20 @@ enum AbsurdComparisonResult {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn is_cast_between_fixed_and_target<'a, 'tcx>(
|
||||||
|
cx: &LateContext<'a, 'tcx>,
|
||||||
|
expr: &'tcx Expr
|
||||||
|
) -> bool {
|
||||||
|
|
||||||
|
if let ExprCast(ref cast_exp, _) = expr.node {
|
||||||
|
let precast_ty = cx.tables.expr_ty(cast_exp);
|
||||||
|
let cast_ty = cx.tables.expr_ty(expr);
|
||||||
|
|
||||||
|
return is_isize_or_usize(precast_ty) != is_isize_or_usize(cast_ty)
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
fn detect_absurd_comparison<'a, 'tcx>(
|
fn detect_absurd_comparison<'a, 'tcx>(
|
||||||
cx: &LateContext<'a, 'tcx>,
|
cx: &LateContext<'a, 'tcx>,
|
||||||
@ -1123,6 +1260,11 @@ fn detect_absurd_comparison<'a, 'tcx>(
|
|||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// comparisons between fix sized types and target sized types are considered unanalyzable
|
||||||
|
if is_cast_between_fixed_and_target(cx, lhs) || is_cast_between_fixed_and_target(cx, rhs) {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
let normalized = normalize_comparison(op, lhs, rhs);
|
let normalized = normalize_comparison(op, lhs, rhs);
|
||||||
let (rel, normalized_lhs, normalized_rhs) = if let Some(val) = normalized {
|
let (rel, normalized_lhs, normalized_rhs) = if let Some(val) = normalized {
|
||||||
val
|
val
|
||||||
|
@ -406,9 +406,6 @@ fn print_item(cx: &LateContext, item: &hir::Item) {
|
|||||||
hir::ItemTraitAlias(..) => {
|
hir::ItemTraitAlias(..) => {
|
||||||
println!("trait alias");
|
println!("trait alias");
|
||||||
}
|
}
|
||||||
hir::ItemAutoImpl(_, ref _trait_ref) => {
|
|
||||||
println!("auto impl");
|
|
||||||
},
|
|
||||||
hir::ItemImpl(_, _, _, _, Some(ref _trait_ref), _, _) => {
|
hir::ItemImpl(_, _, _, _, Some(ref _trait_ref), _, _) => {
|
||||||
println!("trait impl");
|
println!("trait impl");
|
||||||
},
|
},
|
||||||
|
@ -55,6 +55,7 @@ pub const OPTION_SOME: [&str; 4] = ["core", "option", "Option", "Some"];
|
|||||||
pub const PTR_NULL: [&str; 2] = ["ptr", "null"];
|
pub const PTR_NULL: [&str; 2] = ["ptr", "null"];
|
||||||
pub const PTR_NULL_MUT: [&str; 2] = ["ptr", "null_mut"];
|
pub const PTR_NULL_MUT: [&str; 2] = ["ptr", "null_mut"];
|
||||||
pub const RANGE: [&str; 3] = ["core", "ops", "Range"];
|
pub const RANGE: [&str; 3] = ["core", "ops", "Range"];
|
||||||
|
pub const RANGE_ARGUMENT_TRAIT: [&str; 3] = ["alloc", "range", "RangeArgument"];
|
||||||
pub const RANGE_FROM: [&str; 3] = ["core", "ops", "RangeFrom"];
|
pub const RANGE_FROM: [&str; 3] = ["core", "ops", "RangeFrom"];
|
||||||
pub const RANGE_FROM_STD: [&str; 3] = ["std", "ops", "RangeFrom"];
|
pub const RANGE_FROM_STD: [&str; 3] = ["std", "ops", "RangeFrom"];
|
||||||
pub const RANGE_FULL: [&str; 3] = ["core", "ops", "RangeFull"];
|
pub const RANGE_FULL: [&str; 3] = ["core", "ops", "RangeFull"];
|
||||||
|
@ -15,6 +15,7 @@ use syntax::print::pprust::token_to_string;
|
|||||||
use syntax::util::parser::AssocOp;
|
use syntax::util::parser::AssocOp;
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use utils::{higher, snippet, snippet_opt};
|
use utils::{higher, snippet, snippet_opt};
|
||||||
|
use syntax_pos::{BytePos, Pos};
|
||||||
|
|
||||||
/// A helper type to build suggestion correctly handling parenthesis.
|
/// A helper type to build suggestion correctly handling parenthesis.
|
||||||
pub enum Sugg<'a> {
|
pub enum Sugg<'a> {
|
||||||
@ -454,6 +455,19 @@ pub trait DiagnosticBuilderExt<'a, T: LintContext<'a>> {
|
|||||||
/// }");
|
/// }");
|
||||||
/// ```
|
/// ```
|
||||||
fn suggest_prepend_item(&mut self, cx: &T, item: Span, msg: &str, new_item: &str);
|
fn suggest_prepend_item(&mut self, cx: &T, item: Span, msg: &str, new_item: &str);
|
||||||
|
|
||||||
|
/// Suggest to completely remove an item.
|
||||||
|
///
|
||||||
|
/// This will remove an item and all following whitespace until the next non-whitespace
|
||||||
|
/// character. This should work correctly if item is on the same indentation level as the
|
||||||
|
/// following item.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```rust,ignore
|
||||||
|
/// db.suggest_remove_item(cx, item, "remove this")
|
||||||
|
/// ```
|
||||||
|
fn suggest_remove_item(&mut self, cx: &T, item: Span, msg: &str);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'b, 'c, T: LintContext<'c>> DiagnosticBuilderExt<'c, T> for rustc_errors::DiagnosticBuilder<'b> {
|
impl<'a, 'b, 'c, T: LintContext<'c>> DiagnosticBuilderExt<'c, T> for rustc_errors::DiagnosticBuilder<'b> {
|
||||||
@ -485,4 +499,21 @@ impl<'a, 'b, 'c, T: LintContext<'c>> DiagnosticBuilderExt<'c, T> for rustc_error
|
|||||||
self.span_suggestion(span, msg, format!("{}\n{}", new_item, indent));
|
self.span_suggestion(span, msg, format!("{}\n{}", new_item, indent));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn suggest_remove_item(&mut self, cx: &T, item: Span, msg: &str) {
|
||||||
|
let mut remove_span = item;
|
||||||
|
let fmpos = cx.sess()
|
||||||
|
.codemap()
|
||||||
|
.lookup_byte_offset(remove_span.next_point().hi());
|
||||||
|
|
||||||
|
if let Some(ref src) = fmpos.fm.src {
|
||||||
|
let non_whitespace_offset = src[fmpos.pos.to_usize()..].find(|c| c != ' ' && c != '\t' && c != '\n');
|
||||||
|
|
||||||
|
if let Some(non_whitespace_offset) = non_whitespace_offset {
|
||||||
|
remove_span = remove_span.with_hi(remove_span.hi() + BytePos(non_whitespace_offset as u32))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.span_suggestion(remove_span, msg, String::new());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ extern crate rustc_plugin;
|
|||||||
extern crate syntax;
|
extern crate syntax;
|
||||||
|
|
||||||
use rustc_driver::{driver, Compilation, CompilerCalls, RustcDefaultCalls};
|
use rustc_driver::{driver, Compilation, CompilerCalls, RustcDefaultCalls};
|
||||||
use rustc::session::{config, CompileIncomplete, Session};
|
use rustc::session::{config, Session};
|
||||||
use rustc::session::config::{ErrorOutputType, Input};
|
use rustc::session::config::{ErrorOutputType, Input};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
@ -153,47 +153,44 @@ pub fn main() {
|
|||||||
})
|
})
|
||||||
.expect("need to specify SYSROOT env var during clippy compilation, or use rustup or multirust");
|
.expect("need to specify SYSROOT env var during clippy compilation, or use rustup or multirust");
|
||||||
|
|
||||||
rustc_driver::in_rustc_thread(|| {
|
// Setting RUSTC_WRAPPER causes Cargo to pass 'rustc' as the first argument.
|
||||||
// Setting RUSTC_WRAPPER causes Cargo to pass 'rustc' as the first argument.
|
// We're invoking the compiler programmatically, so we ignore this/
|
||||||
// We're invoking the compiler programmatically, so we ignore this/
|
let mut orig_args: Vec<String> = env::args().collect();
|
||||||
let mut orig_args: Vec<String> = env::args().collect();
|
if orig_args.len() <= 1 {
|
||||||
if orig_args.len() <= 1 {
|
std::process::exit(1);
|
||||||
std::process::exit(1);
|
}
|
||||||
}
|
if orig_args[1] == "rustc" {
|
||||||
if orig_args[1] == "rustc" {
|
// we still want to be able to invoke it normally though
|
||||||
// we still want to be able to invoke it normally though
|
orig_args.remove(1);
|
||||||
orig_args.remove(1);
|
}
|
||||||
}
|
// this conditional check for the --sysroot flag is there so users can call
|
||||||
// this conditional check for the --sysroot flag is there so users can call
|
// `clippy_driver` directly
|
||||||
// `clippy_driver` directly
|
// without having to pass --sysroot or anything
|
||||||
// without having to pass --sysroot or anything
|
let mut args: Vec<String> = if orig_args.iter().any(|s| s == "--sysroot") {
|
||||||
let mut args: Vec<String> = if orig_args.iter().any(|s| s == "--sysroot") {
|
orig_args.clone()
|
||||||
orig_args.clone()
|
} else {
|
||||||
} else {
|
orig_args
|
||||||
orig_args
|
.clone()
|
||||||
.clone()
|
.into_iter()
|
||||||
.into_iter()
|
.chain(Some("--sysroot".to_owned()))
|
||||||
.chain(Some("--sysroot".to_owned()))
|
.chain(Some(sys_root))
|
||||||
.chain(Some(sys_root))
|
.collect()
|
||||||
.collect()
|
};
|
||||||
};
|
|
||||||
|
|
||||||
// this check ensures that dependencies are built but not linted and the final
|
// this check ensures that dependencies are built but not linted and the final
|
||||||
// crate is
|
// crate is
|
||||||
// linted but not built
|
// linted but not built
|
||||||
let clippy_enabled = env::var("CLIPPY_TESTS")
|
let clippy_enabled = env::var("CLIPPY_TESTS")
|
||||||
.ok()
|
.ok()
|
||||||
.map_or(false, |val| val == "true")
|
.map_or(false, |val| val == "true")
|
||||||
|| orig_args.iter().any(|s| s == "--emit=metadata");
|
|| orig_args.iter().any(|s| s == "--emit=metadata");
|
||||||
|
|
||||||
if clippy_enabled {
|
if clippy_enabled {
|
||||||
args.extend_from_slice(&["--cfg".to_owned(), r#"feature="cargo-clippy""#.to_owned()]);
|
args.extend_from_slice(&["--cfg".to_owned(), r#"feature="cargo-clippy""#.to_owned()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut ccc = ClippyCompilerCalls::new(clippy_enabled);
|
let mut ccc = ClippyCompilerCalls::new(clippy_enabled);
|
||||||
let (result, _) = rustc_driver::run_compiler(&args, &mut ccc, None, None);
|
rustc_driver::run(move || {
|
||||||
if let Err(CompileIncomplete::Errored(_)) = result {
|
rustc_driver::run_compiler(&args, &mut ccc, None, None)
|
||||||
std::process::exit(1);
|
});
|
||||||
}
|
|
||||||
}).expect("rustc_thread failed");
|
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,9 @@ fn config(dir: &'static str, mode: &'static str) -> compiletest::Config {
|
|||||||
config.target_rustcflags = Some(format!("-L {0} -L {0}/deps -Dwarnings", host_libs().display()));
|
config.target_rustcflags = Some(format!("-L {0} -L {0}/deps -Dwarnings", host_libs().display()));
|
||||||
|
|
||||||
config.mode = cfg_mode;
|
config.mode = cfg_mode;
|
||||||
config.build_base = {
|
config.build_base = if rustc_test_suite().is_some() {
|
||||||
|
PathBuf::from("/tmp/clippy_test_build_base")
|
||||||
|
} else {
|
||||||
let mut path = std::env::current_dir().unwrap();
|
let mut path = std::env::current_dir().unwrap();
|
||||||
path.push("target/debug/test_build_base");
|
path.push("target/debug/test_build_base");
|
||||||
path
|
path
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
#[test]
|
#[test]
|
||||||
fn dogfood() {
|
fn dogfood() {
|
||||||
|
if option_env!("RUSTC_TEST_SUITE").is_some() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
let root_dir = std::env::current_dir().unwrap();
|
let root_dir = std::env::current_dir().unwrap();
|
||||||
for d in &[".", "clippy_lints"] {
|
for d in &[".", "clippy_lints"] {
|
||||||
std::env::set_current_dir(root_dir.join(d)).unwrap();
|
std::env::set_current_dir(root_dir.join(d)).unwrap();
|
||||||
|
@ -50,3 +50,8 @@ impl PartialOrd<u32> for U {
|
|||||||
pub fn foo(val: U) -> bool {
|
pub fn foo(val: U) -> bool {
|
||||||
val > std::u32::MAX
|
val > std::u32::MAX
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn bar(len: u64) -> bool {
|
||||||
|
// This is OK as we are casting from target sized to fixed size
|
||||||
|
len >= std::usize::MAX as u64
|
||||||
|
}
|
||||||
|
@ -143,3 +143,5 @@ error: <-comparison of unit values detected. This will always be false
|
|||||||
|
|
|
|
||||||
= note: `-D unit-cmp` implied by `-D warnings`
|
= note: `-D unit-cmp` implied by `-D warnings`
|
||||||
|
|
||||||
|
error: aborting due to 18 previous errors
|
||||||
|
|
||||||
|
@ -114,3 +114,5 @@ error: approximate value of `f{32, 64}::consts::SQRT_2` found. Consider using it
|
|||||||
55 | let my_sq2 = 1.4142;
|
55 | let my_sq2 = 1.4142;
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 19 previous errors
|
||||||
|
|
||||||
|
@ -69,3 +69,5 @@ error: floating-point arithmetic detected
|
|||||||
29 | -f;
|
29 | -f;
|
||||||
| ^^
|
| ^^
|
||||||
|
|
||||||
|
error: aborting due to 11 previous errors
|
||||||
|
|
||||||
|
@ -116,3 +116,5 @@ error: range is out of bounds
|
|||||||
44 | &empty[..4];
|
44 | &empty[..4];
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 19 previous errors
|
||||||
|
|
||||||
|
@ -134,3 +134,5 @@ error: manual implementation of an assign operation
|
|||||||
40 | s = s + "bla";
|
40 | s = s + "bla";
|
||||||
| ^^^^^^^^^^^^^ help: replace it with: `s += "bla"`
|
| ^^^^^^^^^^^^^ help: replace it with: `s += "bla"`
|
||||||
|
|
||||||
|
error: aborting due to 22 previous errors
|
||||||
|
|
||||||
|
@ -48,3 +48,5 @@ error: variable appears on both sides of an assignment operation
|
|||||||
15 | a &= a & 1;
|
15 | a &= a & 1;
|
||||||
| ^^^^^^^^^^ help: replace it with: `a &= 1`
|
| ^^^^^^^^^^ help: replace it with: `a &= 1`
|
||||||
|
|
||||||
|
error: aborting due to 8 previous errors
|
||||||
|
|
||||||
|
@ -20,3 +20,5 @@ error: the since field must contain a semver-compliant version
|
|||||||
30 | #[deprecated(since = "1")]
|
30 | #[deprecated(since = "1")]
|
||||||
| ^^^^^^^^^^^
|
| ^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
@ -106,3 +106,5 @@ error: ineffective bit mask: `x | 1` compared to `8`, is the same as x compared
|
|||||||
55 | x | 1 >= 8;
|
55 | x | 1 >= 8;
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 17 previous errors
|
||||||
|
|
||||||
|
@ -84,3 +84,5 @@ error: use of a blacklisted/placeholder name `baz`
|
|||||||
35 | if let Some(ref mut baz) = Some(42) {}
|
35 | if let Some(ref mut baz) = Some(42) {}
|
||||||
| ^^^
|
| ^^^
|
||||||
|
|
||||||
|
error: aborting due to 14 previous errors
|
||||||
|
|
||||||
|
@ -50,3 +50,5 @@ error: this boolean expression can be simplified
|
|||||||
|
|
|
|
||||||
= note: `-D nonminimal-bool` implied by `-D warnings`
|
= note: `-D nonminimal-bool` implied by `-D warnings`
|
||||||
|
|
||||||
|
error: aborting due to 5 previous errors
|
||||||
|
|
||||||
|
@ -24,3 +24,5 @@ error: equality checks against false can be replaced by a negation
|
|||||||
10 | if false == x { "yes" } else { "no" };
|
10 | if false == x { "yes" } else { "no" };
|
||||||
| ^^^^^^^^^^ help: try simplifying it as shown: `!x`
|
| ^^^^^^^^^^ help: try simplifying it as shown: `!x`
|
||||||
|
|
||||||
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
|
@ -175,3 +175,5 @@ error: this boolean expression can be simplified
|
|||||||
58 | let _ = !c ^ c || !a.is_some();
|
58 | let _ = !c ^ c || !a.is_some();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^ help: try: `!c ^ c || a.is_none()`
|
| ^^^^^^^^^^^^^^^^^^^^^^ help: try: `!c ^ c || a.is_none()`
|
||||||
|
|
||||||
|
error: aborting due to 21 previous errors
|
||||||
|
|
||||||
|
@ -28,3 +28,5 @@ error: you seem to be trying to use `&Box<T>`. Consider using just `&T`
|
|||||||
22 | fn test4(a: &Box<bool>);
|
22 | fn test4(a: &Box<bool>);
|
||||||
| ^^^^^^^^^^ help: try: `&bool`
|
| ^^^^^^^^^^ help: try: `&bool`
|
||||||
|
|
||||||
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
|
@ -7,3 +7,5 @@ error: you seem to be trying to use `Box<Vec<T>>`. Consider using just `Vec<T>`
|
|||||||
= note: `-D box-vec` implied by `-D warnings`
|
= note: `-D box-vec` implied by `-D warnings`
|
||||||
= help: `Vec<T>` is already on the heap, `Box<Vec<T>>` makes an extra allocation.
|
= help: `Vec<T>` is already on the heap, `Box<Vec<T>>` makes an extra allocation.
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
@ -17,3 +17,5 @@ error[E0308]: mismatched types
|
|||||||
= note: expected type `u32`
|
= note: expected type `u32`
|
||||||
found type `{integer}`
|
found type `{integer}`
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
@ -22,3 +22,5 @@ error: You appear to be counting bytes the naive way
|
|||||||
22 | let _ = x.iter().filter(|a| b + 1 == **a).count(); // naive byte count
|
22 | let _ = x.iter().filter(|a| b + 1 == **a).count(); // naive byte count
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: Consider using the bytecount crate: `bytecount::count(x, b + 1)`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: Consider using the bytecount crate: `bytecount::count(x, b + 1)`
|
||||||
|
|
||||||
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
@ -178,3 +178,5 @@ error: casting to the same type is unnecessary (`bool` -> `bool`)
|
|||||||
39 | false as bool;
|
39 | false as bool;
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 28 previous errors
|
||||||
|
|
||||||
|
@ -60,3 +60,5 @@ error: casting u32 to f64 may become silently lossy if types change
|
|||||||
14 | 1u32 as f64;
|
14 | 1u32 as f64;
|
||||||
| ^^^^^^^^^^^ help: try: `f64::from(1u32)`
|
| ^^^^^^^^^^^ help: try: `f64::from(1u32)`
|
||||||
|
|
||||||
|
error: aborting due to 10 previous errors
|
||||||
|
|
||||||
|
@ -108,3 +108,5 @@ error: casting u32 to u64 may become silently lossy if types change
|
|||||||
23 | 1u32 as u64;
|
23 | 1u32 as u64;
|
||||||
| ^^^^^^^^^^^ help: try: `u64::from(1u32)`
|
| ^^^^^^^^^^^ help: try: `u64::from(1u32)`
|
||||||
|
|
||||||
|
error: aborting due to 18 previous errors
|
||||||
|
|
||||||
|
@ -120,3 +120,5 @@ error: casting i32 to usize may lose the sign of the value
|
|||||||
22 | 1i32 as usize;
|
22 | 1i32 as usize;
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 19 previous errors
|
||||||
|
|
||||||
|
@ -8,3 +8,5 @@ error: casting character literal to u8. `char`s are 4 bytes wide in rust, so cas
|
|||||||
= help: Consider using a byte literal instead:
|
= help: Consider using a byte literal instead:
|
||||||
b'a'
|
b'a'
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
@ -72,3 +72,5 @@ error: doomed comparison with NAN, use `std::{f32,f64}::is_nan()` instead
|
|||||||
21 | y >= std::f64::NAN;
|
21 | y >= std::f64::NAN;
|
||||||
| ^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 12 previous errors
|
||||||
|
|
||||||
|
@ -12,3 +12,5 @@ error: Comparing with null is better expressed by the .is_null() method
|
|||||||
16 | if m == ptr::null_mut() {
|
16 | if m == ptr::null_mut() {
|
||||||
| ^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
@ -36,3 +36,5 @@ error: this creates an owned instance just for comparison
|
|||||||
30 | self.to_owned() == *other
|
30 | self.to_owned() == *other
|
||||||
| ^^^^^^^^^^^^^^^ try calling implementing the comparison without allocating
|
| ^^^^^^^^^^^^^^^ try calling implementing the comparison without allocating
|
||||||
|
|
||||||
|
error: aborting due to 6 previous errors
|
||||||
|
|
||||||
|
@ -240,3 +240,5 @@ help: try
|
|||||||
112 | }
|
112 | }
|
||||||
|
|
|
|
||||||
|
|
||||||
|
error: aborting due to 13 previous errors
|
||||||
|
|
||||||
|
@ -90,3 +90,5 @@ error: very complex type used. Consider factoring parts into `type` definitions
|
|||||||
40 | let _y: Vec<Vec<Box<(u32, u32, u32, u32)>>> = vec![];
|
40 | let _y: Vec<Vec<Box<(u32, u32, u32, u32)>>> = vec![];
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 15 previous errors
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
error: compiler plugins are experimental and possibly buggy (see issue #29597)
|
error[E0658]: compiler plugins are experimental and possibly buggy (see issue #29597)
|
||||||
--> $DIR/conf_bad_arg.rs:4:1
|
--> $DIR/conf_bad_arg.rs:4:1
|
||||||
|
|
|
|
||||||
4 | #![plugin(clippy(conf_file))]
|
4 | #![plugin(clippy(conf_file))]
|
||||||
@ -6,3 +6,5 @@ error: compiler plugins are experimental and possibly buggy (see issue #29597)
|
|||||||
|
|
|
|
||||||
= help: add #![feature(plugin)] to the crate attributes to enable
|
= help: add #![feature(plugin)] to the crate attributes to enable
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
error: compiler plugins are experimental and possibly buggy (see issue #29597)
|
error[E0658]: compiler plugins are experimental and possibly buggy (see issue #29597)
|
||||||
--> $DIR/conf_bad_toml.rs:4:1
|
--> $DIR/conf_bad_toml.rs:4:1
|
||||||
|
|
|
|
||||||
4 | #![plugin(clippy(conf_file="../ui/conf_bad_toml.toml"))]
|
4 | #![plugin(clippy(conf_file="../ui/conf_bad_toml.toml"))]
|
||||||
@ -6,3 +6,5 @@ error: compiler plugins are experimental and possibly buggy (see issue #29597)
|
|||||||
|
|
|
|
||||||
= help: add #![feature(plugin)] to the crate attributes to enable
|
= help: add #![feature(plugin)] to the crate attributes to enable
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
error: compiler plugins are experimental and possibly buggy (see issue #29597)
|
error[E0658]: compiler plugins are experimental and possibly buggy (see issue #29597)
|
||||||
--> $DIR/conf_bad_type.rs:4:1
|
--> $DIR/conf_bad_type.rs:4:1
|
||||||
|
|
|
|
||||||
4 | #![plugin(clippy(conf_file="../ui/conf_bad_type.toml"))]
|
4 | #![plugin(clippy(conf_file="../ui/conf_bad_type.toml"))]
|
||||||
@ -6,3 +6,5 @@ error: compiler plugins are experimental and possibly buggy (see issue #29597)
|
|||||||
|
|
|
|
||||||
= help: add #![feature(plugin)] to the crate attributes to enable
|
= help: add #![feature(plugin)] to the crate attributes to enable
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
error: compiler plugins are experimental and possibly buggy (see issue #29597)
|
error[E0658]: compiler plugins are experimental and possibly buggy (see issue #29597)
|
||||||
--> $DIR/conf_french_blacklisted_name.rs:2:1
|
--> $DIR/conf_french_blacklisted_name.rs:2:1
|
||||||
|
|
|
|
||||||
2 | #![plugin(clippy(conf_file="../auxiliary/conf_french_blacklisted_name.toml"))]
|
2 | #![plugin(clippy(conf_file="../auxiliary/conf_french_blacklisted_name.toml"))]
|
||||||
@ -6,3 +6,5 @@ error: compiler plugins are experimental and possibly buggy (see issue #29597)
|
|||||||
|
|
|
|
||||||
= help: add #![feature(plugin)] to the crate attributes to enable
|
= help: add #![feature(plugin)] to the crate attributes to enable
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
error: compiler plugins are experimental and possibly buggy (see issue #29597)
|
error[E0658]: compiler plugins are experimental and possibly buggy (see issue #29597)
|
||||||
--> $DIR/conf_path_non_string.rs:3:1
|
--> $DIR/conf_path_non_string.rs:3:1
|
||||||
|
|
|
|
||||||
3 | #![plugin(clippy(conf_file=42))]
|
3 | #![plugin(clippy(conf_file=42))]
|
||||||
@ -6,3 +6,5 @@ error: compiler plugins are experimental and possibly buggy (see issue #29597)
|
|||||||
|
|
|
|
||||||
= help: add #![feature(plugin)] to the crate attributes to enable
|
= help: add #![feature(plugin)] to the crate attributes to enable
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
error: compiler plugins are experimental and possibly buggy (see issue #29597)
|
error[E0658]: compiler plugins are experimental and possibly buggy (see issue #29597)
|
||||||
--> $DIR/conf_unknown_key.rs:4:1
|
--> $DIR/conf_unknown_key.rs:4:1
|
||||||
|
|
|
|
||||||
4 | #![plugin(clippy(conf_file="../auxiliary/conf_unknown_key.toml"))]
|
4 | #![plugin(clippy(conf_file="../auxiliary/conf_unknown_key.toml"))]
|
||||||
@ -6,3 +6,5 @@ error: compiler plugins are experimental and possibly buggy (see issue #29597)
|
|||||||
|
|
|
|
||||||
= help: add #![feature(plugin)] to the crate attributes to enable
|
= help: add #![feature(plugin)] to the crate attributes to enable
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ error: Constants have by default a `'static` lifetime
|
|||||||
--> $DIR/const_static_lifetime.rs:4:17
|
--> $DIR/const_static_lifetime.rs:4:17
|
||||||
|
|
|
|
||||||
4 | const VAR_ONE: &'static str = "Test constant #1"; // ERROR Consider removing 'static.
|
4 | const VAR_ONE: &'static str = "Test constant #1"; // ERROR Consider removing 'static.
|
||||||
| ^^^^^^^ help: consider removing `'static`
|
| -^^^^^^^---- help: consider removing `'static`: `&str`
|
||||||
|
|
|
|
||||||
= note: `-D const-static-lifetime` implied by `-D warnings`
|
= note: `-D const-static-lifetime` implied by `-D warnings`
|
||||||
|
|
||||||
@ -10,71 +10,73 @@ error: Constants have by default a `'static` lifetime
|
|||||||
--> $DIR/const_static_lifetime.rs:8:21
|
--> $DIR/const_static_lifetime.rs:8:21
|
||||||
|
|
|
|
||||||
8 | const VAR_THREE: &[&'static str] = &["one", "two"]; // ERROR Consider removing 'static
|
8 | const VAR_THREE: &[&'static str] = &["one", "two"]; // ERROR Consider removing 'static
|
||||||
| ^^^^^^^ help: consider removing `'static`
|
| -^^^^^^^---- help: consider removing `'static`: `&str`
|
||||||
|
|
||||||
error: Constants have by default a `'static` lifetime
|
error: Constants have by default a `'static` lifetime
|
||||||
--> $DIR/const_static_lifetime.rs:10:32
|
--> $DIR/const_static_lifetime.rs:10:32
|
||||||
|
|
|
|
||||||
10 | const VAR_FOUR: (&str, (&str, &'static str), &'static str) = ("on", ("th", "th"), "on"); // ERROR Consider removing 'static
|
10 | const VAR_FOUR: (&str, (&str, &'static str), &'static str) = ("on", ("th", "th"), "on"); // ERROR Consider removing 'static
|
||||||
| ^^^^^^^ help: consider removing `'static`
|
| -^^^^^^^---- help: consider removing `'static`: `&str`
|
||||||
|
|
||||||
error: Constants have by default a `'static` lifetime
|
error: Constants have by default a `'static` lifetime
|
||||||
--> $DIR/const_static_lifetime.rs:10:47
|
--> $DIR/const_static_lifetime.rs:10:47
|
||||||
|
|
|
|
||||||
10 | const VAR_FOUR: (&str, (&str, &'static str), &'static str) = ("on", ("th", "th"), "on"); // ERROR Consider removing 'static
|
10 | const VAR_FOUR: (&str, (&str, &'static str), &'static str) = ("on", ("th", "th"), "on"); // ERROR Consider removing 'static
|
||||||
| ^^^^^^^ help: consider removing `'static`
|
| -^^^^^^^---- help: consider removing `'static`: `&str`
|
||||||
|
|
||||||
error: Constants have by default a `'static` lifetime
|
error: Constants have by default a `'static` lifetime
|
||||||
--> $DIR/const_static_lifetime.rs:12:18
|
--> $DIR/const_static_lifetime.rs:12:18
|
||||||
|
|
|
|
||||||
12 | const VAR_FIVE: &'static [&[&'static str]] = &[&["test"], &["other one"]]; // ERROR Consider removing 'static
|
12 | const VAR_FIVE: &'static [&[&'static str]] = &[&["test"], &["other one"]]; // ERROR Consider removing 'static
|
||||||
| ^^^^^^^ help: consider removing `'static`
|
| -^^^^^^^------------------ help: consider removing `'static`: `&[&[&'static str]]`
|
||||||
|
|
||||||
error: Constants have by default a `'static` lifetime
|
error: Constants have by default a `'static` lifetime
|
||||||
--> $DIR/const_static_lifetime.rs:12:30
|
--> $DIR/const_static_lifetime.rs:12:30
|
||||||
|
|
|
|
||||||
12 | const VAR_FIVE: &'static [&[&'static str]] = &[&["test"], &["other one"]]; // ERROR Consider removing 'static
|
12 | const VAR_FIVE: &'static [&[&'static str]] = &[&["test"], &["other one"]]; // ERROR Consider removing 'static
|
||||||
| ^^^^^^^ help: consider removing `'static`
|
| -^^^^^^^---- help: consider removing `'static`: `&str`
|
||||||
|
|
||||||
error: Constants have by default a `'static` lifetime
|
error: Constants have by default a `'static` lifetime
|
||||||
--> $DIR/const_static_lifetime.rs:14:17
|
--> $DIR/const_static_lifetime.rs:14:17
|
||||||
|
|
|
|
||||||
14 | const VAR_SIX: &'static u8 = &5;
|
14 | const VAR_SIX: &'static u8 = &5;
|
||||||
| ^^^^^^^ help: consider removing `'static`
|
| -^^^^^^^--- help: consider removing `'static`: `&u8`
|
||||||
|
|
||||||
error: Constants have by default a `'static` lifetime
|
error: Constants have by default a `'static` lifetime
|
||||||
--> $DIR/const_static_lifetime.rs:16:29
|
--> $DIR/const_static_lifetime.rs:16:29
|
||||||
|
|
|
|
||||||
16 | const VAR_SEVEN: &[&(&str, &'static [&'static str])] = &[&("one", &["other one"])];
|
16 | const VAR_SEVEN: &[&(&str, &'static [&'static str])] = &[&("one", &["other one"])];
|
||||||
| ^^^^^^^ help: consider removing `'static`
|
| -^^^^^^^--------------- help: consider removing `'static`: `&[&'static str]`
|
||||||
|
|
||||||
error: Constants have by default a `'static` lifetime
|
error: Constants have by default a `'static` lifetime
|
||||||
--> $DIR/const_static_lifetime.rs:16:39
|
--> $DIR/const_static_lifetime.rs:16:39
|
||||||
|
|
|
|
||||||
16 | const VAR_SEVEN: &[&(&str, &'static [&'static str])] = &[&("one", &["other one"])];
|
16 | const VAR_SEVEN: &[&(&str, &'static [&'static str])] = &[&("one", &["other one"])];
|
||||||
| ^^^^^^^ help: consider removing `'static`
|
| -^^^^^^^---- help: consider removing `'static`: `&str`
|
||||||
|
|
||||||
error: Constants have by default a `'static` lifetime
|
error: Constants have by default a `'static` lifetime
|
||||||
--> $DIR/const_static_lifetime.rs:18:20
|
--> $DIR/const_static_lifetime.rs:18:20
|
||||||
|
|
|
|
||||||
18 | const VAR_HEIGHT: &'static Foo = &Foo {};
|
18 | const VAR_HEIGHT: &'static Foo = &Foo {};
|
||||||
| ^^^^^^^ help: consider removing `'static`
|
| -^^^^^^^---- help: consider removing `'static`: `&Foo`
|
||||||
|
|
||||||
error: Constants have by default a `'static` lifetime
|
error: Constants have by default a `'static` lifetime
|
||||||
--> $DIR/const_static_lifetime.rs:20:19
|
--> $DIR/const_static_lifetime.rs:20:19
|
||||||
|
|
|
|
||||||
20 | const VAR_SLICE: &'static [u8] = b"Test constant #1"; // ERROR Consider removing 'static.
|
20 | const VAR_SLICE: &'static [u8] = b"Test constant #1"; // ERROR Consider removing 'static.
|
||||||
| ^^^^^^^ help: consider removing `'static`
|
| -^^^^^^^----- help: consider removing `'static`: `&[u8]`
|
||||||
|
|
||||||
error: Constants have by default a `'static` lifetime
|
error: Constants have by default a `'static` lifetime
|
||||||
--> $DIR/const_static_lifetime.rs:22:19
|
--> $DIR/const_static_lifetime.rs:22:19
|
||||||
|
|
|
|
||||||
22 | const VAR_TUPLE: &'static (u8, u8) = &(1, 2); // ERROR Consider removing 'static.
|
22 | const VAR_TUPLE: &'static (u8, u8) = &(1, 2); // ERROR Consider removing 'static.
|
||||||
| ^^^^^^^ help: consider removing `'static`
|
| -^^^^^^^--------- help: consider removing `'static`: `&(u8, u8)`
|
||||||
|
|
||||||
error: Constants have by default a `'static` lifetime
|
error: Constants have by default a `'static` lifetime
|
||||||
--> $DIR/const_static_lifetime.rs:24:19
|
--> $DIR/const_static_lifetime.rs:24:19
|
||||||
|
|
|
|
||||||
24 | const VAR_ARRAY: &'static [u8; 1] = b"T"; // ERROR Consider removing 'static.
|
24 | const VAR_ARRAY: &'static [u8; 1] = b"T"; // ERROR Consider removing 'static.
|
||||||
| ^^^^^^^ help: consider removing `'static`
|
| -^^^^^^^-------- help: consider removing `'static`: `&[u8; 1]`
|
||||||
|
|
||||||
|
error: aborting due to 13 previous errors
|
||||||
|
|
||||||
|
@ -33,3 +33,5 @@ error: This else block is redundant.
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
@ -12,3 +12,5 @@ help: assign the `CString` to a variable to extend its lifetime
|
|||||||
7 | CString::new("foo").unwrap().as_ptr();
|
7 | CString::new("foo").unwrap().as_ptr();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
@ -269,3 +269,5 @@ error: the function has a cyclomatic complexity of 8
|
|||||||
|
|
|
|
||||||
= help: you could split it up into multiple smaller functions
|
= help: you could split it up into multiple smaller functions
|
||||||
|
|
||||||
|
error: aborting due to 20 previous errors
|
||||||
|
|
||||||
|
@ -13,3 +13,5 @@ error: the function has a cyclomatic complexity of 3
|
|||||||
= note: `-D cyclomatic-complexity` implied by `-D warnings`
|
= note: `-D cyclomatic-complexity` implied by `-D warnings`
|
||||||
= help: you could split it up into multiple smaller functions
|
= help: you could split it up into multiple smaller functions
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
@ -24,3 +24,5 @@ error: lint unstable_as_mut_slice has been removed: `Vec::as_mut_slice` has been
|
|||||||
10 | #[warn(unstable_as_mut_slice)]
|
10 | #[warn(unstable_as_mut_slice)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
|
@ -106,3 +106,5 @@ note: consider deriving `Clone` or removing `Copy`
|
|||||||
87 | | }
|
87 | | }
|
||||||
| |_^
|
| |_^
|
||||||
|
|
||||||
|
error: aborting due to 7 previous errors
|
||||||
|
|
||||||
|
@ -36,3 +36,5 @@ error: sub-expression diverges
|
|||||||
37 | _ => true || break,
|
37 | _ => true || break,
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 6 previous errors
|
||||||
|
|
||||||
|
@ -47,3 +47,5 @@ error: I see you're using a LinkedList! Perhaps you meant some other data struct
|
|||||||
|
|
|
|
||||||
= help: a VecDeque might work
|
= help: a VecDeque might work
|
||||||
|
|
||||||
|
error: aborting due to 6 previous errors
|
||||||
|
|
||||||
|
@ -180,3 +180,5 @@ error: you should put bare URLs between `<`/`>` or make a proper Markdown link
|
|||||||
168 | /// Not ok: http://www.unicode.org/reports/tr9/#Reordering_Resolved_Levels
|
168 | /// Not ok: http://www.unicode.org/reports/tr9/#Reordering_Resolved_Levels
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 30 previous errors
|
||||||
|
|
||||||
|
@ -6,3 +6,5 @@ error: `--x` could be misinterpreted as pre-decrement by C programmers, is usual
|
|||||||
|
|
|
|
||||||
= note: `-D double-neg` implied by `-D warnings`
|
= note: `-D double-neg` implied by `-D warnings`
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
@ -30,3 +30,5 @@ error: Consider removing unnecessary double parentheses
|
|||||||
32 | (())
|
32 | (())
|
||||||
| ^^^^
|
| ^^^^
|
||||||
|
|
||||||
|
error: aborting due to 5 previous errors
|
||||||
|
|
||||||
|
@ -72,3 +72,5 @@ note: argument has type SomeStruct
|
|||||||
42 | forget(s4);
|
42 | forget(s4);
|
||||||
| ^^
|
| ^^
|
||||||
|
|
||||||
|
error: aborting due to 6 previous errors
|
||||||
|
|
||||||
|
@ -216,3 +216,5 @@ note: argument has type &SomeStruct
|
|||||||
59 | std::mem::forget(&SomeStruct);
|
59 | std::mem::forget(&SomeStruct);
|
||||||
| ^^^^^^^^^^^
|
| ^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 18 previous errors
|
||||||
|
|
||||||
|
@ -6,3 +6,5 @@ error: `darth` already exists, having another argument having almost the same na
|
|||||||
|
|
|
|
||||||
= note: `-D duplicate-underscore-argument` implied by `-D warnings`
|
= note: `-D duplicate-underscore-argument` implied by `-D warnings`
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
50
tests/ui/else_if_without_else.rs
Normal file
50
tests/ui/else_if_without_else.rs
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
#![warn(clippy)]
|
||||||
|
#![warn(else_if_without_else)]
|
||||||
|
|
||||||
|
fn bla1() -> bool { unimplemented!() }
|
||||||
|
fn bla2() -> bool { unimplemented!() }
|
||||||
|
fn bla3() -> bool { unimplemented!() }
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
if bla1() {
|
||||||
|
println!("if");
|
||||||
|
}
|
||||||
|
|
||||||
|
if bla1() {
|
||||||
|
println!("if");
|
||||||
|
} else {
|
||||||
|
println!("else");
|
||||||
|
}
|
||||||
|
|
||||||
|
if bla1() {
|
||||||
|
println!("if");
|
||||||
|
} else if bla2() {
|
||||||
|
println!("else if");
|
||||||
|
} else {
|
||||||
|
println!("else")
|
||||||
|
}
|
||||||
|
|
||||||
|
if bla1() {
|
||||||
|
println!("if");
|
||||||
|
} else if bla2() {
|
||||||
|
println!("else if 1");
|
||||||
|
} else if bla3() {
|
||||||
|
println!("else if 2");
|
||||||
|
} else {
|
||||||
|
println!("else")
|
||||||
|
}
|
||||||
|
|
||||||
|
if bla1() {
|
||||||
|
println!("if");
|
||||||
|
} else if bla2() { //~ ERROR else if without else
|
||||||
|
println!("else if");
|
||||||
|
}
|
||||||
|
|
||||||
|
if bla1() {
|
||||||
|
println!("if");
|
||||||
|
} else if bla2() {
|
||||||
|
println!("else if 1");
|
||||||
|
} else if bla3() { //~ ERROR else if without else
|
||||||
|
println!("else if 2");
|
||||||
|
}
|
||||||
|
}
|
22
tests/ui/else_if_without_else.stderr
Normal file
22
tests/ui/else_if_without_else.stderr
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
error: if expression with an `else if`, but without a final `else`
|
||||||
|
--> $DIR/else_if_without_else.rs:39:12
|
||||||
|
|
|
||||||
|
39 | } else if bla2() { //~ ERROR else if without else
|
||||||
|
| ____________^
|
||||||
|
40 | | println!("else if");
|
||||||
|
41 | | }
|
||||||
|
| |_____^ help: add an `else` block here
|
||||||
|
|
|
||||||
|
= note: `-D else-if-without-else` implied by `-D warnings`
|
||||||
|
|
||||||
|
error: if expression with an `else if`, but without a final `else`
|
||||||
|
--> $DIR/else_if_without_else.rs:47:12
|
||||||
|
|
|
||||||
|
47 | } else if bla3() { //~ ERROR else if without else
|
||||||
|
| ____________^
|
||||||
|
48 | | println!("else if 2");
|
||||||
|
49 | | }
|
||||||
|
| |_____^ help: add an `else` block here
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
@ -11,3 +11,5 @@ help: consider using the uninhabited type `!` or a wrapper around it
|
|||||||
7 | enum Empty {}
|
7 | enum Empty {}
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
@ -42,3 +42,5 @@ error: usage of `contains_key` followed by `insert` on a `BTreeMap`
|
|||||||
37 | if !m.contains_key(&k) { foo(); m.insert(k, v) } else { None };
|
37 | if !m.contains_key(&k) { foo(); m.insert(k, v) } else { None };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `m.entry(k)`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `m.entry(k)`
|
||||||
|
|
||||||
|
error: aborting due to 7 previous errors
|
||||||
|
|
||||||
|
@ -12,3 +12,5 @@ error: don't use glob imports for enum variants
|
|||||||
12 | use self::Enum::*;
|
12 | use self::Enum::*;
|
||||||
| ^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
@ -97,3 +97,5 @@ error: All variants have the same prefix: `With`
|
|||||||
= note: `-D pub-enum-variant-names` implied by `-D warnings`
|
= note: `-D pub-enum-variant-names` implied by `-D warnings`
|
||||||
= help: remove the prefixes and use full paths to the variants instead of glob imports
|
= help: remove the prefixes and use full paths to the variants instead of glob imports
|
||||||
|
|
||||||
|
error: aborting due to 10 previous errors
|
||||||
|
|
||||||
|
@ -48,3 +48,5 @@ error: Clike enum variant discriminant is not portable to 32-bit targets
|
|||||||
37 | A = 0x1_0000_0000,
|
37 | A = 0x1_0000_0000,
|
||||||
| ^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 8 previous errors
|
||||||
|
|
||||||
|
@ -204,3 +204,5 @@ error: taken reference of right operand
|
|||||||
|
|
|
|
||||||
= note: `-D op-ref` implied by `-D warnings`
|
= note: `-D op-ref` implied by `-D warnings`
|
||||||
|
|
||||||
|
error: aborting due to 33 previous errors
|
||||||
|
|
||||||
|
@ -18,3 +18,5 @@ error: this operation will always return zero. This is likely not the intended o
|
|||||||
11 | 0 / x;
|
11 | 0 / x;
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
@ -32,3 +32,5 @@ error: redundant closure found
|
|||||||
18 | let e = Some(1u8).map(|a| generic(a));
|
18 | let e = Some(1u8).map(|a| generic(a));
|
||||||
| ^^^^^^^^^^^^^^ help: remove closure as shown: `generic`
|
| ^^^^^^^^^^^^^^ help: remove closure as shown: `generic`
|
||||||
|
|
||||||
|
error: aborting due to 5 previous errors
|
||||||
|
|
||||||
|
@ -47,3 +47,5 @@ note: whether read occurs before this write depends on evaluation order
|
|||||||
21 | x += { x = 20; 2 };
|
21 | x += { x = 20; 2 };
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
|
@ -36,3 +36,5 @@ error: use of `stderr().write_fmt(...).unwrap()`. Consider using `eprint!` inste
|
|||||||
21 | std::io::stderr().write_fmt(format_args!("test")).unwrap();
|
21 | std::io::stderr().write_fmt(format_args!("test")).unwrap();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 6 previous errors
|
||||||
|
|
||||||
|
@ -89,3 +89,5 @@ note: potential failure(s)
|
|||||||
| ^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^
|
||||||
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
|
||||||
|
|
||||||
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
|
@ -36,3 +36,5 @@ error: called `filter_map(p).map(q)` on an `Iterator`. This is more succinctly e
|
|||||||
25 | | .map(|x| x.checked_mul(2))
|
25 | | .map(|x| x.checked_mul(2))
|
||||||
| |__________________________________________________________^
|
| |__________________________________________________________^
|
||||||
|
|
||||||
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
|
@ -95,3 +95,5 @@ note: std::f32::EPSILON and std::f64::EPSILON are available.
|
|||||||
57 | twice(x) != twice(ONE as f64);
|
57 | twice(x) != twice(ONE as f64);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 8 previous errors
|
||||||
|
|
||||||
|
@ -83,3 +83,5 @@ note: std::f32::EPSILON and std::f64::EPSILON are available.
|
|||||||
25 | v != ONE;
|
25 | v != ONE;
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 7 previous errors
|
||||||
|
|
||||||
|
@ -565,3 +565,5 @@ error: it looks like you're manually copying between slices
|
|||||||
549 | | }
|
549 | | }
|
||||||
| |_____^ help: try replacing the loop by: `dst[..src.len()].clone_from_slice(&src[..])`
|
| |_____^ help: try replacing the loop by: `dst[..src.len()].clone_from_slice(&src[..])`
|
||||||
|
|
||||||
|
error: aborting due to 59 previous errors
|
||||||
|
|
||||||
|
@ -6,3 +6,5 @@ error: useless use of `format!`
|
|||||||
|
|
|
|
||||||
= note: `-D useless-format` implied by `-D warnings`
|
= note: `-D useless-format` implied by `-D warnings`
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
@ -86,3 +86,5 @@ error: possibly missing a comma here
|
|||||||
|
|
|
|
||||||
= note: to remove this lint, add a comma or write the expr in a single line
|
= note: to remove this lint, add a comma or write the expr in a single line
|
||||||
|
|
||||||
|
error: aborting due to 10 previous errors
|
||||||
|
|
||||||
|
@ -75,3 +75,5 @@ error: this public function dereferences a raw pointer but is not marked `unsafe
|
|||||||
63 | unsafe { std::ptr::read(p) };
|
63 | unsafe { std::ptr::read(p) };
|
||||||
| ^
|
| ^
|
||||||
|
|
||||||
|
error: aborting due to 12 previous errors
|
||||||
|
|
||||||
|
@ -60,3 +60,5 @@ error: called `.get_mut().unwrap()` on a VecDeque. Using `[]` is more clear and
|
|||||||
40 | *some_vecdeque.get_mut(0).unwrap() = 1;
|
40 | *some_vecdeque.get_mut(0).unwrap() = 1;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&mut some_vecdeque[0]`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&mut some_vecdeque[0]`
|
||||||
|
|
||||||
|
error: aborting due to 10 previous errors
|
||||||
|
|
||||||
|
@ -40,3 +40,5 @@ error: identical conversion
|
|||||||
39 | let _ = String::from("foo".to_string());
|
39 | let _ = String::from("foo".to_string());
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `String::from()`: `"foo".to_string()`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `String::from()`: `"foo".to_string()`
|
||||||
|
|
||||||
|
error: aborting due to 6 previous errors
|
||||||
|
|
||||||
|
@ -48,3 +48,5 @@ error: the operation is ineffective. Consider reducing it to `u`
|
|||||||
32 | u & 255;
|
32 | u & 255;
|
||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 8 previous errors
|
||||||
|
|
||||||
|
@ -24,3 +24,5 @@ error: redundant pattern matching, consider using `is_some()`
|
|||||||
17 | if let Some(_) = Some(42) {
|
17 | if let Some(_) = Some(42) {
|
||||||
| -------^^^^^^^----------- help: try this: `if Some(42).is_some()`
|
| -------^^^^^^^----------- help: try this: `if Some(42).is_some()`
|
||||||
|
|
||||||
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
|
@ -23,3 +23,5 @@ error: Unnecessary `!=` operation
|
|||||||
|
|
|
|
||||||
= help: change to `==` and swap the blocks of the if/else
|
= help: change to `==` and swap the blocks of the if/else
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
@ -133,3 +133,5 @@ help: consider adding a type parameter
|
|||||||
78 | pub fn $name<S: ::std::hash::BuildHasher>(_map: &mut HashMap<i32, i32>, _set: &mut HashSet<i32, S>) {
|
78 | pub fn $name<S: ::std::hash::BuildHasher>(_map: &mut HashMap<i32, i32>, _set: &mut HashSet<i32, S>) {
|
||||||
|
|
|
|
||||||
|
|
||||||
|
error: aborting due to 10 previous errors
|
||||||
|
|
||||||
|
@ -39,3 +39,5 @@ error: digits grouped inconsistently by underscores
|
|||||||
|
|
|
|
||||||
= help: consider: 1.234_567_8_f32
|
= help: consider: 1.234_567_8_f32
|
||||||
|
|
||||||
|
error: aborting due to 5 previous errors
|
||||||
|
|
||||||
|
@ -96,3 +96,5 @@ error: possible infinite iteration detected
|
|||||||
30 | (0..).all(|x| x == 24); // maybe infinite iter
|
30 | (0..).all(|x| x == 24); // maybe infinite iter
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 14 previous errors
|
||||||
|
|
||||||
|
23
tests/ui/inline_fn_without_body.rs
Normal file
23
tests/ui/inline_fn_without_body.rs
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#![warn(inline_fn_without_body)]
|
||||||
|
#![allow(inline_always)]
|
||||||
|
|
||||||
|
trait Foo {
|
||||||
|
#[inline]
|
||||||
|
fn default_inline();
|
||||||
|
|
||||||
|
#[inline(always)]fn always_inline();
|
||||||
|
|
||||||
|
#[inline(never)]
|
||||||
|
|
||||||
|
fn never_inline();
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn has_body() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user