Merge branch 'master' of github.com:rust-lang-nursery/rust-clippy

This commit is contained in:
cgm616 2017-11-02 22:57:07 -05:00
commit ee289c9f88
23 changed files with 484 additions and 70 deletions

View File

@ -1,6 +1,13 @@
# Change Log
All notable changes to this project will be documented in this file.
## 0.0.168
* Rustup to *rustc 1.23.0-nightly (f0fe716db 2017-10-30)*
## 0.0.167
* Rustup to *rustc 1.23.0-nightly (90ef3372e 2017-10-29)*
* New lints: [`const_static_lifetime`], [`erasing_op`], [`fallible_impl_from`], [`println_empty_string`], [`useless_asref`]
## 0.0.166
* Rustup to *rustc 1.22.0-nightly (b7960878b 2017-10-18)*
* New lints: [`explicit_write`], [`identity_conversion`], [`implicit_hasher`], [`invalid_ref`], [`option_map_or_none`], [`range_minus_one`], [`range_plus_one`], [`transmute_int_to_bool`], [`transmute_int_to_char`], [`transmute_int_to_float`]
@ -68,7 +75,7 @@ All notable changes to this project will be documented in this file.
## 0.0.148
* Update to *rustc 1.21.0-nightly (37c7d0ebb 2017-07-31)*
* New lints: [`unreadable_literal`], [`inconsisten_digit_grouping`], [`large_digit_groups`]
* New lints: [`unreadable_literal`], [`inconsistent_digit_grouping`], [`large_digit_groups`]
## 0.0.147
* Update to *rustc 1.21.0-nightly (aac223f4f 2017-07-30)*
@ -486,6 +493,7 @@ All notable changes to this project will be documented in this file.
[`cmp_null`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#cmp_null
[`cmp_owned`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#cmp_owned
[`collapsible_if`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#collapsible_if
[`const_static_lifetime`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#const_static_lifetime
[`crosspointer_transmute`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#crosspointer_transmute
[`cyclomatic_complexity`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#cyclomatic_complexity
[`deprecated_semver`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#deprecated_semver
@ -504,6 +512,7 @@ All notable changes to this project will be documented in this file.
[`enum_glob_use`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#enum_glob_use
[`enum_variant_names`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#enum_variant_names
[`eq_op`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#eq_op
[`erasing_op`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#erasing_op
[`eval_order_dependence`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#eval_order_dependence
[`expl_impl_clone_on_copy`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#expl_impl_clone_on_copy
[`explicit_counter_loop`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#explicit_counter_loop
@ -511,6 +520,7 @@ All notable changes to this project will be documented in this file.
[`explicit_iter_loop`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#explicit_iter_loop
[`explicit_write`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#explicit_write
[`extend_from_slice`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#extend_from_slice
[`fallible_impl_from`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#fallible_impl_from
[`filter_map`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#filter_map
[`filter_next`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#filter_next
[`float_arithmetic`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#float_arithmetic
@ -611,6 +621,7 @@ All notable changes to this project will be documented in this file.
[`precedence`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#precedence
[`print_stdout`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#print_stdout
[`print_with_newline`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#print_with_newline
[`println_empty_string`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#println_empty_string
[`ptr_arg`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#ptr_arg
[`pub_enum_variant_names`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#pub_enum_variant_names
[`range_minus_one`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#range_minus_one
@ -673,6 +684,7 @@ All notable changes to this project will be documented in this file.
[`use_debug`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#use_debug
[`use_self`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#use_self
[`used_underscore_binding`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#used_underscore_binding
[`useless_asref`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#useless_asref
[`useless_attribute`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#useless_attribute
[`useless_format`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#useless_format
[`useless_let_if_seq`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#useless_let_if_seq

View File

@ -1,6 +1,6 @@
[package]
name = "clippy"
version = "0.0.166"
version = "0.0.168"
authors = [
"Manish Goregaokar <manishsmail@gmail.com>",
"Andre Bogus <bogusandre@gmail.com>",
@ -37,7 +37,7 @@ path = "src/driver.rs"
[dependencies]
# begin automatic update
clippy_lints = { version = "0.0.166", path = "clippy_lints" }
clippy_lints = { version = "0.0.168", path = "clippy_lints" }
# end automatic update
cargo_metadata = "0.2"

View File

@ -1,7 +1,7 @@
[package]
name = "clippy_lints"
# begin automatic update
version = "0.0.166"
version = "0.0.168"
# end automatic update
authors = [
"Manish Goregaokar <manishsmail@gmail.com>",

View File

@ -37,7 +37,7 @@ impl StaticConst {
// Recursively visit types
fn visit_type(&mut self, ty: &Ty, cx: &EarlyContext) {
match ty.node {
// Be carefull of nested structures (arrays and tuples)
// Be careful of nested structures (arrays and tuples)
TyKind::Array(ref ty, _) => {
self.visit_type(&*ty, cx);
},

View File

@ -224,7 +224,7 @@ fn check_doc<'a, Events: Iterator<Item = (usize, pulldown_cmark::Event<'a>)>>(
let (begin, span) = spans[index];
// Adjust for the begining of the current `Event`
// Adjust for the beginning of the current `Event`
let span = span.with_lo(span.lo() + BytePos::from_usize(offset - begin));
check_text(cx, valid_idents, &text, span);

View File

@ -9,6 +9,7 @@
#![feature(stmt_expr_attributes)]
#![feature(conservative_impl_trait)]
#![feature(inclusive_range_syntax, range_contains)]
#![feature(macro_vis_matcher)]
#![allow(unknown_lints, indexing_slicing, shadow_reuse, missing_docs_in_private_items)]
#![recursion_limit="256"]
@ -93,12 +94,13 @@ pub mod entry;
pub mod enum_clike;
pub mod enum_glob_use;
pub mod enum_variants;
pub mod erasing_op;
pub mod eq_op;
pub mod erasing_op;
pub mod escape;
pub mod eta_reduction;
pub mod eval_order_dependence;
pub mod explicit_write;
pub mod fallible_impl_from;
pub mod format;
pub mod formatting;
pub mod functions;
@ -106,7 +108,6 @@ pub mod identity_conversion;
pub mod identity_op;
pub mod if_let_redundant_pattern_matching;
pub mod if_not_else;
pub mod fallible_impl_from;
pub mod infinite_iter;
pub mod int_plus_one;
pub mod invalid_ref;
@ -209,7 +210,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) {
let mut store = reg.sess.lint_store.borrow_mut();
store.register_removed(
"should_assert_eq",
"`assert!()` will be more flexible with RFC 2011"
"`assert!()` will be more flexible with RFC 2011",
);
store.register_removed(
"extend_from_slice",
@ -360,11 +361,11 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) {
reg.register_lint_group("clippy_pedantic", vec![
booleans::NONMINIMAL_BOOL,
const_static_lifetime::CONST_STATIC_LIFETIME,
empty_enum::EMPTY_ENUM,
enum_glob_use::ENUM_GLOB_USE,
enum_variants::PUB_ENUM_VARIANT_NAMES,
enum_variants::STUTTER,
fallible_impl_from::FALLIBLE_IMPL_FROM,
if_not_else::IF_NOT_ELSE,
infinite_iter::MAYBE_INFINITE_ITER,
int_plus_one::INT_PLUS_ONE,
@ -374,6 +375,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) {
methods::FILTER_MAP,
methods::OPTION_MAP_UNWRAP_OR,
methods::OPTION_MAP_UNWRAP_OR_ELSE,
methods::RESULT_MAP_UNWRAP_OR_ELSE,
methods::OPTION_UNWRAP_USED,
methods::RESULT_UNWRAP_USED,
methods::WRONG_PUB_SELF_CONVENTION,
@ -423,6 +425,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) {
booleans::LOGIC_BUG,
bytecount::NAIVE_BYTECOUNT,
collapsible_if::COLLAPSIBLE_IF,
const_static_lifetime::CONST_STATIC_LIFETIME,
copies::IF_SAME_THEN_ELSE,
copies::IFS_SAME_COND,
copies::MATCH_SAME_ARMS,
@ -441,6 +444,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) {
enum_variants::MODULE_INCEPTION,
eq_op::EQ_OP,
eq_op::OP_REF,
erasing_op::ERASING_OP,
escape::BOXED_LOCAL,
eta_reduction::REDUNDANT_CLOSURE,
eval_order_dependence::DIVERGING_SUB_EXPRESSION,
@ -455,7 +459,6 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) {
identity_conversion::IDENTITY_CONVERSION,
identity_op::IDENTITY_OP,
if_let_redundant_pattern_matching::IF_LET_REDUNDANT_PATTERN_MATCHING,
fallible_impl_from::FALLIBLE_IMPL_FROM,
infinite_iter::INFINITE_ITER,
invalid_ref::INVALID_REF,
is_unit_expr::UNIT_EXPR,
@ -509,6 +512,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) {
methods::SINGLE_CHAR_PATTERN,
methods::STRING_EXTEND_CHARS,
methods::TEMPORARY_CSTRING_AS_PTR,
methods::USELESS_ASREF,
methods::WRONG_SELF_CONVENTION,
minmax::MIN_MAX,
misc::CMP_NAN,

View File

@ -66,7 +66,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LifetimePass {
fn check_impl_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx ImplItem) {
if let ImplItemKind::Method(ref sig, id) = item.node {
check_fn_inner(cx, &sig.decl, Some(id), &sig.generics, item.span);
check_fn_inner(cx, &sig.decl, Some(id), &item.generics, item.span);
}
}
@ -76,7 +76,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LifetimePass {
TraitMethod::Required(_) => None,
TraitMethod::Provided(id) => Some(id),
};
check_fn_inner(cx, &sig.decl, body, &sig.generics, item.span);
check_fn_inner(cx, &sig.decl, body, &item.generics, item.span);
}
}
}

View File

@ -193,6 +193,24 @@ declare_lint! {
`map_or_else(g, f)`"
}
/// **What it does:** Checks for usage of `result.map(_).unwrap_or_else(_)`.
///
/// **Why is this bad?** Readability, this can be written more concisely as
/// `result.ok().map_or_else(_, _)`.
///
/// **Known problems:** None.
///
/// **Example:**
/// ```rust
/// x.map(|a| a + 1).unwrap_or_else(some_function)
/// ```
declare_lint! {
pub RESULT_MAP_UNWRAP_OR_ELSE,
Allow,
"using `Result.map(f).unwrap_or_else(g)`, which is more succinctly expressed as \
`.ok().map_or_else(g, f)`"
}
/// **What it does:** Checks for usage of `_.map_or(None, _)`.
///
/// **Why is this bad?** Readability, this can be written more concisely as
@ -615,6 +633,7 @@ impl LintPass for Pass {
OK_EXPECT,
OPTION_MAP_UNWRAP_OR,
OPTION_MAP_UNWRAP_OR_ELSE,
RESULT_MAP_UNWRAP_OR_ELSE,
OPTION_MAP_OR_NONE,
OR_FUN_CALL,
CHARS_NEXT_CMP,
@ -748,7 +767,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
if name == method_name &&
sig.decl.inputs.len() == n_args &&
out_type.matches(&sig.decl.output) &&
self_kind.matches(first_arg_ty, first_arg, self_ty, false, &sig.generics) {
self_kind.matches(first_arg_ty, first_arg, self_ty, false, &implitem.generics) {
span_lint(cx, SHOULD_IMPLEMENT_TRAIT, implitem.span, &format!(
"defining a method called `{}` on this type; consider implementing \
the `{}` trait or choosing a less ambiguous name", name, trait_name));
@ -763,7 +782,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
for &(ref conv, self_kinds) in &CONVENTIONS {
if_chain! {
if conv.check(&name.as_str());
if !self_kinds.iter().any(|k| k.matches(first_arg_ty, first_arg, self_ty, is_copy, &sig.generics));
if !self_kinds.iter().any(|k| k.matches(first_arg_ty, first_arg, self_ty, is_copy, &implitem.generics));
then {
let lint = if item.vis == hir::Visibility::Public {
WRONG_PUB_SELF_CONVENTION
@ -1244,13 +1263,25 @@ fn lint_map_unwrap_or(cx: &LateContext, expr: &hir::Expr, map_args: &[hir::Expr]
}
}
/// lint use of `map().unwrap_or_else()` for `Option`s
fn lint_map_unwrap_or_else<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr, map_args: &'tcx [hir::Expr], unwrap_args: &'tcx [hir::Expr]) {
/// lint use of `map().unwrap_or_else()` for `Option`s and `Result`s
fn lint_map_unwrap_or_else<'a, 'tcx>(
cx: &LateContext<'a, 'tcx>,
expr: &'tcx hir::Expr,
map_args: &'tcx [hir::Expr],
unwrap_args: &'tcx [hir::Expr],
) {
// lint if the caller of `map()` is an `Option`
if match_type(cx, cx.tables.expr_ty(&map_args[0]), &paths::OPTION) {
let is_option = match_type(cx, cx.tables.expr_ty(&map_args[0]), &paths::OPTION);
let is_result = match_type(cx, cx.tables.expr_ty(&map_args[0]), &paths::RESULT);
if is_option || is_result {
// lint message
let msg = "called `map(f).unwrap_or_else(g)` on an Option value. This can be done more directly by calling \
`map_or_else(g, f)` instead";
let msg = if is_option {
"called `map(f).unwrap_or_else(g)` on an Option value. This can be done more directly by calling \
`map_or_else(g, f)` instead"
} else {
"called `map(f).unwrap_or_else(g)` on a Result value. This can be done more directly by calling \
`ok().map_or_else(g, f)` instead"
};
// get snippets for args to map() and unwrap_or_else()
let map_snippet = snippet(cx, map_args[1].span, "..");
let unwrap_snippet = snippet(cx, unwrap_args[1].span, "..");
@ -1261,18 +1292,32 @@ fn lint_map_unwrap_or_else<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx hir
if same_span && !multiline {
span_note_and_lint(
cx,
OPTION_MAP_UNWRAP_OR_ELSE,
if is_option {
OPTION_MAP_UNWRAP_OR_ELSE
} else {
RESULT_MAP_UNWRAP_OR_ELSE
},
expr.span,
msg,
expr.span,
&format!(
"replace `map({0}).unwrap_or_else({1})` with `map_or_else({1}, {0})`",
"replace `map({0}).unwrap_or_else({1})` with `{2}map_or_else({1}, {0})`",
map_snippet,
unwrap_snippet
unwrap_snippet,
if is_result { "ok()." } else { "" }
),
);
} else if same_span && multiline {
span_lint(cx, OPTION_MAP_UNWRAP_OR_ELSE, expr.span, msg);
span_lint(
cx,
if is_option {
OPTION_MAP_UNWRAP_OR_ELSE
} else {
RESULT_MAP_UNWRAP_OR_ELSE
},
expr.span,
msg,
);
};
}
}

View File

@ -108,11 +108,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NewWithoutDefault {
// can't be implemented by default
return;
}
if !sig.generics.ty_params.is_empty() {
// when the result of `new()` depends on a type parameter we should not require
// an
// impl of `Default`
return;
if !cx.generics.expect("method must have generics").ty_params.is_empty() {
// when the result of `new()` depends on a type parameter we should not require
// an
// impl of `Default`
return;
}
if decl.inputs.is_empty() && name == "new" && cx.access_levels.is_reachable(id) {
let self_ty = cx.tcx

View File

@ -80,15 +80,24 @@ declare_lint! {
/// **What it does:** Checks for transmutes from an integer to a `char`.
///
/// **Why is this bad?** Not every integer is a unicode scalar value.
/// **Why is this bad?** Not every integer is a Unicode scalar value.
///
/// **Known problems:** None.
/// **Known problems:**
/// - [`from_u32`] which this lint suggests using is slower than `transmute`
/// as it needs to validate the input.
/// If you are certain that the input is always a valid Unicode scalar value,
/// use [`from_u32_unchecked`] which is as fast as `transmute`
/// but has a semantically meaningful name.
/// - You might want to handle `None` returned from [`from_u32`] instead of calling `unwrap`.
///
/// [`from_u32`]: https://doc.rust-lang.org/std/char/fn.from_u32.html
/// [`from_u32_unchecked`]: https://doc.rust-lang.org/std/char/fn.from_u32_unchecked.html
///
/// **Example:**
/// ```rust
/// let _: char = std::mem::transmute(x); // where x: u32
/// // should be:
/// let _: Option<char> = std::char::from_u32(x);
/// let _ = std::char::from_u32(x).unwrap();
/// ```
declare_lint! {
pub TRANSMUTE_INT_TO_CHAR,
@ -96,6 +105,33 @@ declare_lint! {
"transmutes from an integer to a `char`"
}
/// **What it does:** Checks for transmutes from a `&[u8]` to a `&str`.
///
/// **Why is this bad?** Not every byte slice is a valid UTF-8 string.
///
/// **Known problems:**
/// - [`from_utf8`] which this lint suggests using is slower than `transmute`
/// as it needs to validate the input.
/// If you are certain that the input is always a valid UTF-8,
/// use [`from_utf8_unchecked`] which is as fast as `transmute`
/// but has a semantically meaningful name.
/// - You might want to handle errors returned from [`from_utf8`] instead of calling `unwrap`.
///
/// [`from_utf8`]: https://doc.rust-lang.org/std/str/fn.from_utf8.html
/// [`from_utf8_unchecked`]: https://doc.rust-lang.org/std/str/fn.from_utf8_unchecked.html
///
/// **Example:**
/// ```rust
/// let _: &str = std::mem::transmute(b); // where b: &[u8]
/// // should be:
/// let _ = std::str::from_utf8(b).unwrap();
/// ```
declare_lint! {
pub TRANSMUTE_BYTES_TO_STR,
Warn,
"transmutes from a `&[u8]` to a `&str`"
}
/// **What it does:** Checks for transmutes from an integer to a `bool`.
///
/// **Why is this bad?** This might result in an invalid in-memory representation of a `bool`.
@ -142,6 +178,7 @@ impl LintPass for Transmute {
USELESS_TRANSMUTE,
WRONG_TRANSMUTE,
TRANSMUTE_INT_TO_CHAR,
TRANSMUTE_BYTES_TO_STR,
TRANSMUTE_INT_TO_BOOL,
TRANSMUTE_INT_TO_FLOAT
)
@ -254,9 +291,41 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Transmute {
} else {
arg
};
db.span_suggestion(e.span, "consider using", format!("std::char::from_u32({})", arg.to_string()));
db.span_suggestion(e.span, "consider using", format!("std::char::from_u32({}).unwrap()", arg.to_string()));
}
),
(&ty::TyRef(_, ref ref_from), &ty::TyRef(_, ref ref_to)) => {
if_chain! {
if let (&ty::TySlice(slice_ty), &ty::TyStr) = (&ref_from.ty.sty, &ref_to.ty.sty);
if let ty::TyUint(ast::UintTy::U8) = slice_ty.sty;
if ref_from.mutbl == ref_to.mutbl;
then {
let postfix = if ref_from.mutbl == Mutability::MutMutable {
"_mut"
} else {
""
};
span_lint_and_then(
cx,
TRANSMUTE_BYTES_TO_STR,
e.span,
&format!("transmute from a `{}` to a `{}`", from_ty, to_ty),
|db| {
db.span_suggestion(
e.span,
"consider using",
format!(
"std::str::from_utf8{}({}).unwrap()",
postfix,
snippet(cx, args[0].span, ".."),
),
);
}
)
}
}
},
(&ty::TyInt(ast::IntTy::I8), &ty::TyBool) |
(&ty::TyUint(ast::UintTy::U8), &ty::TyBool) => span_lint_and_then(
cx,

View File

@ -161,16 +161,13 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LintWithoutLintPass {
fn is_lint_ref_type(ty: &Ty) -> bool {
if let TyRptr(
ref lt,
_,
MutTy {
ty: ref inner,
mutbl: MutImmutable,
},
) = ty.node
{
if lt.is_elided() {
return false;
}
if let TyPath(ref path) = inner.node {
return match_qpath(path, &paths::LINT);
}

View File

@ -924,6 +924,7 @@ pub fn opt_def_id(def: Def) -> Option<DefId> {
Def::TyAlias(id) |
Def::AssociatedTy(id) |
Def::TyParam(id) |
Def::TyForeign(id) |
Def::Struct(id) |
Def::StructCtor(id, ..) |
Def::Union(id) |

View File

@ -41,8 +41,8 @@ pub const IO_READ: [&str; 3] = ["std", "io", "Read"];
pub const IO_WRITE: [&str; 3] = ["std", "io", "Write"];
pub const ITERATOR: [&str; 4] = ["core", "iter", "iterator", "Iterator"];
pub const LINKED_LIST: [&str; 3] = ["alloc", "linked_list", "LinkedList"];
pub const LINT: [&str; 3] = ["rustc", "lint", "Lint"];
pub const LINT_ARRAY: [&str; 3] = ["rustc", "lint", "LintArray"];
pub const LINT: [&str; 2] = ["lint", "Lint"];
pub const LINT_ARRAY: [&str; 2] = ["lint", "LintArray"];
pub const MEM_FORGET: [&str; 3] = ["core", "mem", "forget"];
pub const MEM_UNINIT: [&str; 3] = ["core", "mem", "uninitialized"];
pub const MEM_ZEROED: [&str; 3] = ["core", "mem", "zeroed"];

Binary file not shown.

View File

@ -82,7 +82,7 @@ impl<'a> CompilerCalls<'a> for ClippyCompilerCalls {
.as_ref()
.expect(
"at this compilation stage \
the krate must be parsed",
the crate must be parsed",
)
.span,
);
@ -129,7 +129,7 @@ fn show_version() {
pub fn main() {
use std::env;
if env::var("CLIPPY_DOGFOOD").map(|_| true).unwrap_or(false) {
if env::var("CLIPPY_DOGFOOD").is_ok() {
panic!("yummy");
}
@ -161,8 +161,11 @@ pub fn main() {
rustc_driver::in_rustc_thread(|| {
// Setting RUSTC_WRAPPER causes Cargo to pass 'rustc' as the first argument.
// We're invoking the compiler programatically, so we ignore this/
// We're invoking the compiler programmatically, so we ignore this/
let mut orig_args: Vec<String> = env::args().collect();
if orig_args.len() <= 1 {
std::process::exit(1);
}
if orig_args[1] == "rustc" {
// we still want to be able to invoke it normally though
orig_args.remove(1);

View File

@ -1,6 +1,7 @@
// error-pattern:cargo-clippy
#![feature(plugin_registrar)]
#![feature(rustc_private)]
#![feature(macro_vis_matcher)]
#![allow(unknown_lints)]
#![allow(missing_docs_in_private_items)]

View File

@ -51,7 +51,7 @@ fn show_version() {
pub fn main() {
use std::env;
if env::var("CLIPPY_DOGFOOD").map(|_| true).unwrap_or(false) {
if env::var("CLIPPY_DOGFOOD").is_ok() {
panic!("yummy");
}

View File

@ -1,6 +1,6 @@
#![feature(rustc_private)]
#![feature(macro_vis_matcher)]
#![warn(lint_without_lint_pass)]

View File

@ -152,6 +152,29 @@ fn option_methods() {
);
}
/// Checks implementation of the following lints:
/// * `RESULT_MAP_UNWRAP_OR_ELSE`
fn result_methods() {
let res: Result<i32, ()> = Ok(1);
// Check RESULT_MAP_UNWRAP_OR_ELSE
// single line case
let _ = res.map(|x| x + 1)
.unwrap_or_else(|e| 0); // should lint even though this call is on a separate line
// multi line cases
let _ = res.map(|x| {
x + 1
}
).unwrap_or_else(|e| 0);
let _ = res.map(|x| x + 1)
.unwrap_or_else(|e|
0
);
// macro case
let _ = opt_map!(res, |x| x + 1).unwrap_or_else(|e| 0); // should not lint
}
/// Struct to generate false positives for things with .iter()
#[derive(Copy, Clone)]
struct HasIter;

View File

@ -226,7 +226,40 @@ help: try using and_then instead
151 | });
|
error: called `map(f).unwrap_or_else(g)` on a Result value. This can be done more directly by calling `ok().map_or_else(g, f)` instead
--> $DIR/methods.rs:159:13
|
159 | let _ = res.map(|x| x + 1)
| _____________^
160 | |
161 | | .unwrap_or_else(|e| 0); // should lint even though this call is on a separate line
| |_____________________________________^
|
= note: `-D result-map-unwrap-or-else` implied by `-D warnings`
= note: replace `map(|x| x + 1).unwrap_or_else(|e| 0)` with `ok().map_or_else(|e| 0, |x| x + 1)`
error: called `map(f).unwrap_or_else(g)` on a Result value. This can be done more directly by calling `ok().map_or_else(g, f)` instead
--> $DIR/methods.rs:163:13
|
163 | let _ = res.map(|x| {
| _____________^
164 | | x + 1
165 | | }
166 | | ).unwrap_or_else(|e| 0);
| |_____________________________________^
error: called `map(f).unwrap_or_else(g)` on a Result value. This can be done more directly by calling `ok().map_or_else(g, f)` instead
--> $DIR/methods.rs:167:13
|
167 | let _ = res.map(|x| x + 1)
| _____________^
168 | | .unwrap_or_else(|e|
169 | | 0
170 | | );
| |_________________^
error: unnecessary structure name repetition
<<<<<<< HEAD
--> $DIR/methods.rs:176:24
|
176 | fn filter(self) -> IteratorFalsePositives {
@ -248,12 +281,36 @@ error: called `filter(p).next()` on an `Iterator`. This is more succinctly expre
--> $DIR/methods.rs:210:13
|
210 | let _ = v.iter().filter(|&x| *x < 0).next();
=======
--> $DIR/methods.rs:196:24
|
196 | fn filter(self) -> IteratorFalsePositives {
| ^^^^^^^^^^^^^^^^^^^^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
--> $DIR/methods.rs:200:22
|
200 | fn next(self) -> IteratorFalsePositives {
| ^^^^^^^^^^^^^^^^^^^^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
--> $DIR/methods.rs:220:32
|
220 | fn skip(self, _: usize) -> IteratorFalsePositives {
| ^^^^^^^^^^^^^^^^^^^^^^ help: use the applicable keyword: `Self`
error: called `filter(p).next()` on an `Iterator`. This is more succinctly expressed by calling `.find(p)` instead.
--> $DIR/methods.rs:230:13
|
230 | let _ = v.iter().filter(|&x| *x < 0).next();
>>>>>>> 47be6927239cc8dabeb59764581fc4ac73327f22
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D filter-next` implied by `-D warnings`
= note: replace `filter(|&x| *x < 0).next()` with `find(|&x| *x < 0)`
error: called `filter(p).next()` on an `Iterator`. This is more succinctly expressed by calling `.find(p)` instead.
<<<<<<< HEAD
--> $DIR/methods.rs:213:13
|
213 | let _ = v.iter().filter(|&x| {
@ -267,12 +324,28 @@ error: called `is_some()` after searching an `Iterator` with find. This is more
--> $DIR/methods.rs:228:13
|
228 | let _ = v.iter().find(|&x| *x < 0).is_some();
=======
--> $DIR/methods.rs:233:13
|
233 | let _ = v.iter().filter(|&x| {
| _____________^
234 | | *x < 0
235 | | }
236 | | ).next();
| |___________________________^
error: called `is_some()` after searching an `Iterator` with find. This is more succinctly expressed by calling `any()`.
--> $DIR/methods.rs:248:13
|
248 | let _ = v.iter().find(|&x| *x < 0).is_some();
>>>>>>> 47be6927239cc8dabeb59764581fc4ac73327f22
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D search-is-some` implied by `-D warnings`
= note: replace `find(|&x| *x < 0).is_some()` with `any(|&x| *x < 0)`
error: called `is_some()` after searching an `Iterator` with find. This is more succinctly expressed by calling `any()`.
<<<<<<< HEAD
--> $DIR/methods.rs:231:13
|
231 | let _ = v.iter().find(|&x| {
@ -286,11 +359,27 @@ error: called `is_some()` after searching an `Iterator` with position. This is m
--> $DIR/methods.rs:237:13
|
237 | let _ = v.iter().position(|&x| x < 0).is_some();
=======
--> $DIR/methods.rs:251:13
|
251 | let _ = v.iter().find(|&x| {
| _____________^
252 | | *x < 0
253 | | }
254 | | ).is_some();
| |______________________________^
error: called `is_some()` after searching an `Iterator` with position. This is more succinctly expressed by calling `any()`.
--> $DIR/methods.rs:257:13
|
257 | let _ = v.iter().position(|&x| x < 0).is_some();
>>>>>>> 47be6927239cc8dabeb59764581fc4ac73327f22
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: replace `position(|&x| x < 0).is_some()` with `any(|&x| x < 0)`
error: called `is_some()` after searching an `Iterator` with position. This is more succinctly expressed by calling `any()`.
<<<<<<< HEAD
--> $DIR/methods.rs:240:13
|
240 | let _ = v.iter().position(|&x| {
@ -304,11 +393,27 @@ error: called `is_some()` after searching an `Iterator` with rposition. This is
--> $DIR/methods.rs:246:13
|
246 | let _ = v.iter().rposition(|&x| x < 0).is_some();
=======
--> $DIR/methods.rs:260:13
|
260 | let _ = v.iter().position(|&x| {
| _____________^
261 | | x < 0
262 | | }
263 | | ).is_some();
| |______________________________^
error: called `is_some()` after searching an `Iterator` with rposition. This is more succinctly expressed by calling `any()`.
--> $DIR/methods.rs:266:13
|
266 | let _ = v.iter().rposition(|&x| x < 0).is_some();
>>>>>>> 47be6927239cc8dabeb59764581fc4ac73327f22
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: replace `rposition(|&x| x < 0).is_some()` with `any(|&x| x < 0)`
error: called `is_some()` after searching an `Iterator` with rposition. This is more succinctly expressed by calling `any()`.
<<<<<<< HEAD
--> $DIR/methods.rs:249:13
|
249 | let _ = v.iter().rposition(|&x| {
@ -328,11 +433,33 @@ error: use of `unwrap_or` followed by a function call
--> $DIR/methods.rs:284:5
|
284 | with_constructor.unwrap_or(make());
=======
--> $DIR/methods.rs:269:13
|
269 | let _ = v.iter().rposition(|&x| {
| _____________^
270 | | x < 0
271 | | }
272 | | ).is_some();
| |______________________________^
error: unnecessary structure name repetition
--> $DIR/methods.rs:286:21
|
286 | fn new() -> Foo { Foo }
| ^^^ help: use the applicable keyword: `Self`
error: use of `unwrap_or` followed by a function call
--> $DIR/methods.rs:304:5
|
304 | with_constructor.unwrap_or(make());
>>>>>>> 47be6927239cc8dabeb59764581fc4ac73327f22
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `with_constructor.unwrap_or_else(make)`
|
= note: `-D or-fun-call` implied by `-D warnings`
error: use of `unwrap_or` followed by a call to `new`
<<<<<<< HEAD
--> $DIR/methods.rs:287:5
|
287 | with_new.unwrap_or(Vec::new());
@ -402,11 +529,83 @@ error: called `.iter().nth()` on a Vec. Calling `.get()` is both faster and more
--> $DIR/methods.rs:330:23
|
330 | let bad_vec = some_vec.iter().nth(3);
=======
--> $DIR/methods.rs:307:5
|
307 | 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/methods.rs:310:5
|
310 | with_const_args.unwrap_or(Vec::with_capacity(12));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `with_const_args.unwrap_or_else(|| Vec::with_capacity(12))`
error: use of `unwrap_or` followed by a function call
--> $DIR/methods.rs:313:5
|
313 | with_err.unwrap_or(make());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `with_err.unwrap_or_else(|_| make())`
error: use of `unwrap_or` followed by a function call
--> $DIR/methods.rs:316:5
|
316 | with_err_args.unwrap_or(Vec::with_capacity(12));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `with_err_args.unwrap_or_else(|_| Vec::with_capacity(12))`
error: use of `unwrap_or` followed by a call to `default`
--> $DIR/methods.rs:319:5
|
319 | 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/methods.rs:322:5
|
322 | 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/methods.rs:325:5
|
325 | with_vec.unwrap_or(vec![]);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `with_vec.unwrap_or_else(|| < [ _ ] > :: into_vec ( box [ $ ( $ x ) , * ] ))`
error: use of `unwrap_or` followed by a function call
--> $DIR/methods.rs:330:5
|
330 | without_default.unwrap_or(Foo::new());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `without_default.unwrap_or_else(Foo::new)`
error: use of `or_insert` followed by a function call
--> $DIR/methods.rs:333:5
|
333 | map.entry(42).or_insert(String::new());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `map.entry(42).or_insert_with(String::new)`
error: use of `or_insert` followed by a function call
--> $DIR/methods.rs:336:5
|
336 | btree.entry(42).or_insert(String::new());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `btree.entry(42).or_insert_with(String::new)`
error: use of `unwrap_or` followed by a function call
--> $DIR/methods.rs:339:13
|
339 | let _ = stringy.unwrap_or("".to_owned());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `stringy.unwrap_or_else(|| "".to_owned())`
error: called `.iter().nth()` on a Vec. Calling `.get()` is both faster and more readable
--> $DIR/methods.rs:350:23
|
350 | let bad_vec = some_vec.iter().nth(3);
>>>>>>> 47be6927239cc8dabeb59764581fc4ac73327f22
| ^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D iter-nth` implied by `-D warnings`
error: called `.iter().nth()` on a slice. Calling `.get()` is both faster and more readable
<<<<<<< HEAD
--> $DIR/methods.rs:331:26
|
331 | let bad_slice = &some_vec[..].iter().nth(3);
@ -446,11 +645,53 @@ error: called `skip(x).next()` on an iterator. This is more succinctly expressed
--> $DIR/methods.rs:356:13
|
356 | let _ = some_vec.iter().skip(42).next();
=======
--> $DIR/methods.rs:351:26
|
351 | let bad_slice = &some_vec[..].iter().nth(3);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
error: called `.iter().nth()` on a slice. Calling `.get()` is both faster and more readable
--> $DIR/methods.rs:352:31
|
352 | let bad_boxed_slice = boxed_slice.iter().nth(3);
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: called `.iter().nth()` on a VecDeque. Calling `.get()` is both faster and more readable
--> $DIR/methods.rs:353:29
|
353 | let bad_vec_deque = some_vec_deque.iter().nth(3);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: called `.iter_mut().nth()` on a Vec. Calling `.get_mut()` is both faster and more readable
--> $DIR/methods.rs:358:23
|
358 | let bad_vec = some_vec.iter_mut().nth(3);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
error: called `.iter_mut().nth()` on a slice. Calling `.get_mut()` is both faster and more readable
--> $DIR/methods.rs:361:26
|
361 | let bad_slice = &some_vec[..].iter_mut().nth(3);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: called `.iter_mut().nth()` on a VecDeque. Calling `.get_mut()` is both faster and more readable
--> $DIR/methods.rs:364:29
|
364 | let bad_vec_deque = some_vec_deque.iter_mut().nth(3);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: called `skip(x).next()` on an iterator. This is more succinctly expressed by calling `nth(x)`
--> $DIR/methods.rs:376:13
|
376 | let _ = some_vec.iter().skip(42).next();
>>>>>>> 47be6927239cc8dabeb59764581fc4ac73327f22
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D iter-skip-next` implied by `-D warnings`
error: called `skip(x).next()` on an iterator. This is more succinctly expressed by calling `nth(x)`
<<<<<<< HEAD
--> $DIR/methods.rs:357:13
|
357 | let _ = some_vec.iter().cycle().skip(42).next();
@ -472,6 +713,29 @@ error: used unwrap() on an Option value. If you don't want to handle the None ca
--> $DIR/methods.rs:368:13
|
368 | let _ = opt.unwrap();
=======
--> $DIR/methods.rs:377:13
|
377 | let _ = some_vec.iter().cycle().skip(42).next();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: called `skip(x).next()` on an iterator. This is more succinctly expressed by calling `nth(x)`
--> $DIR/methods.rs:378:13
|
378 | let _ = (1..10).skip(10).next();
| ^^^^^^^^^^^^^^^^^^^^^^^
error: called `skip(x).next()` on an iterator. This is more succinctly expressed by calling `nth(x)`
--> $DIR/methods.rs:379:14
|
379 | let _ = &some_vec[..].iter().skip(3).next();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: used unwrap() on an Option value. If you don't want to handle the None case gracefully, consider using expect() to provide a better panic message
--> $DIR/methods.rs:388:13
|
388 | let _ = opt.unwrap();
>>>>>>> 47be6927239cc8dabeb59764581fc4ac73327f22
| ^^^^^^^^^^^^
|
= note: `-D option-unwrap-used` implied by `-D warnings`

View File

@ -39,12 +39,6 @@ error: generally you want to avoid `&mut &mut _` if possible
30 | let y : &mut &mut u32 = &mut &mut 2;
| ^^^^^^^^^^^^^
error: generally you want to avoid `&mut &mut _` if possible
--> $DIR/mut_mut.rs:30:17
|
30 | let y : &mut &mut u32 = &mut &mut 2;
| ^^^^^^^^^^^^^
error: generally you want to avoid `&mut &mut _` if possible
--> $DIR/mut_mut.rs:35:38
|
@ -63,21 +57,3 @@ error: generally you want to avoid `&mut &mut _` if possible
35 | let y : &mut &mut &mut u32 = &mut &mut &mut 2;
| ^^^^^^^^^^^^^
error: generally you want to avoid `&mut &mut _` if possible
--> $DIR/mut_mut.rs:35:17
|
35 | let y : &mut &mut &mut u32 = &mut &mut &mut 2;
| ^^^^^^^^^^^^^^^^^^
error: generally you want to avoid `&mut &mut _` if possible
--> $DIR/mut_mut.rs:35:22
|
35 | let y : &mut &mut &mut u32 = &mut &mut &mut 2;
| ^^^^^^^^^^^^^
error: generally you want to avoid `&mut &mut _` if possible
--> $DIR/mut_mut.rs:35:22
|
35 | let y : &mut &mut &mut u32 = &mut &mut &mut 2;
| ^^^^^^^^^^^^^

View File

@ -135,4 +135,9 @@ fn int_to_float() {
let _: f32 = unsafe { std::mem::transmute(0_i32) };
}
fn bytes_to_str(b: &[u8], mb: &mut [u8]) {
let _: &str = unsafe { std::mem::transmute(b) };
let _: &mut str = unsafe { std::mem::transmute(mb) };
}
fn main() { }

View File

@ -158,7 +158,7 @@ error: transmute from a `u32` to a `char`
--> $DIR/transmute.rs:123:28
|
123 | let _: char = unsafe { std::mem::transmute(0_u32) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::char::from_u32(0_u32)`
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::char::from_u32(0_u32).unwrap()`
|
= note: `-D transmute-int-to-char` implied by `-D warnings`
@ -166,7 +166,7 @@ error: transmute from a `i32` to a `char`
--> $DIR/transmute.rs:124:28
|
124 | let _: char = unsafe { std::mem::transmute(0_i32) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::char::from_u32(0_i32 as u32)`
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::char::from_u32(0_i32 as u32).unwrap()`
error: transmute from a `u8` to a `bool`
--> $DIR/transmute.rs:129:28
@ -190,3 +190,17 @@ error: transmute from a `i32` to a `f32`
135 | let _: f32 = unsafe { std::mem::transmute(0_i32) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f32::from_bits(0_i32 as u32)`
error: transmute from a `&[u8]` to a `&str`
--> $DIR/transmute.rs:139:28
|
139 | let _: &str = unsafe { std::mem::transmute(b) };
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8(b).unwrap()`
|
= note: `-D transmute-bytes-to-str` implied by `-D warnings`
error: transmute from a `&mut [u8]` to a `&mut str`
--> $DIR/transmute.rs:140:32
|
140 | let _: &mut str = unsafe { std::mem::transmute(mb) };
| ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8_mut(mb).unwrap()`