Merge branch 'master' into option_option_pr

This commit is contained in:
Michael Wright 2018-01-17 06:52:00 +02:00
commit 21fde9a9d1
45 changed files with 1066 additions and 479 deletions

View File

@ -14,6 +14,15 @@ env:
- secure: dj8SwwuRGuzbo2wZq5z7qXIf7P3p7cbSGs1I3pvXQmB6a58gkLiRn/qBcIIegdt/nzXs+Z0Nug+DdesYVeUPxk1hIa/eeU8p6mpyTtZ+30H4QVgVzd0VCthB5F/NUiPVxTgpGpEgCM9/p72xMwTn7AAJfsGqk7AJ4FS5ZZKhqFI=
- RUST_BACKTRACE=1
before_install:
- |
# work-around for issue https://github.com/travis-ci/travis-ci/issues/6307
# might not be necessary in the future
if [ "$TRAVIS_OS_NAME" == "osx" ]; then
command curl -sSL https://rvm.io/mpapis.asc | gpg --import -
rvm get stable
fi
install:
- . $HOME/.nvm/nvm.sh
- nvm install stable

View File

@ -1,6 +1,15 @@
# Change Log
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
* Rustup to *rustc 1.25.0-nightly (61452e506 2018-01-09)*
## 0.0.178
* Rustup to *rustc 1.25.0-nightly (ee220daca 2018-01-07)*
## 0.0.177
* Rustup to *rustc 1.24.0-nightly (250b49205 2017-12-21)*
* New lint: [`match_as_ref`]
@ -664,6 +673,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_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
[`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_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

View File

@ -1,6 +1,6 @@
[package]
name = "clippy"
version = "0.0.177"
version = "0.0.180"
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.177", path = "clippy_lints" }
clippy_lints = { version = "0.0.180", path = "clippy_lints" }
# end automatic update
cargo_metadata = "0.2"
regex = "0.2"

View File

@ -26,18 +26,35 @@ as an included feature during build. All of these options are detailed below.
As a general rule clippy will only work with the *latest* Rust nightly for now.
### As a cargo subcommand (`cargo clippy`)
One way to use clippy is by installing clippy through cargo as a cargo
subcommand.
```terminal
cargo +nightly install clippy
```
(The `+nightly` is not necessary if your default `rustup` install is nightly)
Now you can run clippy by invoking `cargo +nightly clippy`.
In case you are not using rustup, you need to set the environment flag
`SYSROOT` during installation so clippy knows where to find `librustc` and
similar crates.
```terminal
SYSROOT=/path/to/rustc/sysroot cargo install clippy
```
### Optional dependency
If you want to make clippy an optional dependency, you can do the following:
In your `Cargo.toml`:
In some cases you might want to include clippy in your project directly, as an
optional dependency. To do this, just modify `Cargo.toml`:
```toml
[dependencies]
clippy = {version = "*", optional = true}
[features]
default = []
clippy = { version = "*", optional = true }
```
And, in your `main.rs` or `lib.rs`, add these lines:
@ -54,25 +71,18 @@ Instead of adding the `cfg_attr` attributes you can also run clippy on demand:
(the `-Z no trans`, while not necessary, will stop the compilation process after
typechecking (and lints) have completed, which can significantly reduce the runtime).
### As a cargo subcommand (`cargo clippy`)
Alternatively, to only run clippy when testing:
An alternate way to use clippy is by installing clippy through cargo as a cargo
subcommand.
```terminal
cargo install clippy
```toml
[dev-dependencies]
clippy = { version = "*" }
```
Now you can run clippy by invoking `cargo clippy`, or
`rustup run nightly cargo clippy` directly from a directory that is usually
compiled with stable.
and add to `main.rs` or `lib.rs`:
In case you are not using rustup, you need to set the environment flag
`SYSROOT` during installation so clippy knows where to find `librustc` and
similar crates.
```terminal
SYSROOT=/path/to/rustc/sysroot cargo install clippy
```
#![cfg_attr(test, feature(plugin))]
#![cfg_attr(test, plugin(clippy))]
```
### Running clippy from the command line without installing
@ -143,7 +153,7 @@ blacklisted-names = ["toto", "tata", "titi"]
cyclomatic-complexity-threshold = 30
```
See the wiki for more information about which lints can be configured and the
See the [list of lints](https://rust-lang-nursery.github.io/rust-clippy/master/index.html) for more information about which lints can be configured and the
meaning of the variables.
You can also specify the path to the configuration file with:
@ -152,7 +162,7 @@ You can also specify the path to the configuration file with:
#![plugin(clippy(conf_file="path/to/clippy's/configuration"))]
```
To deactivate the “for further information visit *wiki-link*” message you can
To deactivate the “for further information visit *lint-link*” message you can
define the `CLIPPY_DISABLE_DOCS_LINKS` environment variable.
### Allowing/denying lints

View File

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

View File

@ -1,6 +1,6 @@
use syntax::ast::{Item, ItemKind, Ty, TyKind};
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.
///
@ -51,14 +51,15 @@ impl StaticConst {
TyKind::Path(..) | TyKind::Slice(..) | TyKind::Array(..) |
TyKind::Tup(..) => {
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(
cx,
CONST_STATIC_LIFETIME,
lifetime.span,
"Constants have by default a `'static` lifetime",
|db| {
db.span_suggestion(lifetime.span, "consider removing `'static`", sug);
db.span_suggestion(ty.span, "consider removing `'static`", sugg);
},
);
}

View File

@ -148,6 +148,13 @@ fn check_copy_clone<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, item: &Item, trait_ref
return;
}
}
for subst in substs {
if let Some(subst) = subst.as_type() {
if let ty::TyParam(_) = subst.sty {
return;
}
}
}
},
_ => (),
}

View File

@ -86,7 +86,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Functions {
use rustc::hir::map::Node::*;
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 {
false
};

View File

@ -150,6 +150,7 @@ pub mod ptr;
pub mod ranges;
pub mod reference;
pub mod regex;
pub mod replace_consts;
pub mod returns;
pub mod serde_api;
pub mod shadow;
@ -361,6 +362,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) {
reg.register_late_lint_pass(box types::ImplicitHasher);
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 replace_consts::ReplaceConsts);
reg.register_lint_group("clippy_restrictions", vec![
arithmetic::FLOAT_ARITHMETIC,
@ -399,6 +401,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) {
print::PRINT_STDOUT,
print::USE_DEBUG,
ranges::RANGE_PLUS_ONE,
replace_consts::REPLACE_CONSTS,
shadow::SHADOW_REUSE,
shadow::SHADOW_SAME,
shadow::SHADOW_UNRELATED,

View File

@ -361,9 +361,8 @@ declare_lint! {
/// ```rust
/// x.clone()
/// ```
declare_lint! {
declare_restriction_lint! {
pub CLONE_ON_REF_PTR,
Warn,
"using 'clone' on a ref-counted pointer"
}
@ -1013,24 +1012,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) {
let (obj_ty, _) = walk_ptrs_ty_depth(cx.tables.expr_ty(arg));
let caller_type = if match_type(cx, obj_ty, &paths::RC) {
"Rc"
} else if match_type(cx, obj_ty, &paths::ARC) {
"Arc"
} else if match_type(cx, obj_ty, &paths::WEAK_RC) || match_type(cx, obj_ty, &paths::WEAK_ARC) {
"Weak"
} else {
return;
};
if let ty::TyAdt(_, subst) = obj_ty.sty {
let caller_type = if match_type(cx, obj_ty, &paths::RC) {
"Rc"
} else if match_type(cx, obj_ty, &paths::ARC) {
"Arc"
} else if match_type(cx, obj_ty, &paths::WEAK_RC) || match_type(cx, obj_ty, &paths::WEAK_ARC) {
"Weak"
} else {
return;
};
span_lint_and_sugg(
cx,
CLONE_ON_REF_PTR,
expr.span,
"using '.clone()' on a ref-counted pointer",
"try this",
format!("{}::clone(&{})", caller_type, snippet(cx, arg.span, "_")),
);
span_lint_and_sugg(
cx,
CLONE_ON_REF_PTR,
expr.span,
"using '.clone()' on a ref-counted pointer",
"try this",
format!("{}::<{}>::clone(&{})", caller_type, subst.type_at(0), snippet(cx, arg.span, "_")),
);
}
}

View File

@ -124,7 +124,17 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDoc {
let desc = match it.node {
hir::ItemConst(..) => "a constant",
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::ItemStatic(..) => "a static",
hir::ItemStruct(..) => "a struct",
@ -133,7 +143,6 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDoc {
hir::ItemGlobalAsm(..) => "an assembly blob",
hir::ItemTy(..) => "a type alias",
hir::ItemUnion(..) => "a union",
hir::ItemAutoImpl(..) |
hir::ItemExternCrate(..) |
hir::ItemForeignMod(..) |
hir::ItemImpl(..) |

View File

@ -69,8 +69,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MutexAtomic {
atomic_name
);
match mutex_param.sty {
ty::TyUint(t) if t != ast::UintTy::Us => span_lint(cx, MUTEX_INTEGER, expr.span, &msg),
ty::TyInt(t) if t != ast::IntTy::Is => span_lint(cx, MUTEX_INTEGER, expr.span, &msg),
ty::TyUint(t) if t != ast::UintTy::Usize => span_lint(cx, MUTEX_INTEGER, expr.span, &msg),
ty::TyInt(t) if t != ast::IntTy::Isize => span_lint(cx, MUTEX_INTEGER, expr.span, &msg),
_ => span_lint(cx, MUTEX_ATOMIC, expr.span, &msg),
};
}

View File

@ -38,7 +38,7 @@ use utils::{in_macro, snippet, span_lint_and_then};
/// let mut v = Vec::<String>::new();
/// let _ = v.iter_mut().filter(|&ref a| a.is_empty());
/// ```
/// This clojure takes a reference on something that has been matched as a
/// This closure takes a reference on something that has been matched as a
/// reference and
/// de-referenced.
/// As such, it could just be |a| a.is_empty()

View File

@ -87,7 +87,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessPassByValue {
// Exclude non-inherent impls
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(..))
{
return;

View File

@ -35,7 +35,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
if let ExprStruct(_, ref fields, Some(ref base)) = expr.node {
let ty = cx.tables.expr_ty(expr);
if let ty::TyAdt(def, _) = ty.sty {
if fields.len() == def.struct_variant().fields.len() {
if fields.len() == def.non_enum_variant().fields.len() {
span_lint(
cx,
NEEDLESS_UPDATE,

View File

@ -5,7 +5,7 @@ use rustc::lint::*;
use syntax::ast::LitKind;
use syntax::symbol::InternedString;
use syntax_pos::Span;
use utils::{is_expn_of, match_def_path, match_path, resolve_node, span_lint};
use utils::{is_expn_of, match_def_path, match_path, resolve_node, span_lint, span_lint_and_sugg};
use utils::{opt_def_id, paths};
/// **What it does:** This lint warns when you using `println!("")` to
@ -182,8 +182,14 @@ fn check_println<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, span: Span, fmtstr: Inter
if let Ok(snippet) = cx.sess().codemap().span_to_snippet(span);
if snippet.contains("\"\"");
then {
span_lint(cx, PRINT_WITH_NEWLINE, span,
"using `println!(\"\")`, consider using `println!()` instead");
span_lint_and_sugg(
cx,
PRINT_WITH_NEWLINE,
span,
"using `println!(\"\")`",
"replace it with",
"println!()".to_string(),
);
}
}
}

View File

@ -0,0 +1,102 @@
use rustc::lint::*;
use rustc::hir;
use rustc::hir::def::Def;
use utils::{match_def_path, span_lint_and_sugg};
/// **What it does:** Checks for usage of `ATOMIC_X_INIT`, `ONCE_INIT`, and
/// `uX/iX::MIN/MAX`.
///
/// **Why is this bad?** `const fn`s exist
///
/// **Known problems:** None.
///
/// **Example:**
/// ```rust
/// static FOO: AtomicIsize = ATOMIC_ISIZE_INIT;
/// ```
///
/// Could be written:
///
/// ```rust
/// static FOO: AtomicIsize = AtomicIsize::new(0);
/// ```
declare_lint! {
pub REPLACE_CONSTS,
Allow,
"Lint usages of standard library `const`s that could be replaced by `const fn`s"
}
pub struct ReplaceConsts;
impl LintPass for ReplaceConsts {
fn get_lints(&self) -> LintArray {
lint_array!(REPLACE_CONSTS)
}
}
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ReplaceConsts {
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr) {
if_chain! {
if let hir::ExprPath(ref qp) = expr.node;
if let Def::Const(def_id) = cx.tables.qpath_def(qp, expr.hir_id);
then {
for &(const_path, repl_snip) in REPLACEMENTS {
if match_def_path(cx.tcx, def_id, const_path) {
span_lint_and_sugg(
cx,
REPLACE_CONSTS,
expr.span,
&format!("using `{}`", const_path.last().expect("empty path")),
"try this",
repl_snip.to_string(),
);
return;
}
}
}
}
}
}
const REPLACEMENTS: &[(&[&str], &str)] = &[
// Once
(&["core", "sync", "ONCE_INIT"], "Once::new()"),
// Atomic
(&["core", "sync", "atomic", "ATOMIC_BOOL_INIT"], "AtomicBool::new(false)"),
(&["core", "sync", "atomic", "ATOMIC_ISIZE_INIT"], "AtomicIsize::new(0)"),
(&["core", "sync", "atomic", "ATOMIC_I8_INIT"], "AtomicI8::new(0)"),
(&["core", "sync", "atomic", "ATOMIC_I16_INIT"], "AtomicI16::new(0)"),
(&["core", "sync", "atomic", "ATOMIC_I32_INIT"], "AtomicI32::new(0)"),
(&["core", "sync", "atomic", "ATOMIC_I64_INIT"], "AtomicI64::new(0)"),
(&["core", "sync", "atomic", "ATOMIC_USIZE_INIT"], "AtomicUsize::new(0)"),
(&["core", "sync", "atomic", "ATOMIC_U8_INIT"], "AtomicU8::new(0)"),
(&["core", "sync", "atomic", "ATOMIC_U16_INIT"], "AtomicU16::new(0)"),
(&["core", "sync", "atomic", "ATOMIC_U32_INIT"], "AtomicU32::new(0)"),
(&["core", "sync", "atomic", "ATOMIC_U64_INIT"], "AtomicU64::new(0)"),
// Min
(&["core", "isize", "MIN"], "isize::min_value()"),
(&["core", "i8", "MIN"], "i8::min_value()"),
(&["core", "i16", "MIN"], "i16::min_value()"),
(&["core", "i32", "MIN"], "i32::min_value()"),
(&["core", "i64", "MIN"], "i64::min_value()"),
(&["core", "i128", "MIN"], "i128::min_value()"),
(&["core", "usize", "MIN"], "usize::min_value()"),
(&["core", "u8", "MIN"], "u8::min_value()"),
(&["core", "u16", "MIN"], "u16::min_value()"),
(&["core", "u32", "MIN"], "u32::min_value()"),
(&["core", "u64", "MIN"], "u64::min_value()"),
(&["core", "u128", "MIN"], "u128::min_value()"),
// Max
(&["core", "isize", "MAX"], "isize::max_value()"),
(&["core", "i8", "MAX"], "i8::max_value()"),
(&["core", "i16", "MAX"], "i16::max_value()"),
(&["core", "i32", "MAX"], "i32::max_value()"),
(&["core", "i64", "MAX"], "i64::max_value()"),
(&["core", "i128", "MAX"], "i128::max_value()"),
(&["core", "usize", "MAX"], "usize::max_value()"),
(&["core", "u8", "MAX"], "u8::max_value()"),
(&["core", "u16", "MAX"], "u16::max_value()"),
(&["core", "u32", "MAX"], "u32::max_value()"),
(&["core", "u64", "MAX"], "u64::max_value()"),
(&["core", "u128", "MAX"], "u128::max_value()"),
];

View File

@ -36,6 +36,14 @@ pub struct TypePass;
/// values: Box<Vec<Foo>>,
/// }
/// ```
///
/// Better:
///
/// ```rust
/// struct X {
/// values: Vec<Foo>,
/// }
/// ```
declare_lint! {
pub BOX_VEC,
Warn,
@ -109,6 +117,12 @@ declare_lint! {
/// ```rust
/// fn foo(bar: &Box<T>) { ... }
/// ```
///
/// Better:
///
/// ```rust
/// fn foo(bar: &T) { ... }
/// ```
declare_lint! {
pub BORROWED_BOX,
Warn,
@ -553,6 +567,12 @@ declare_lint! {
/// ```rust
/// fn as_u64(x: u8) -> u64 { x as u64 }
/// ```
///
/// Using `::from` would look like this:
///
/// ```rust
/// fn as_u64(x: u8) -> u64 { u64::from(x) }
/// ```
declare_lint! {
pub CAST_LOSSLESS,
Warn,
@ -580,7 +600,7 @@ declare_lint! {
fn int_ty_to_nbits(typ: Ty, tcx: TyCtxt) -> u64 {
match typ.sty {
ty::TyInt(i) => match i {
IntTy::Is => tcx.data_layout.pointer_size.bits(),
IntTy::Isize => tcx.data_layout.pointer_size.bits(),
IntTy::I8 => 8,
IntTy::I16 => 16,
IntTy::I32 => 32,
@ -588,7 +608,7 @@ fn int_ty_to_nbits(typ: Ty, tcx: TyCtxt) -> u64 {
IntTy::I128 => 128,
},
ty::TyUint(i) => match i {
UintTy::Us => tcx.data_layout.pointer_size.bits(),
UintTy::Usize => tcx.data_layout.pointer_size.bits(),
UintTy::U8 => 8,
UintTy::U16 => 16,
UintTy::U32 => 32,
@ -601,7 +621,7 @@ fn int_ty_to_nbits(typ: Ty, tcx: TyCtxt) -> u64 {
fn is_isize_or_usize(typ: Ty) -> bool {
match typ.sty {
ty::TyInt(IntTy::Is) | ty::TyUint(UintTy::Us) => true,
ty::TyInt(IntTy::Isize) | ty::TyUint(UintTy::Usize) => true,
_ => false,
}
}
@ -1033,6 +1053,12 @@ impl<'tcx> Visitor<'tcx> for TypeComplexityVisitor {
/// ```rust
/// 'x' as u8
/// ```
///
/// A better version, using the byte literal:
///
/// ```rust
/// b'x'
/// ```
declare_lint! {
pub CHAR_LIT_AS_U8,
Warn,
@ -1119,6 +1145,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>(
cx: &LateContext<'a, 'tcx>,
@ -1136,6 +1176,11 @@ fn detect_absurd_comparison<'a, 'tcx>(
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 (rel, normalized_lhs, normalized_rhs) = if let Some(val) = normalized {
val
@ -1190,15 +1235,15 @@ fn detect_extreme_expr<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) -
let which = match (&ty.sty, cv.val) {
(&ty::TyBool, Bool(false)) |
(&ty::TyInt(IntTy::Is), Integral(Isize(Is32(::std::i32::MIN)))) |
(&ty::TyInt(IntTy::Is), Integral(Isize(Is64(::std::i64::MIN)))) |
(&ty::TyInt(IntTy::Isize), Integral(Isize(Is32(::std::i32::MIN)))) |
(&ty::TyInt(IntTy::Isize), Integral(Isize(Is64(::std::i64::MIN)))) |
(&ty::TyInt(IntTy::I8), Integral(I8(::std::i8::MIN))) |
(&ty::TyInt(IntTy::I16), Integral(I16(::std::i16::MIN))) |
(&ty::TyInt(IntTy::I32), Integral(I32(::std::i32::MIN))) |
(&ty::TyInt(IntTy::I64), Integral(I64(::std::i64::MIN))) |
(&ty::TyInt(IntTy::I128), Integral(I128(::std::i128::MIN))) |
(&ty::TyUint(UintTy::Us), Integral(Usize(Us32(::std::u32::MIN)))) |
(&ty::TyUint(UintTy::Us), Integral(Usize(Us64(::std::u64::MIN)))) |
(&ty::TyUint(UintTy::Usize), Integral(Usize(Us32(::std::u32::MIN)))) |
(&ty::TyUint(UintTy::Usize), Integral(Usize(Us64(::std::u64::MIN)))) |
(&ty::TyUint(UintTy::U8), Integral(U8(::std::u8::MIN))) |
(&ty::TyUint(UintTy::U16), Integral(U16(::std::u16::MIN))) |
(&ty::TyUint(UintTy::U32), Integral(U32(::std::u32::MIN))) |
@ -1206,15 +1251,15 @@ fn detect_extreme_expr<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) -
(&ty::TyUint(UintTy::U128), Integral(U128(::std::u128::MIN))) => Minimum,
(&ty::TyBool, Bool(true)) |
(&ty::TyInt(IntTy::Is), Integral(Isize(Is32(::std::i32::MAX)))) |
(&ty::TyInt(IntTy::Is), Integral(Isize(Is64(::std::i64::MAX)))) |
(&ty::TyInt(IntTy::Isize), Integral(Isize(Is32(::std::i32::MAX)))) |
(&ty::TyInt(IntTy::Isize), Integral(Isize(Is64(::std::i64::MAX)))) |
(&ty::TyInt(IntTy::I8), Integral(I8(::std::i8::MAX))) |
(&ty::TyInt(IntTy::I16), Integral(I16(::std::i16::MAX))) |
(&ty::TyInt(IntTy::I32), Integral(I32(::std::i32::MAX))) |
(&ty::TyInt(IntTy::I64), Integral(I64(::std::i64::MAX))) |
(&ty::TyInt(IntTy::I128), Integral(I128(::std::i128::MAX))) |
(&ty::TyUint(UintTy::Us), Integral(Usize(Us32(::std::u32::MAX)))) |
(&ty::TyUint(UintTy::Us), Integral(Usize(Us64(::std::u64::MAX)))) |
(&ty::TyUint(UintTy::Usize), Integral(Usize(Us32(::std::u32::MAX)))) |
(&ty::TyUint(UintTy::Usize), Integral(Usize(Us64(::std::u64::MAX)))) |
(&ty::TyUint(UintTy::U8), Integral(U8(::std::u8::MAX))) |
(&ty::TyUint(UintTy::U16), Integral(U16(::std::u16::MAX))) |
(&ty::TyUint(UintTy::U32), Integral(U32(::std::u32::MAX))) |
@ -1368,7 +1413,7 @@ fn numeric_cast_precast_bounds<'a>(cx: &LateContext, expr: &'a Expr) -> Option<(
FullInt::S(i128::from(i64::max_value())),
),
IntTy::I128 => (FullInt::S(i128::min_value() as i128), FullInt::S(i128::max_value() as i128)),
IntTy::Is => (FullInt::S(isize::min_value() as i128), FullInt::S(isize::max_value() as i128)),
IntTy::Isize => (FullInt::S(isize::min_value() as i128), FullInt::S(isize::max_value() as i128)),
}),
ty::TyUint(uint_ty) => Some(match uint_ty {
UintTy::U8 => (FullInt::U(u128::from(u8::min_value())), FullInt::U(u128::from(u8::max_value()))),
@ -1385,7 +1430,7 @@ fn numeric_cast_precast_bounds<'a>(cx: &LateContext, expr: &'a Expr) -> Option<(
FullInt::U(u128::from(u64::max_value())),
),
UintTy::U128 => (FullInt::U(u128::min_value() as u128), FullInt::U(u128::max_value() as u128)),
UintTy::Us => (FullInt::U(usize::min_value() as u128), FullInt::U(usize::max_value() as u128)),
UintTy::Usize => (FullInt::U(usize::min_value() as u128), FullInt::U(usize::max_value() as u128)),
}),
_ => None,
}
@ -1634,7 +1679,6 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ImplicitHasher {
let mut ctr_vis = ImplicitHasherConstructorVisitor::new(cx, target);
ctr_vis.visit_body(body);
assert!(ctr_vis.suggestions.is_empty());
span_lint_and_then(
cx,

View File

@ -152,10 +152,10 @@ define_Conf! {
"DirectX",
"ECMAScript",
"GPLv2", "GPLv3",
"GitHub",
"GitHub", "GitLab",
"IPv4", "IPv6",
"JavaScript",
"NaN",
"NaN", "NaNs",
"OAuth",
"OpenGL", "OpenSSH", "OpenSSL", "OpenStreetMap",
"TrueType",

View File

@ -406,9 +406,6 @@ fn print_item(cx: &LateContext, item: &hir::Item) {
hir::ItemTraitAlias(..) => {
println!("trait alias");
}
hir::ItemAutoImpl(_, ref _trait_ref) => {
println!("auto impl");
},
hir::ItemImpl(_, _, _, _, Some(ref _trait_ref), _, _) => {
println!("trait impl");
},

View File

@ -50,3 +50,8 @@ impl PartialOrd<u32> for U {
pub fn foo(val: U) -> bool {
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
}

View File

@ -25,36 +25,6 @@ fn main() {
1u32 as i32;
1u64 as i64;
1usize as isize;
// Test cast_lossless with casts to integer types
1i8 as i16;
1i8 as i32;
1i8 as i64;
1u8 as i16;
1u8 as i32;
1u8 as i64;
1u8 as u16;
1u8 as u32;
1u8 as u64;
1i16 as i32;
1i16 as i64;
1u16 as i32;
1u16 as i64;
1u16 as u32;
1u16 as u64;
1i32 as i64;
1u32 as i64;
1u32 as u64;
// Test cast_lossless with casts to floating-point types
1i8 as f32;
1i8 as f64;
1u8 as f32;
1u8 as f64;
1i16 as f32;
1i16 as f64;
1u16 as f32;
1u16 as f64;
1i32 as f64;
1u32 as f64;
// Test cast_lossless with casts from floating-point types
1.0f32 as f64;
// Test cast_lossless with an expression wrapped in parens
@ -63,25 +33,6 @@ fn main() {
1i32 as u32;
1isize as usize;
// Extra checks for *size
// Casting from *size
1isize as i8;
1isize as f64;
1usize as f64;
1isize as f32;
1usize as f32;
1isize as i32;
1isize as u32;
1usize as u32;
1usize as i32;
// Casting to *size
1i64 as isize;
1i64 as usize;
1u64 as isize;
1u64 as usize;
1u32 as isize;
1u32 as usize; // Should not trigger any lint
1i32 as isize; // Neither should this
1i32 as usize;
// Test cast_unnecessary
1i32 as i32;
1f32 as f32;

View File

@ -132,331 +132,49 @@ error: casting usize to isize may wrap around the value
27 | 1usize as isize;
| ^^^^^^^^^^^^^^^
error: casting i8 to i16 may become silently lossy if types change
error: casting f32 to f64 may become silently lossy if types change
--> $DIR/cast.rs:29:5
|
29 | 1i8 as i16;
| ^^^^^^^^^^ help: try: `i16::from(1i8)`
29 | 1.0f32 as f64;
| ^^^^^^^^^^^^^ help: try: `f64::from(1.0f32)`
|
= note: `-D cast-lossless` implied by `-D warnings`
error: casting i8 to i32 may become silently lossy if types change
--> $DIR/cast.rs:30:5
|
30 | 1i8 as i32;
| ^^^^^^^^^^ help: try: `i32::from(1i8)`
error: casting i8 to i64 may become silently lossy if types change
error: casting u8 to u16 may become silently lossy if types change
--> $DIR/cast.rs:31:5
|
31 | 1i8 as i64;
| ^^^^^^^^^^ help: try: `i64::from(1i8)`
error: casting u8 to i16 may become silently lossy if types change
--> $DIR/cast.rs:32:5
|
32 | 1u8 as i16;
| ^^^^^^^^^^ help: try: `i16::from(1u8)`
error: casting u8 to i32 may become silently lossy if types change
--> $DIR/cast.rs:33:5
|
33 | 1u8 as i32;
| ^^^^^^^^^^ help: try: `i32::from(1u8)`
error: casting u8 to i64 may become silently lossy if types change
--> $DIR/cast.rs:34:5
|
34 | 1u8 as i64;
| ^^^^^^^^^^ help: try: `i64::from(1u8)`
error: casting u8 to u16 may become silently lossy if types change
--> $DIR/cast.rs:35:5
|
35 | 1u8 as u16;
| ^^^^^^^^^^ help: try: `u16::from(1u8)`
error: casting u8 to u32 may become silently lossy if types change
--> $DIR/cast.rs:36:5
|
36 | 1u8 as u32;
| ^^^^^^^^^^ help: try: `u32::from(1u8)`
error: casting u8 to u64 may become silently lossy if types change
--> $DIR/cast.rs:37:5
|
37 | 1u8 as u64;
| ^^^^^^^^^^ help: try: `u64::from(1u8)`
error: casting i16 to i32 may become silently lossy if types change
--> $DIR/cast.rs:38:5
|
38 | 1i16 as i32;
| ^^^^^^^^^^^ help: try: `i32::from(1i16)`
error: casting i16 to i64 may become silently lossy if types change
--> $DIR/cast.rs:39:5
|
39 | 1i16 as i64;
| ^^^^^^^^^^^ help: try: `i64::from(1i16)`
error: casting u16 to i32 may become silently lossy if types change
--> $DIR/cast.rs:40:5
|
40 | 1u16 as i32;
| ^^^^^^^^^^^ help: try: `i32::from(1u16)`
error: casting u16 to i64 may become silently lossy if types change
--> $DIR/cast.rs:41:5
|
41 | 1u16 as i64;
| ^^^^^^^^^^^ help: try: `i64::from(1u16)`
error: casting u16 to u32 may become silently lossy if types change
--> $DIR/cast.rs:42:5
|
42 | 1u16 as u32;
| ^^^^^^^^^^^ help: try: `u32::from(1u16)`
error: casting u16 to u64 may become silently lossy if types change
--> $DIR/cast.rs:43:5
|
43 | 1u16 as u64;
| ^^^^^^^^^^^ help: try: `u64::from(1u16)`
error: casting i32 to i64 may become silently lossy if types change
--> $DIR/cast.rs:44:5
|
44 | 1i32 as i64;
| ^^^^^^^^^^^ help: try: `i64::from(1i32)`
error: casting u32 to i64 may become silently lossy if types change
--> $DIR/cast.rs:45:5
|
45 | 1u32 as i64;
| ^^^^^^^^^^^ help: try: `i64::from(1u32)`
error: casting u32 to u64 may become silently lossy if types change
--> $DIR/cast.rs:46:5
|
46 | 1u32 as u64;
| ^^^^^^^^^^^ help: try: `u64::from(1u32)`
error: casting i8 to f32 may become silently lossy if types change
--> $DIR/cast.rs:48:5
|
48 | 1i8 as f32;
| ^^^^^^^^^^ help: try: `f32::from(1i8)`
error: casting i8 to f64 may become silently lossy if types change
--> $DIR/cast.rs:49:5
|
49 | 1i8 as f64;
| ^^^^^^^^^^ help: try: `f64::from(1i8)`
error: casting u8 to f32 may become silently lossy if types change
--> $DIR/cast.rs:50:5
|
50 | 1u8 as f32;
| ^^^^^^^^^^ help: try: `f32::from(1u8)`
error: casting u8 to f64 may become silently lossy if types change
--> $DIR/cast.rs:51:5
|
51 | 1u8 as f64;
| ^^^^^^^^^^ help: try: `f64::from(1u8)`
error: casting i16 to f32 may become silently lossy if types change
--> $DIR/cast.rs:52:5
|
52 | 1i16 as f32;
| ^^^^^^^^^^^ help: try: `f32::from(1i16)`
error: casting i16 to f64 may become silently lossy if types change
--> $DIR/cast.rs:53:5
|
53 | 1i16 as f64;
| ^^^^^^^^^^^ help: try: `f64::from(1i16)`
error: casting u16 to f32 may become silently lossy if types change
--> $DIR/cast.rs:54:5
|
54 | 1u16 as f32;
| ^^^^^^^^^^^ help: try: `f32::from(1u16)`
error: casting u16 to f64 may become silently lossy if types change
--> $DIR/cast.rs:55:5
|
55 | 1u16 as f64;
| ^^^^^^^^^^^ help: try: `f64::from(1u16)`
error: casting i32 to f64 may become silently lossy if types change
--> $DIR/cast.rs:56:5
|
56 | 1i32 as f64;
| ^^^^^^^^^^^ help: try: `f64::from(1i32)`
error: casting u32 to f64 may become silently lossy if types change
--> $DIR/cast.rs:57:5
|
57 | 1u32 as f64;
| ^^^^^^^^^^^ help: try: `f64::from(1u32)`
error: casting f32 to f64 may become silently lossy if types change
--> $DIR/cast.rs:59:5
|
59 | 1.0f32 as f64;
| ^^^^^^^^^^^^^ help: try: `f64::from(1.0f32)`
error: casting u8 to u16 may become silently lossy if types change
--> $DIR/cast.rs:61:5
|
61 | (1u8 + 1u8) as u16;
31 | (1u8 + 1u8) as u16;
| ^^^^^^^^^^^^^^^^^^ help: try: `u16::from(1u8 + 1u8)`
error: casting i32 to u32 may lose the sign of the value
--> $DIR/cast.rs:63:5
--> $DIR/cast.rs:33:5
|
63 | 1i32 as u32;
33 | 1i32 as u32;
| ^^^^^^^^^^^
error: casting isize to usize may lose the sign of the value
--> $DIR/cast.rs:64:5
--> $DIR/cast.rs:34:5
|
64 | 1isize as usize;
34 | 1isize as usize;
| ^^^^^^^^^^^^^^^
error: casting isize to i8 may truncate the value
--> $DIR/cast.rs:67:5
|
67 | 1isize as i8;
| ^^^^^^^^^^^^
error: casting isize to f64 causes a loss of precision on targets with 64-bit wide pointers (isize is 64 bits wide, but f64's mantissa is only 52 bits wide)
--> $DIR/cast.rs:68:5
|
68 | 1isize as f64;
| ^^^^^^^^^^^^^
error: casting usize to f64 causes a loss of precision on targets with 64-bit wide pointers (usize is 64 bits wide, but f64's mantissa is only 52 bits wide)
--> $DIR/cast.rs:69:5
|
69 | 1usize as f64;
| ^^^^^^^^^^^^^
error: casting isize to f32 causes a loss of precision (isize is 32 or 64 bits wide, but f32's mantissa is only 23 bits wide)
--> $DIR/cast.rs:70:5
|
70 | 1isize as f32;
| ^^^^^^^^^^^^^
error: casting usize to f32 causes a loss of precision (usize is 32 or 64 bits wide, but f32's mantissa is only 23 bits wide)
--> $DIR/cast.rs:71:5
|
71 | 1usize as f32;
| ^^^^^^^^^^^^^
error: casting isize to i32 may truncate the value on targets with 64-bit wide pointers
--> $DIR/cast.rs:72:5
|
72 | 1isize as i32;
| ^^^^^^^^^^^^^
error: casting isize to u32 may lose the sign of the value
--> $DIR/cast.rs:73:5
|
73 | 1isize as u32;
| ^^^^^^^^^^^^^
error: casting isize to u32 may truncate the value on targets with 64-bit wide pointers
--> $DIR/cast.rs:73:5
|
73 | 1isize as u32;
| ^^^^^^^^^^^^^
error: casting usize to u32 may truncate the value on targets with 64-bit wide pointers
--> $DIR/cast.rs:74:5
|
74 | 1usize as u32;
| ^^^^^^^^^^^^^
error: casting usize to i32 may truncate the value on targets with 64-bit wide pointers
--> $DIR/cast.rs:75:5
|
75 | 1usize as i32;
| ^^^^^^^^^^^^^
error: casting usize to i32 may wrap around the value on targets with 32-bit wide pointers
--> $DIR/cast.rs:75:5
|
75 | 1usize as i32;
| ^^^^^^^^^^^^^
error: casting i64 to isize may truncate the value on targets with 32-bit wide pointers
--> $DIR/cast.rs:77:5
|
77 | 1i64 as isize;
| ^^^^^^^^^^^^^
error: casting i64 to usize may lose the sign of the value
--> $DIR/cast.rs:78:5
|
78 | 1i64 as usize;
| ^^^^^^^^^^^^^
error: casting i64 to usize may truncate the value on targets with 32-bit wide pointers
--> $DIR/cast.rs:78:5
|
78 | 1i64 as usize;
| ^^^^^^^^^^^^^
error: casting u64 to isize may truncate the value on targets with 32-bit wide pointers
--> $DIR/cast.rs:79:5
|
79 | 1u64 as isize;
| ^^^^^^^^^^^^^
error: casting u64 to isize may wrap around the value on targets with 64-bit wide pointers
--> $DIR/cast.rs:79:5
|
79 | 1u64 as isize;
| ^^^^^^^^^^^^^
error: casting u64 to usize may truncate the value on targets with 32-bit wide pointers
--> $DIR/cast.rs:80:5
|
80 | 1u64 as usize;
| ^^^^^^^^^^^^^
error: casting u32 to isize may wrap around the value on targets with 32-bit wide pointers
--> $DIR/cast.rs:81:5
|
81 | 1u32 as isize;
| ^^^^^^^^^^^^^
error: casting i32 to usize may lose the sign of the value
--> $DIR/cast.rs:84:5
|
84 | 1i32 as usize;
| ^^^^^^^^^^^^^
error: casting to the same type is unnecessary (`i32` -> `i32`)
--> $DIR/cast.rs:86:5
--> $DIR/cast.rs:37:5
|
86 | 1i32 as i32;
37 | 1i32 as i32;
| ^^^^^^^^^^^
|
= note: `-D unnecessary-cast` implied by `-D warnings`
error: casting to the same type is unnecessary (`f32` -> `f32`)
--> $DIR/cast.rs:87:5
--> $DIR/cast.rs:38:5
|
87 | 1f32 as f32;
38 | 1f32 as f32;
| ^^^^^^^^^^^
error: casting to the same type is unnecessary (`bool` -> `bool`)
--> $DIR/cast.rs:88:5
--> $DIR/cast.rs:39:5
|
88 | false as bool;
39 | false as bool;
| ^^^^^^^^^^^^^

View File

@ -0,0 +1,15 @@
#[warn(cast_lossless)]
#[allow(no_effect, unnecessary_operation)]
fn main() {
// Test cast_lossless with casts to floating-point types
1i8 as f32;
1i8 as f64;
1u8 as f32;
1u8 as f64;
1i16 as f32;
1i16 as f64;
1u16 as f32;
1u16 as f64;
1i32 as f64;
1u32 as f64;
}

View File

@ -0,0 +1,62 @@
error: casting i8 to f32 may become silently lossy if types change
--> $DIR/cast_lossless_float.rs:5:5
|
5 | 1i8 as f32;
| ^^^^^^^^^^ help: try: `f32::from(1i8)`
|
= note: `-D cast-lossless` implied by `-D warnings`
error: casting i8 to f64 may become silently lossy if types change
--> $DIR/cast_lossless_float.rs:6:5
|
6 | 1i8 as f64;
| ^^^^^^^^^^ help: try: `f64::from(1i8)`
error: casting u8 to f32 may become silently lossy if types change
--> $DIR/cast_lossless_float.rs:7:5
|
7 | 1u8 as f32;
| ^^^^^^^^^^ help: try: `f32::from(1u8)`
error: casting u8 to f64 may become silently lossy if types change
--> $DIR/cast_lossless_float.rs:8:5
|
8 | 1u8 as f64;
| ^^^^^^^^^^ help: try: `f64::from(1u8)`
error: casting i16 to f32 may become silently lossy if types change
--> $DIR/cast_lossless_float.rs:9:5
|
9 | 1i16 as f32;
| ^^^^^^^^^^^ help: try: `f32::from(1i16)`
error: casting i16 to f64 may become silently lossy if types change
--> $DIR/cast_lossless_float.rs:10:5
|
10 | 1i16 as f64;
| ^^^^^^^^^^^ help: try: `f64::from(1i16)`
error: casting u16 to f32 may become silently lossy if types change
--> $DIR/cast_lossless_float.rs:11:5
|
11 | 1u16 as f32;
| ^^^^^^^^^^^ help: try: `f32::from(1u16)`
error: casting u16 to f64 may become silently lossy if types change
--> $DIR/cast_lossless_float.rs:12:5
|
12 | 1u16 as f64;
| ^^^^^^^^^^^ help: try: `f64::from(1u16)`
error: casting i32 to f64 may become silently lossy if types change
--> $DIR/cast_lossless_float.rs:13:5
|
13 | 1i32 as f64;
| ^^^^^^^^^^^ help: try: `f64::from(1i32)`
error: casting u32 to f64 may become silently lossy if types change
--> $DIR/cast_lossless_float.rs:14:5
|
14 | 1u32 as f64;
| ^^^^^^^^^^^ help: try: `f64::from(1u32)`

View File

@ -0,0 +1,24 @@
#[warn(cast_lossless)]
#[allow(no_effect, unnecessary_operation)]
fn main() {
// Test cast_lossless with casts to integer types
1i8 as i16;
1i8 as i32;
1i8 as i64;
1u8 as i16;
1u8 as i32;
1u8 as i64;
1u8 as u16;
1u8 as u32;
1u8 as u64;
1i16 as i32;
1i16 as i64;
1u16 as i32;
1u16 as i64;
1u16 as u32;
1u16 as u64;
1i32 as i64;
1u32 as i64;
1u32 as u64;
}

View File

@ -0,0 +1,110 @@
error: casting i8 to i16 may become silently lossy if types change
--> $DIR/cast_lossless_integer.rs:6:5
|
6 | 1i8 as i16;
| ^^^^^^^^^^ help: try: `i16::from(1i8)`
|
= note: `-D cast-lossless` implied by `-D warnings`
error: casting i8 to i32 may become silently lossy if types change
--> $DIR/cast_lossless_integer.rs:7:5
|
7 | 1i8 as i32;
| ^^^^^^^^^^ help: try: `i32::from(1i8)`
error: casting i8 to i64 may become silently lossy if types change
--> $DIR/cast_lossless_integer.rs:8:5
|
8 | 1i8 as i64;
| ^^^^^^^^^^ help: try: `i64::from(1i8)`
error: casting u8 to i16 may become silently lossy if types change
--> $DIR/cast_lossless_integer.rs:9:5
|
9 | 1u8 as i16;
| ^^^^^^^^^^ help: try: `i16::from(1u8)`
error: casting u8 to i32 may become silently lossy if types change
--> $DIR/cast_lossless_integer.rs:10:5
|
10 | 1u8 as i32;
| ^^^^^^^^^^ help: try: `i32::from(1u8)`
error: casting u8 to i64 may become silently lossy if types change
--> $DIR/cast_lossless_integer.rs:11:5
|
11 | 1u8 as i64;
| ^^^^^^^^^^ help: try: `i64::from(1u8)`
error: casting u8 to u16 may become silently lossy if types change
--> $DIR/cast_lossless_integer.rs:12:5
|
12 | 1u8 as u16;
| ^^^^^^^^^^ help: try: `u16::from(1u8)`
error: casting u8 to u32 may become silently lossy if types change
--> $DIR/cast_lossless_integer.rs:13:5
|
13 | 1u8 as u32;
| ^^^^^^^^^^ help: try: `u32::from(1u8)`
error: casting u8 to u64 may become silently lossy if types change
--> $DIR/cast_lossless_integer.rs:14:5
|
14 | 1u8 as u64;
| ^^^^^^^^^^ help: try: `u64::from(1u8)`
error: casting i16 to i32 may become silently lossy if types change
--> $DIR/cast_lossless_integer.rs:15:5
|
15 | 1i16 as i32;
| ^^^^^^^^^^^ help: try: `i32::from(1i16)`
error: casting i16 to i64 may become silently lossy if types change
--> $DIR/cast_lossless_integer.rs:16:5
|
16 | 1i16 as i64;
| ^^^^^^^^^^^ help: try: `i64::from(1i16)`
error: casting u16 to i32 may become silently lossy if types change
--> $DIR/cast_lossless_integer.rs:17:5
|
17 | 1u16 as i32;
| ^^^^^^^^^^^ help: try: `i32::from(1u16)`
error: casting u16 to i64 may become silently lossy if types change
--> $DIR/cast_lossless_integer.rs:18:5
|
18 | 1u16 as i64;
| ^^^^^^^^^^^ help: try: `i64::from(1u16)`
error: casting u16 to u32 may become silently lossy if types change
--> $DIR/cast_lossless_integer.rs:19:5
|
19 | 1u16 as u32;
| ^^^^^^^^^^^ help: try: `u32::from(1u16)`
error: casting u16 to u64 may become silently lossy if types change
--> $DIR/cast_lossless_integer.rs:20:5
|
20 | 1u16 as u64;
| ^^^^^^^^^^^ help: try: `u64::from(1u16)`
error: casting i32 to i64 may become silently lossy if types change
--> $DIR/cast_lossless_integer.rs:21:5
|
21 | 1i32 as i64;
| ^^^^^^^^^^^ help: try: `i64::from(1i32)`
error: casting u32 to i64 may become silently lossy if types change
--> $DIR/cast_lossless_integer.rs:22:5
|
22 | 1u32 as i64;
| ^^^^^^^^^^^ help: try: `i64::from(1u32)`
error: casting u32 to u64 may become silently lossy if types change
--> $DIR/cast_lossless_integer.rs:23:5
|
23 | 1u32 as u64;
| ^^^^^^^^^^^ help: try: `u64::from(1u32)`

23
tests/ui/cast_size.rs Normal file
View File

@ -0,0 +1,23 @@
#[warn(cast_precision_loss, cast_possible_truncation, cast_sign_loss, cast_possible_wrap, cast_lossless)]
#[allow(no_effect, unnecessary_operation)]
fn main() {
// Casting from *size
1isize as i8;
1isize as f64;
1usize as f64;
1isize as f32;
1usize as f32;
1isize as i32;
1isize as u32;
1usize as u32;
1usize as i32;
// Casting to *size
1i64 as isize;
1i64 as usize;
1u64 as isize;
1u64 as usize;
1u32 as isize;
1u32 as usize; // Should not trigger any lint
1i32 as isize; // Neither should this
1i32 as usize;
}

122
tests/ui/cast_size.stderr Normal file
View File

@ -0,0 +1,122 @@
error: casting isize to i8 may truncate the value
--> $DIR/cast_size.rs:5:5
|
5 | 1isize as i8;
| ^^^^^^^^^^^^
|
= note: `-D cast-possible-truncation` implied by `-D warnings`
error: casting isize to f64 causes a loss of precision on targets with 64-bit wide pointers (isize is 64 bits wide, but f64's mantissa is only 52 bits wide)
--> $DIR/cast_size.rs:6:5
|
6 | 1isize as f64;
| ^^^^^^^^^^^^^
|
= note: `-D cast-precision-loss` implied by `-D warnings`
error: casting usize to f64 causes a loss of precision on targets with 64-bit wide pointers (usize is 64 bits wide, but f64's mantissa is only 52 bits wide)
--> $DIR/cast_size.rs:7:5
|
7 | 1usize as f64;
| ^^^^^^^^^^^^^
error: casting isize to f32 causes a loss of precision (isize is 32 or 64 bits wide, but f32's mantissa is only 23 bits wide)
--> $DIR/cast_size.rs:8:5
|
8 | 1isize as f32;
| ^^^^^^^^^^^^^
error: casting usize to f32 causes a loss of precision (usize is 32 or 64 bits wide, but f32's mantissa is only 23 bits wide)
--> $DIR/cast_size.rs:9:5
|
9 | 1usize as f32;
| ^^^^^^^^^^^^^
error: casting isize to i32 may truncate the value on targets with 64-bit wide pointers
--> $DIR/cast_size.rs:10:5
|
10 | 1isize as i32;
| ^^^^^^^^^^^^^
error: casting isize to u32 may lose the sign of the value
--> $DIR/cast_size.rs:11:5
|
11 | 1isize as u32;
| ^^^^^^^^^^^^^
|
= note: `-D cast-sign-loss` implied by `-D warnings`
error: casting isize to u32 may truncate the value on targets with 64-bit wide pointers
--> $DIR/cast_size.rs:11:5
|
11 | 1isize as u32;
| ^^^^^^^^^^^^^
error: casting usize to u32 may truncate the value on targets with 64-bit wide pointers
--> $DIR/cast_size.rs:12:5
|
12 | 1usize as u32;
| ^^^^^^^^^^^^^
error: casting usize to i32 may truncate the value on targets with 64-bit wide pointers
--> $DIR/cast_size.rs:13:5
|
13 | 1usize as i32;
| ^^^^^^^^^^^^^
error: casting usize to i32 may wrap around the value on targets with 32-bit wide pointers
--> $DIR/cast_size.rs:13:5
|
13 | 1usize as i32;
| ^^^^^^^^^^^^^
|
= note: `-D cast-possible-wrap` implied by `-D warnings`
error: casting i64 to isize may truncate the value on targets with 32-bit wide pointers
--> $DIR/cast_size.rs:15:5
|
15 | 1i64 as isize;
| ^^^^^^^^^^^^^
error: casting i64 to usize may lose the sign of the value
--> $DIR/cast_size.rs:16:5
|
16 | 1i64 as usize;
| ^^^^^^^^^^^^^
error: casting i64 to usize may truncate the value on targets with 32-bit wide pointers
--> $DIR/cast_size.rs:16:5
|
16 | 1i64 as usize;
| ^^^^^^^^^^^^^
error: casting u64 to isize may truncate the value on targets with 32-bit wide pointers
--> $DIR/cast_size.rs:17:5
|
17 | 1u64 as isize;
| ^^^^^^^^^^^^^
error: casting u64 to isize may wrap around the value on targets with 64-bit wide pointers
--> $DIR/cast_size.rs:17:5
|
17 | 1u64 as isize;
| ^^^^^^^^^^^^^
error: casting u64 to usize may truncate the value on targets with 32-bit wide pointers
--> $DIR/cast_size.rs:18:5
|
18 | 1u64 as usize;
| ^^^^^^^^^^^^^
error: casting u32 to isize may wrap around the value on targets with 32-bit wide pointers
--> $DIR/cast_size.rs:19:5
|
19 | 1u32 as isize;
| ^^^^^^^^^^^^^
error: casting i32 to usize may lose the sign of the value
--> $DIR/cast_size.rs:22:5
|
22 | 1i32 as usize;
| ^^^^^^^^^^^^^

View File

@ -0,0 +1,22 @@
use std::marker::PhantomData;
use std::fmt;
pub struct Key<T> {
#[doc(hidden)]
pub __name: &'static str,
#[doc(hidden)]
pub __phantom: PhantomData<T>,
}
impl<T> Copy for Key<T> {}
impl<T> Clone for Key<T> {
fn clone(&self) -> Self {
Key {
__name: self.__name,
__phantom: self.__phantom,
}
}
}
fn main() {}

View File

@ -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
|
4 | #![plugin(clippy(conf_file))]

View File

@ -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
|
4 | #![plugin(clippy(conf_file="../ui/conf_bad_toml.toml"))]

View File

@ -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
|
4 | #![plugin(clippy(conf_file="../ui/conf_bad_type.toml"))]

View File

@ -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
|
2 | #![plugin(clippy(conf_file="../auxiliary/conf_french_blacklisted_name.toml"))]

View File

@ -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
|
3 | #![plugin(clippy(conf_file=42))]

View File

@ -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
|
4 | #![plugin(clippy(conf_file="../auxiliary/conf_unknown_key.toml"))]

View File

@ -2,7 +2,7 @@ error: Constants have by default a `'static` lifetime
--> $DIR/const_static_lifetime.rs:4:17
|
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`
@ -10,71 +10,71 @@ error: Constants have by default a `'static` lifetime
--> $DIR/const_static_lifetime.rs:8:21
|
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
--> $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
| ^^^^^^^ help: consider removing `'static`
| -^^^^^^^---- help: consider removing `'static`: `&str`
error: Constants have by default a `'static` lifetime
--> $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
| ^^^^^^^ help: consider removing `'static`
| -^^^^^^^---- help: consider removing `'static`: `&str`
error: Constants have by default a `'static` lifetime
--> $DIR/const_static_lifetime.rs:12:18
|
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
--> $DIR/const_static_lifetime.rs:12:30
|
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
--> $DIR/const_static_lifetime.rs:14:17
|
14 | const VAR_SIX: &'static u8 = &5;
| ^^^^^^^ help: consider removing `'static`
| -^^^^^^^--- help: consider removing `'static`: `&u8`
error: Constants have by default a `'static` lifetime
--> $DIR/const_static_lifetime.rs:16:29
|
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
--> $DIR/const_static_lifetime.rs:16:39
|
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
--> $DIR/const_static_lifetime.rs:18:20
|
18 | const VAR_HEIGHT: &'static Foo = &Foo {};
| ^^^^^^^ help: consider removing `'static`
| -^^^^^^^---- help: consider removing `'static`: `&Foo`
error: Constants have by default a `'static` lifetime
--> $DIR/const_static_lifetime.rs:20:19
|
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
--> $DIR/const_static_lifetime.rs:22:19
|
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
--> $DIR/const_static_lifetime.rs:24:19
|
24 | const VAR_ARRAY: &'static [u8; 1] = b"T"; // ERROR Consider removing 'static.
| ^^^^^^^ help: consider removing `'static`
| -^^^^^^^-------- help: consider removing `'static`: `&[u8; 1]`

View File

@ -264,9 +264,3 @@ error: missing documentation for a function
191 | fn also_undocumented2() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
error: missing documentation for a function
--> $DIR/missing-doc.rs:202:1
|
202 | fn main() {}
| ^^^^^^^^^^^^

View File

@ -1,8 +1,8 @@
error: using `println!("")`, consider using `println!()` instead
error: using `println!("")`
--> $DIR/println_empty_string.rs:3:5
|
3 | println!("");
| ^^^^^^^^^^^^^
| ^^^^^^^^^^^^^ help: replace it with: `println!()`
|
= note: `-D print-with-newline` implied by `-D warnings`

View File

@ -0,0 +1,96 @@
#![feature(integer_atomics, i128, i128_type)]
#![allow(blacklisted_name)]
#![deny(replace_consts)]
use std::sync::atomic::*;
use std::sync::{ONCE_INIT, Once};
fn bad() {
// Once
{ let foo = ONCE_INIT; };
// Atomic
{ let foo = ATOMIC_BOOL_INIT; };
{ let foo = ATOMIC_ISIZE_INIT; };
{ let foo = ATOMIC_I8_INIT; };
{ let foo = ATOMIC_I16_INIT; };
{ let foo = ATOMIC_I32_INIT; };
{ let foo = ATOMIC_I64_INIT; };
{ let foo = ATOMIC_USIZE_INIT; };
{ let foo = ATOMIC_U8_INIT; };
{ let foo = ATOMIC_U16_INIT; };
{ let foo = ATOMIC_U32_INIT; };
{ let foo = ATOMIC_U64_INIT; };
// Min
{ let foo = std::isize::MIN; };
{ let foo = std::i8::MIN; };
{ let foo = std::i16::MIN; };
{ let foo = std::i32::MIN; };
{ let foo = std::i64::MIN; };
{ let foo = std::i128::MIN; };
{ let foo = std::usize::MIN; };
{ let foo = std::u8::MIN; };
{ let foo = std::u16::MIN; };
{ let foo = std::u32::MIN; };
{ let foo = std::u64::MIN; };
{ let foo = std::u128::MIN; };
// Max
{ let foo = std::isize::MAX; };
{ let foo = std::i8::MAX; };
{ let foo = std::i16::MAX; };
{ let foo = std::i32::MAX; };
{ let foo = std::i64::MAX; };
{ let foo = std::i128::MAX; };
{ let foo = std::usize::MAX; };
{ let foo = std::u8::MAX; };
{ let foo = std::u16::MAX; };
{ let foo = std::u32::MAX; };
{ let foo = std::u64::MAX; };
{ let foo = std::u128::MAX; };
}
fn good() {
// Once
{ let foo = Once::new(); };
// Atomic
{ let foo = AtomicBool::new(false); };
{ let foo = AtomicIsize::new(0); };
{ let foo = AtomicI8::new(0); };
{ let foo = AtomicI16::new(0); };
{ let foo = AtomicI32::new(0); };
{ let foo = AtomicI64::new(0); };
{ let foo = AtomicUsize::new(0); };
{ let foo = AtomicU8::new(0); };
{ let foo = AtomicU16::new(0); };
{ let foo = AtomicU32::new(0); };
{ let foo = AtomicU64::new(0); };
// Min
{ let foo = isize::min_value(); };
{ let foo = i8::min_value(); };
{ let foo = i16::min_value(); };
{ let foo = i32::min_value(); };
{ let foo = i64::min_value(); };
{ let foo = i128::min_value(); };
{ let foo = usize::min_value(); };
{ let foo = u8::min_value(); };
{ let foo = u16::min_value(); };
{ let foo = u32::min_value(); };
{ let foo = u64::min_value(); };
{ let foo = u128::min_value(); };
// Max
{ let foo = isize::max_value(); };
{ let foo = i8::max_value(); };
{ let foo = i16::max_value(); };
{ let foo = i32::max_value(); };
{ let foo = i64::max_value(); };
{ let foo = i128::max_value(); };
{ let foo = usize::max_value(); };
{ let foo = u8::max_value(); };
{ let foo = u16::max_value(); };
{ let foo = u32::max_value(); };
{ let foo = u64::max_value(); };
{ let foo = u128::max_value(); };
}
fn main() {
bad();
good();
}

View File

@ -0,0 +1,216 @@
error: using `ATOMIC_BOOL_INIT`
--> $DIR/replace_consts.rs:11:17
|
11 | { let foo = ATOMIC_BOOL_INIT; };
| ^^^^^^^^^^^^^^^^ help: try this: `AtomicBool::new(false)`
|
note: lint level defined here
--> $DIR/replace_consts.rs:3:9
|
3 | #![deny(replace_consts)]
| ^^^^^^^^^^^^^^
error: using `ATOMIC_ISIZE_INIT`
--> $DIR/replace_consts.rs:12:17
|
12 | { let foo = ATOMIC_ISIZE_INIT; };
| ^^^^^^^^^^^^^^^^^ help: try this: `AtomicIsize::new(0)`
error: using `ATOMIC_I8_INIT`
--> $DIR/replace_consts.rs:13:17
|
13 | { let foo = ATOMIC_I8_INIT; };
| ^^^^^^^^^^^^^^ help: try this: `AtomicI8::new(0)`
error: using `ATOMIC_I16_INIT`
--> $DIR/replace_consts.rs:14:17
|
14 | { let foo = ATOMIC_I16_INIT; };
| ^^^^^^^^^^^^^^^ help: try this: `AtomicI16::new(0)`
error: using `ATOMIC_I32_INIT`
--> $DIR/replace_consts.rs:15:17
|
15 | { let foo = ATOMIC_I32_INIT; };
| ^^^^^^^^^^^^^^^ help: try this: `AtomicI32::new(0)`
error: using `ATOMIC_I64_INIT`
--> $DIR/replace_consts.rs:16:17
|
16 | { let foo = ATOMIC_I64_INIT; };
| ^^^^^^^^^^^^^^^ help: try this: `AtomicI64::new(0)`
error: using `ATOMIC_USIZE_INIT`
--> $DIR/replace_consts.rs:17:17
|
17 | { let foo = ATOMIC_USIZE_INIT; };
| ^^^^^^^^^^^^^^^^^ help: try this: `AtomicUsize::new(0)`
error: using `ATOMIC_U8_INIT`
--> $DIR/replace_consts.rs:18:17
|
18 | { let foo = ATOMIC_U8_INIT; };
| ^^^^^^^^^^^^^^ help: try this: `AtomicU8::new(0)`
error: using `ATOMIC_U16_INIT`
--> $DIR/replace_consts.rs:19:17
|
19 | { let foo = ATOMIC_U16_INIT; };
| ^^^^^^^^^^^^^^^ help: try this: `AtomicU16::new(0)`
error: using `ATOMIC_U32_INIT`
--> $DIR/replace_consts.rs:20:17
|
20 | { let foo = ATOMIC_U32_INIT; };
| ^^^^^^^^^^^^^^^ help: try this: `AtomicU32::new(0)`
error: using `ATOMIC_U64_INIT`
--> $DIR/replace_consts.rs:21:17
|
21 | { let foo = ATOMIC_U64_INIT; };
| ^^^^^^^^^^^^^^^ help: try this: `AtomicU64::new(0)`
error: using `MIN`
--> $DIR/replace_consts.rs:23:17
|
23 | { let foo = std::isize::MIN; };
| ^^^^^^^^^^^^^^^ help: try this: `isize::min_value()`
error: using `MIN`
--> $DIR/replace_consts.rs:24:17
|
24 | { let foo = std::i8::MIN; };
| ^^^^^^^^^^^^ help: try this: `i8::min_value()`
error: using `MIN`
--> $DIR/replace_consts.rs:25:17
|
25 | { let foo = std::i16::MIN; };
| ^^^^^^^^^^^^^ help: try this: `i16::min_value()`
error: using `MIN`
--> $DIR/replace_consts.rs:26:17
|
26 | { let foo = std::i32::MIN; };
| ^^^^^^^^^^^^^ help: try this: `i32::min_value()`
error: using `MIN`
--> $DIR/replace_consts.rs:27:17
|
27 | { let foo = std::i64::MIN; };
| ^^^^^^^^^^^^^ help: try this: `i64::min_value()`
error: using `MIN`
--> $DIR/replace_consts.rs:28:17
|
28 | { let foo = std::i128::MIN; };
| ^^^^^^^^^^^^^^ help: try this: `i128::min_value()`
error: using `MIN`
--> $DIR/replace_consts.rs:29:17
|
29 | { let foo = std::usize::MIN; };
| ^^^^^^^^^^^^^^^ help: try this: `usize::min_value()`
error: using `MIN`
--> $DIR/replace_consts.rs:30:17
|
30 | { let foo = std::u8::MIN; };
| ^^^^^^^^^^^^ help: try this: `u8::min_value()`
error: using `MIN`
--> $DIR/replace_consts.rs:31:17
|
31 | { let foo = std::u16::MIN; };
| ^^^^^^^^^^^^^ help: try this: `u16::min_value()`
error: using `MIN`
--> $DIR/replace_consts.rs:32:17
|
32 | { let foo = std::u32::MIN; };
| ^^^^^^^^^^^^^ help: try this: `u32::min_value()`
error: using `MIN`
--> $DIR/replace_consts.rs:33:17
|
33 | { let foo = std::u64::MIN; };
| ^^^^^^^^^^^^^ help: try this: `u64::min_value()`
error: using `MIN`
--> $DIR/replace_consts.rs:34:17
|
34 | { let foo = std::u128::MIN; };
| ^^^^^^^^^^^^^^ help: try this: `u128::min_value()`
error: using `MAX`
--> $DIR/replace_consts.rs:36:17
|
36 | { let foo = std::isize::MAX; };
| ^^^^^^^^^^^^^^^ help: try this: `isize::max_value()`
error: using `MAX`
--> $DIR/replace_consts.rs:37:17
|
37 | { let foo = std::i8::MAX; };
| ^^^^^^^^^^^^ help: try this: `i8::max_value()`
error: using `MAX`
--> $DIR/replace_consts.rs:38:17
|
38 | { let foo = std::i16::MAX; };
| ^^^^^^^^^^^^^ help: try this: `i16::max_value()`
error: using `MAX`
--> $DIR/replace_consts.rs:39:17
|
39 | { let foo = std::i32::MAX; };
| ^^^^^^^^^^^^^ help: try this: `i32::max_value()`
error: using `MAX`
--> $DIR/replace_consts.rs:40:17
|
40 | { let foo = std::i64::MAX; };
| ^^^^^^^^^^^^^ help: try this: `i64::max_value()`
error: using `MAX`
--> $DIR/replace_consts.rs:41:17
|
41 | { let foo = std::i128::MAX; };
| ^^^^^^^^^^^^^^ help: try this: `i128::max_value()`
error: using `MAX`
--> $DIR/replace_consts.rs:42:17
|
42 | { let foo = std::usize::MAX; };
| ^^^^^^^^^^^^^^^ help: try this: `usize::max_value()`
error: using `MAX`
--> $DIR/replace_consts.rs:43:17
|
43 | { let foo = std::u8::MAX; };
| ^^^^^^^^^^^^ help: try this: `u8::max_value()`
error: using `MAX`
--> $DIR/replace_consts.rs:44:17
|
44 | { let foo = std::u16::MAX; };
| ^^^^^^^^^^^^^ help: try this: `u16::max_value()`
error: using `MAX`
--> $DIR/replace_consts.rs:45:17
|
45 | { let foo = std::u32::MAX; };
| ^^^^^^^^^^^^^ help: try this: `u32::max_value()`
error: using `MAX`
--> $DIR/replace_consts.rs:46:17
|
46 | { let foo = std::u64::MAX; };
| ^^^^^^^^^^^^^ help: try this: `u64::max_value()`
error: using `MAX`
--> $DIR/replace_consts.rs:47:17
|
47 | { let foo = std::u128::MAX; };
| ^^^^^^^^^^^^^^ help: try this: `u128::max_value()`

10
tests/ui/types.rs Normal file
View File

@ -0,0 +1,10 @@
// should not warn on lossy casting in constant types
// because not supported yet
const C : i32 = 42;
const C_I64 : i64 = C as i64;
fn main() {
// should suggest i64::from(c)
let c : i32 = 42;
let c_i64 : i64 = c as i64;
}

8
tests/ui/types.stderr Normal file
View File

@ -0,0 +1,8 @@
error: casting i32 to i64 may become silently lossy if types change
--> $DIR/types.rs:9:23
|
9 | let c_i64 : i64 = c as i64;
| ^^^^^^^^ help: try: `i64::from(c)`
|
= note: `-D cast-lossless` implied by `-D warnings`

View File

@ -1,3 +1,4 @@
#![warn(clone_on_ref_ptr)]
#![allow(unused)]
use std::collections::HashSet;
@ -5,6 +6,10 @@ use std::collections::VecDeque;
use std::rc::{self, Rc};
use std::sync::{self, Arc};
trait SomeTrait {}
struct SomeImpl;
impl SomeTrait for SomeImpl {}
fn main() {}
fn clone_on_copy() {
@ -34,7 +39,8 @@ fn clone_on_ref_ptr() {
arc_weak.clone();
sync::Weak::clone(&arc_weak);
let x = Arc::new(SomeImpl);
let _: Arc<SomeTrait> = x.clone();
}
fn clone_on_copy_generic<T: Copy>(t: T) {

View File

@ -1,75 +1,81 @@
error: using `clone` on a `Copy` type
--> $DIR/unnecessary_clone.rs:11:5
--> $DIR/unnecessary_clone.rs:16:5
|
11 | 42.clone();
16 | 42.clone();
| ^^^^^^^^^^ help: try removing the `clone` call: `42`
|
= note: `-D clone-on-copy` implied by `-D warnings`
error: using `clone` on a `Copy` type
--> $DIR/unnecessary_clone.rs:15:5
--> $DIR/unnecessary_clone.rs:20:5
|
15 | (&42).clone();
20 | (&42).clone();
| ^^^^^^^^^^^^^ help: try dereferencing it: `*(&42)`
error: using '.clone()' on a ref-counted pointer
--> $DIR/unnecessary_clone.rs:25:5
--> $DIR/unnecessary_clone.rs:30:5
|
25 | rc.clone();
| ^^^^^^^^^^ help: try this: `Rc::clone(&rc)`
30 | rc.clone();
| ^^^^^^^^^^ help: try this: `Rc::<bool>::clone(&rc)`
|
= note: `-D clone-on-ref-ptr` implied by `-D warnings`
error: using '.clone()' on a ref-counted pointer
--> $DIR/unnecessary_clone.rs:28:5
--> $DIR/unnecessary_clone.rs:33:5
|
28 | arc.clone();
| ^^^^^^^^^^^ help: try this: `Arc::clone(&arc)`
33 | arc.clone();
| ^^^^^^^^^^^ help: try this: `Arc::<bool>::clone(&arc)`
error: using '.clone()' on a ref-counted pointer
--> $DIR/unnecessary_clone.rs:31:5
--> $DIR/unnecessary_clone.rs:36:5
|
31 | rcweak.clone();
| ^^^^^^^^^^^^^^ help: try this: `Weak::clone(&rcweak)`
36 | rcweak.clone();
| ^^^^^^^^^^^^^^ help: try this: `Weak::<bool>::clone(&rcweak)`
error: using '.clone()' on a ref-counted pointer
--> $DIR/unnecessary_clone.rs:34:5
--> $DIR/unnecessary_clone.rs:39:5
|
34 | arc_weak.clone();
| ^^^^^^^^^^^^^^^^ help: try this: `Weak::clone(&arc_weak)`
39 | arc_weak.clone();
| ^^^^^^^^^^^^^^^^ help: try this: `Weak::<bool>::clone(&arc_weak)`
error: using '.clone()' on a ref-counted pointer
--> $DIR/unnecessary_clone.rs:43:29
|
43 | let _: Arc<SomeTrait> = x.clone();
| ^^^^^^^^^ help: try this: `Arc::<SomeImpl>::clone(&x)`
error: using `clone` on a `Copy` type
--> $DIR/unnecessary_clone.rs:41:5
--> $DIR/unnecessary_clone.rs:47:5
|
41 | t.clone();
47 | t.clone();
| ^^^^^^^^^ help: try removing the `clone` call: `t`
error: using `clone` on a `Copy` type
--> $DIR/unnecessary_clone.rs:43:5
--> $DIR/unnecessary_clone.rs:49:5
|
43 | Some(t).clone();
49 | Some(t).clone();
| ^^^^^^^^^^^^^^^ help: try removing the `clone` call: `Some(t)`
error: using `clone` on a double-reference; this will copy the reference instead of cloning the inner type
--> $DIR/unnecessary_clone.rs:49:22
--> $DIR/unnecessary_clone.rs:55:22
|
49 | let z: &Vec<_> = y.clone();
55 | let z: &Vec<_> = y.clone();
| ^^^^^^^^^
|
= note: `-D clone-double-ref` implied by `-D warnings`
help: try dereferencing it
|
49 | let z: &Vec<_> = &(*y).clone();
55 | let z: &Vec<_> = &(*y).clone();
| ^^^^^^^^^^^^^
help: or try being explicit about what type to clone
|
49 | let z: &Vec<_> = &std::vec::Vec<i32>::clone(y);
55 | let z: &Vec<_> = &std::vec::Vec<i32>::clone(y);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: called `cloned().collect()` on a slice to create a `Vec`. Calling `to_vec()` is both faster and more readable
--> $DIR/unnecessary_clone.rs:56:27
--> $DIR/unnecessary_clone.rs:62:27
|
56 | let v2 : Vec<isize> = v.iter().cloned().collect();
62 | let v2 : Vec<isize> = v.iter().cloned().collect();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D iter-cloned-collect` implied by `-D warnings`