Merge remote-tracking branch 'upstream/master' into prs
This commit is contained in:
commit
8e0de3d120
|
@ -170,7 +170,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) {
|
|||
reg.register_early_lint_pass(box else_if_without_else::ElseIfWithoutElse);
|
||||
// ...
|
||||
|
||||
reg.register_lint_group("clippy_restriction", vec![
|
||||
reg.register_lint_group("clippy::restriction", vec![
|
||||
// ...
|
||||
else_if_without_else::ELSE_IF_WITHOUT_ELSE,
|
||||
// ...
|
||||
|
@ -185,7 +185,7 @@ It's worth noting that the majority of `clippy_lints/src/lib.rs` is autogenerate
|
|||
```rust
|
||||
// ./clippy_lints/src/else_if_without_else.rs
|
||||
|
||||
use rustc::lint::*;
|
||||
use rustc::lint::{EarlyLintPass, LintArray, LintPass};
|
||||
|
||||
// ...
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ regex = "1"
|
|||
semver = "0.9"
|
||||
|
||||
[dev-dependencies]
|
||||
cargo_metadata = "0.5"
|
||||
cargo_metadata = "0.6"
|
||||
compiletest_rs = "0.3.7"
|
||||
lazy_static = "1.0"
|
||||
serde_derive = "1.0"
|
||||
|
@ -59,9 +59,5 @@ derive-new = "0.5"
|
|||
# for more information.
|
||||
rustc-workspace-hack = "1.0.0"
|
||||
|
||||
[build-dependencies]
|
||||
rustc_version = "0.2.2"
|
||||
ansi_term = "0.11"
|
||||
|
||||
[features]
|
||||
debugging = []
|
||||
|
|
32
README.md
32
README.md
|
@ -13,14 +13,14 @@ A collection of lints to catch common mistakes and improve your [Rust](https://g
|
|||
|
||||
We have a bunch of lint categories to allow you to choose how much Clippy is supposed to ~~annoy~~ help you:
|
||||
|
||||
* `clippy` (everything that has no false positives)
|
||||
* `clippy_pedantic` (everything)
|
||||
* `clippy_nursery` (new lints that aren't quite ready yet)
|
||||
* `clippy_style` (code that should be written in a more idiomatic way)
|
||||
* `clippy_complexity` (code that does something simple but in a complex way)
|
||||
* `clippy_perf` (code that can be written in a faster way)
|
||||
* `clippy_cargo` (checks against the cargo manifest)
|
||||
* **`clippy_correctness`** (code that is just outright wrong or very very useless)
|
||||
* `clippy::all` (everything that has no false positives)
|
||||
* `clippy::pedantic` (everything)
|
||||
* `clippy::nursery` (new lints that aren't quite ready yet)
|
||||
* `clippy::style` (code that should be written in a more idiomatic way)
|
||||
* `clippy::complexity` (code that does something simple but in a complex way)
|
||||
* `clippy::perf` (code that can be written in a faster way)
|
||||
* `clippy::cargo` (checks against the cargo manifest)
|
||||
* **`clippy::correctness`** (code that is just outright wrong or very very useless)
|
||||
|
||||
More to come, please [file an issue](https://github.com/rust-lang-nursery/rust-clippy/issues) if you have ideas!
|
||||
|
||||
|
@ -106,26 +106,18 @@ define the `CLIPPY_DISABLE_DOCS_LINKS` environment variable.
|
|||
|
||||
You can add options to `allow`/`warn`/`deny`:
|
||||
|
||||
* the whole set of `Warn` lints using the `clippy` lint group (`#![deny(clippy)]`)
|
||||
* the whole set of `Warn` lints using the `clippy` lint group (`#![deny(clippy::all)]`)
|
||||
|
||||
* all lints using both the `clippy` and `clippy_pedantic` lint groups (`#![deny(clippy)]`,
|
||||
`#![deny(clippy_pedantic)]`). Note that `clippy_pedantic` contains some very aggressive
|
||||
* all lints using both the `clippy` and `clippy::pedantic` lint groups (`#![deny(clippy::all)]`,
|
||||
`#![deny(clippy::pedantic)]`). Note that `clippy::pedantic` contains some very aggressive
|
||||
lints prone to false positives.
|
||||
|
||||
* only some lints (`#![deny(single_match, box_vec)]`, etc)
|
||||
* only some lints (`#![deny(clippy::single_match, clippy::box_vec)]`, etc)
|
||||
|
||||
* `allow`/`warn`/`deny` can be limited to a single function or module using `#[allow(...)]`, etc
|
||||
|
||||
Note: `deny` produces errors instead of warnings.
|
||||
|
||||
For convenience, `cargo clippy` automatically defines a `cargo-clippy`
|
||||
feature. This lets you set lint levels and compile with or without Clippy
|
||||
transparently:
|
||||
|
||||
```rust
|
||||
#[cfg_attr(feature = "cargo-clippy", allow(needless_lifetimes))]
|
||||
```
|
||||
|
||||
## Updating rustc
|
||||
|
||||
Sometimes, rustc moves forward without Clippy catching up. Therefore updating
|
||||
|
|
87
build.rs
87
build.rs
|
@ -13,98 +13,11 @@
|
|||
//! This build script was originally taken from the Rocket web framework:
|
||||
//! https://github.com/SergioBenitez/Rocket
|
||||
|
||||
use ansi_term::Colour::Red;
|
||||
use rustc_version::{version_meta, version_meta_for, Channel, Version, VersionMeta};
|
||||
use std::env;
|
||||
|
||||
fn main() {
|
||||
check_rustc_version();
|
||||
|
||||
// Forward the profile to the main compilation
|
||||
println!("cargo:rustc-env=PROFILE={}", env::var("PROFILE").unwrap());
|
||||
// Don't rebuild even if nothing changed
|
||||
println!("cargo:rerun-if-changed=build.rs");
|
||||
}
|
||||
|
||||
fn check_rustc_version() {
|
||||
let string = include_str!("min_version.txt");
|
||||
let min_version_meta = version_meta_for(string).expect("Could not parse version string in min_version.txt");
|
||||
let current_version_meta = version_meta().expect("Could not retrieve current rustc version information from ENV");
|
||||
|
||||
let min_version = min_version_meta.clone().semver;
|
||||
let min_date_str = min_version_meta
|
||||
.clone()
|
||||
.commit_date
|
||||
.expect("min_version.txt does not contain a rustc commit date");
|
||||
|
||||
// Dev channel (rustc built from git) does not have any date or commit information in rustc -vV
|
||||
// `current_version_meta.commit_date` would crash, so we return early here.
|
||||
if current_version_meta.channel == Channel::Dev {
|
||||
return;
|
||||
}
|
||||
|
||||
let current_version = current_version_meta.clone().semver;
|
||||
let current_date_str = current_version_meta
|
||||
.clone()
|
||||
.commit_date
|
||||
.expect("current rustc version information does not contain a rustc commit date");
|
||||
|
||||
let print_version_err = |version: &Version, date: &str| {
|
||||
eprintln!(
|
||||
"> {} {}. {} {}.\n",
|
||||
"Installed rustc version is:",
|
||||
format!("{} ({})", version, date),
|
||||
"Minimum required rustc version:",
|
||||
format!("{} ({})", min_version, min_date_str)
|
||||
);
|
||||
};
|
||||
|
||||
if !correct_channel(¤t_version_meta) {
|
||||
eprintln!(
|
||||
"\n{} {}",
|
||||
Red.bold().paint("error:"),
|
||||
"Clippy requires a nightly version of Rust."
|
||||
);
|
||||
print_version_err(¤t_version, &*current_date_str);
|
||||
eprintln!(
|
||||
"{}{}{}",
|
||||
"See the README (", "https://github.com/rust-lang-nursery/rust-clippy#usage", ") for more information."
|
||||
);
|
||||
panic!("Aborting compilation due to incompatible compiler.")
|
||||
}
|
||||
|
||||
let current_date = str_to_ymd(¤t_date_str).unwrap();
|
||||
let min_date = str_to_ymd(&min_date_str).unwrap();
|
||||
|
||||
if current_date < min_date {
|
||||
eprintln!(
|
||||
"\n{} {}",
|
||||
Red.bold().paint("error:"),
|
||||
"Clippy does not support this version of rustc nightly."
|
||||
);
|
||||
eprintln!(
|
||||
"> {}{}{}",
|
||||
"Use `", "rustup update", "` or your preferred method to update Rust."
|
||||
);
|
||||
print_version_err(¤t_version, &*current_date_str);
|
||||
panic!("Aborting compilation due to incompatible compiler.")
|
||||
}
|
||||
}
|
||||
|
||||
fn correct_channel(version_meta: &VersionMeta) -> bool {
|
||||
match version_meta.channel {
|
||||
Channel::Stable | Channel::Beta => false,
|
||||
Channel::Nightly | Channel::Dev => true,
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert a string of %Y-%m-%d to a single u32 maintaining ordering.
|
||||
fn str_to_ymd(ymd: &str) -> Option<u32> {
|
||||
let ymd: Vec<u32> = ymd.split("-").filter_map(|s| s.parse::<u32>().ok()).collect();
|
||||
if ymd.len() != 3 {
|
||||
return None;
|
||||
}
|
||||
|
||||
let (y, m, d) = (ymd[0], ymd[1], ymd[2]);
|
||||
Some((y << 9) | (m << 5) | d)
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ remark -f *.md > /dev/null
|
|||
# build clippy in debug mode and run tests
|
||||
cargo build --features debugging
|
||||
cargo test --features debugging
|
||||
cd clippy_lints && cargo test && cd ..
|
||||
mkdir -p ~/rust/cargo/bin
|
||||
cp target/debug/cargo-clippy ~/rust/cargo/bin/cargo-clippy
|
||||
cp target/debug/clippy-driver ~/rust/cargo/bin/clippy-driver
|
||||
|
|
|
@ -19,7 +19,7 @@ keywords = ["clippy", "lint", "plugin"]
|
|||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
cargo_metadata = "0.5"
|
||||
cargo_metadata = "0.6"
|
||||
itertools = "0.7"
|
||||
lazy_static = "1.0.2"
|
||||
matches = "0.1.7"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate::utils::span_lint;
|
||||
use rustc::hir::*;
|
||||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use std::f64::consts as f64;
|
||||
use syntax::ast::{FloatTy, Lit, LitKind};
|
||||
use syntax::symbol;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate::utils::span_lint;
|
||||
use rustc::hir;
|
||||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use syntax::source_map::Span;
|
||||
|
||||
/// **What it does:** Checks for plain integer arithmetic.
|
||||
|
|
|
@ -2,30 +2,11 @@ use crate::utils::{get_trait_def_id, implements_trait, snippet_opt, span_lint_an
|
|||
use crate::utils::{higher, sugg};
|
||||
use rustc::hir;
|
||||
use rustc::hir::intravisit::{walk_expr, NestedVisitorMap, Visitor};
|
||||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use if_chain::if_chain;
|
||||
use syntax::ast;
|
||||
|
||||
/// **What it does:** Checks for compound assignment operations (`+=` and
|
||||
/// similar).
|
||||
///
|
||||
/// **Why is this bad?** Projects with many developers from languages without
|
||||
/// those operations may find them unreadable and not worth their weight.
|
||||
///
|
||||
/// **Known problems:** Types implementing `OpAssign` don't necessarily
|
||||
/// implement `Op`.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// a += 1;
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
pub ASSIGN_OPS,
|
||||
restriction,
|
||||
"any compound assignment operation"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for `a = a op b` or `a = b commutative_op a`
|
||||
/// patterns.
|
||||
///
|
||||
|
@ -73,7 +54,7 @@ pub struct AssignOps;
|
|||
|
||||
impl LintPass for AssignOps {
|
||||
fn get_lints(&self) -> LintArray {
|
||||
lint_array!(ASSIGN_OPS, ASSIGN_OP_PATTERN, MISREFACTORED_ASSIGN_OP)
|
||||
lint_array!(ASSIGN_OP_PATTERN, MISREFACTORED_ASSIGN_OP)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -81,16 +62,6 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AssignOps {
|
|||
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr) {
|
||||
match expr.node {
|
||||
hir::ExprKind::AssignOp(op, ref lhs, ref rhs) => {
|
||||
span_lint_and_then(cx, ASSIGN_OPS, expr.span, "assign operation detected", |db| {
|
||||
let lhs = &sugg::Sugg::hir(cx, lhs, "..");
|
||||
let rhs = &sugg::Sugg::hir(cx, rhs, "..");
|
||||
|
||||
db.span_suggestion(
|
||||
expr.span,
|
||||
"replace it with",
|
||||
format!("{} = {}", lhs, sugg::make_binop(higher::binop(op.node), lhs, rhs)),
|
||||
);
|
||||
});
|
||||
if let hir::ExprKind::Binary(binop, ref l, ref r) = rhs.node {
|
||||
if op.node == binop.node {
|
||||
let lint = |assignee: &hir::Expr, rhs_other: &hir::Expr| {
|
||||
|
@ -137,7 +108,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AssignOps {
|
|||
},
|
||||
hir::ExprKind::Assign(ref assignee, ref e) => {
|
||||
if let hir::ExprKind::Binary(op, ref l, ref r) = e.node {
|
||||
#[allow(cyclomatic_complexity)]
|
||||
#[allow(clippy::cyclomatic_complexity)]
|
||||
let lint = |assignee: &hir::Expr, rhs: &hir::Expr| {
|
||||
let ty = cx.tables.expr_ty(assignee);
|
||||
let rty = cx.tables.expr_ty(rhs);
|
||||
|
@ -162,7 +133,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AssignOps {
|
|||
// the crate node is the only one that is not in the map
|
||||
if_chain! {
|
||||
if parent_impl != ast::CRATE_NODE_ID;
|
||||
if let hir::map::Node::NodeItem(item) = cx.tcx.hir.get(parent_impl);
|
||||
if let hir::Node::Item(item) = cx.tcx.hir.get(parent_impl);
|
||||
if let hir::ItemKind::Impl(_, _, _, _, Some(ref trait_ref), _, _) =
|
||||
item.node;
|
||||
if trait_ref.path.def.def_id() == trait_id;
|
||||
|
|
|
@ -6,8 +6,8 @@ use crate::utils::{
|
|||
without_block_comments,
|
||||
};
|
||||
use rustc::hir::*;
|
||||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use if_chain::if_chain;
|
||||
use rustc::ty::{self, TyCtxt};
|
||||
use semver::Version;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use rustc::hir::*;
|
||||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use if_chain::if_chain;
|
||||
use syntax::ast::LitKind;
|
||||
use syntax::source_map::Span;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use rustc::hir::*;
|
||||
use crate::utils::span_lint;
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use matches::matches;
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use rustc::hir::*;
|
||||
use rustc::hir::intravisit::{walk_expr, NestedVisitorMap, Visitor};
|
||||
use crate::utils::*;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use rustc::hir::*;
|
||||
use rustc::hir::intravisit::*;
|
||||
use syntax::ast::{LitKind, NodeId, DUMMY_NODE_ID};
|
||||
|
@ -118,7 +118,7 @@ impl<'a, 'tcx, 'v> Hir2Qmm<'a, 'tcx, 'v> {
|
|||
}
|
||||
for (n, expr) in self.terminals.iter().enumerate() {
|
||||
if SpanlessEq::new(self.cx).ignore_fn().eq_expr(e, expr) {
|
||||
#[allow(cast_possible_truncation)]
|
||||
#[allow(clippy::cast_possible_truncation)]
|
||||
return Ok(Bool::Term(n as u8));
|
||||
}
|
||||
let negated = match e.node {
|
||||
|
@ -150,14 +150,14 @@ impl<'a, 'tcx, 'v> Hir2Qmm<'a, 'tcx, 'v> {
|
|||
_ => continue,
|
||||
};
|
||||
if SpanlessEq::new(self.cx).ignore_fn().eq_expr(&negated, expr) {
|
||||
#[allow(cast_possible_truncation)]
|
||||
#[allow(clippy::cast_possible_truncation)]
|
||||
return Ok(Bool::Not(Box::new(Bool::Term(n as u8))));
|
||||
}
|
||||
}
|
||||
let n = self.terminals.len();
|
||||
self.terminals.push(e);
|
||||
if n < 32 {
|
||||
#[allow(cast_possible_truncation)]
|
||||
#[allow(clippy::cast_possible_truncation)]
|
||||
Ok(Bool::Term(n as u8))
|
||||
} else {
|
||||
Err("too many literals".to_owned())
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use rustc::hir::*;
|
||||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use if_chain::if_chain;
|
||||
use rustc::ty;
|
||||
use syntax::ast::{Name, UintTy};
|
||||
|
@ -65,7 +65,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ByteCount {
|
|||
_ => { return; }
|
||||
}
|
||||
};
|
||||
if ty::TyUint(UintTy::U8) != walk_ptrs_ty(cx.tables.expr_ty(needle)).sty {
|
||||
if ty::Uint(UintTy::U8) != walk_ptrs_ty(cx.tables.expr_ty(needle)).sty {
|
||||
return;
|
||||
}
|
||||
let haystack = if let ExprKind::MethodCall(ref path, _, ref args) =
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
//!
|
||||
//! This lint is **warn** by default
|
||||
|
||||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use if_chain::if_chain;
|
||||
use syntax::ast;
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use syntax::ast::*;
|
||||
use rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use crate::utils::{in_macro, snippet, span_lint_and_then};
|
||||
|
||||
/// **What it does:** Checks for constants with an explicit `'static` lifetime.
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#![allow(cast_possible_truncation)]
|
||||
#![allow(float_cmp)]
|
||||
#![allow(clippy::float_cmp)]
|
||||
|
||||
use rustc::lint::LateContext;
|
||||
use rustc::{span_bug, bug};
|
||||
|
@ -16,22 +15,6 @@ use syntax::ast::{FloatTy, LitKind};
|
|||
use syntax::ptr::P;
|
||||
use crate::utils::{sext, unsext, clip};
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum FloatWidth {
|
||||
F32,
|
||||
F64,
|
||||
Any,
|
||||
}
|
||||
|
||||
impl From<FloatTy> for FloatWidth {
|
||||
fn from(ty: FloatTy) -> Self {
|
||||
match ty {
|
||||
FloatTy::F32 => FloatWidth::F32,
|
||||
FloatTy::F64 => FloatWidth::F64,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A `LitKind`-like enum to fold constant `Expr`s into.
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Constant {
|
||||
|
@ -123,12 +106,12 @@ impl Hash for Constant {
|
|||
}
|
||||
|
||||
impl Constant {
|
||||
pub fn partial_cmp(tcx: TyCtxt<'_, '_, '_>, cmp_type: &ty::TypeVariants<'_>, left: &Self, right: &Self) -> Option<Ordering> {
|
||||
pub fn partial_cmp(tcx: TyCtxt<'_, '_, '_>, cmp_type: &ty::TyKind<'_>, left: &Self, right: &Self) -> Option<Ordering> {
|
||||
match (left, right) {
|
||||
(&Constant::Str(ref ls), &Constant::Str(ref rs)) => Some(ls.cmp(rs)),
|
||||
(&Constant::Char(ref l), &Constant::Char(ref r)) => Some(l.cmp(r)),
|
||||
(&Constant::Int(l), &Constant::Int(r)) => {
|
||||
if let ty::TyInt(int_ty) = *cmp_type {
|
||||
if let ty::Int(int_ty) = *cmp_type {
|
||||
Some(sext(tcx, l, int_ty).cmp(&sext(tcx, r, int_ty)))
|
||||
} else {
|
||||
Some(l.cmp(&r))
|
||||
|
@ -166,8 +149,8 @@ pub fn lit_to_constant<'tcx>(lit: &LitKind, ty: Ty<'tcx>) -> Constant {
|
|||
LitKind::Int(n, _) => Constant::Int(n),
|
||||
LitKind::Float(ref is, _) |
|
||||
LitKind::FloatUnsuffixed(ref is) => match ty.sty {
|
||||
ty::TyFloat(FloatTy::F32) => Constant::F32(is.as_str().parse().unwrap()),
|
||||
ty::TyFloat(FloatTy::F64) => Constant::F64(is.as_str().parse().unwrap()),
|
||||
ty::Float(FloatTy::F32) => Constant::F32(is.as_str().parse().unwrap()),
|
||||
ty::Float(FloatTy::F64) => Constant::F64(is.as_str().parse().unwrap()),
|
||||
_ => bug!(),
|
||||
},
|
||||
LitKind::Bool(b) => Constant::Bool(b),
|
||||
|
@ -220,7 +203,7 @@ impl<'c, 'cc> ConstEvalLateContext<'c, 'cc> {
|
|||
ExprKind::Tup(ref tup) => self.multi(tup).map(Constant::Tuple),
|
||||
ExprKind::Repeat(ref value, _) => {
|
||||
let n = match self.tables.expr_ty(e).sty {
|
||||
ty::TyArray(_, n) => n.assert_usize(self.tcx).expect("array length"),
|
||||
ty::Array(_, n) => n.assert_usize(self.tcx).expect("array length"),
|
||||
_ => span_bug!(e.span, "typeck error"),
|
||||
};
|
||||
self.expr(value).map(|v| Constant::Repeat(Box::new(v), n as u64))
|
||||
|
@ -243,8 +226,8 @@ impl<'c, 'cc> ConstEvalLateContext<'c, 'cc> {
|
|||
Int(value) => {
|
||||
let value = !value;
|
||||
match ty.sty {
|
||||
ty::TyInt(ity) => Some(Int(unsext(self.tcx, value as i128, ity))),
|
||||
ty::TyUint(ity) => Some(Int(clip(self.tcx, value, ity))),
|
||||
ty::Int(ity) => Some(Int(unsext(self.tcx, value as i128, ity))),
|
||||
ty::Uint(ity) => Some(Int(clip(self.tcx, value, ity))),
|
||||
_ => None,
|
||||
}
|
||||
},
|
||||
|
@ -257,7 +240,7 @@ impl<'c, 'cc> ConstEvalLateContext<'c, 'cc> {
|
|||
match *o {
|
||||
Int(value) => {
|
||||
let ity = match ty.sty {
|
||||
ty::TyInt(ity) => ity,
|
||||
ty::Int(ity) => ity,
|
||||
_ => return None,
|
||||
};
|
||||
// sign extend
|
||||
|
@ -336,7 +319,7 @@ impl<'c, 'cc> ConstEvalLateContext<'c, 'cc> {
|
|||
match (l, r) {
|
||||
(Constant::Int(l), Some(Constant::Int(r))) => {
|
||||
match self.tables.expr_ty(left).sty {
|
||||
ty::TyInt(ity) => {
|
||||
ty::Int(ity) => {
|
||||
let l = sext(self.tcx, l, ity);
|
||||
let r = sext(self.tcx, r, ity);
|
||||
let zext = |n: i128| Constant::Int(unsext(self.tcx, n, ity));
|
||||
|
@ -360,7 +343,7 @@ impl<'c, 'cc> ConstEvalLateContext<'c, 'cc> {
|
|||
_ => None,
|
||||
}
|
||||
}
|
||||
ty::TyUint(_) => {
|
||||
ty::Uint(_) => {
|
||||
match op.node {
|
||||
BinOpKind::Add => l.checked_add(r).map(Constant::Int),
|
||||
BinOpKind::Sub => l.checked_sub(r).map(Constant::Int),
|
||||
|
@ -429,18 +412,18 @@ pub fn miri_to_const<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, result: &ty::Const<'
|
|||
use rustc::mir::interpret::{Scalar, ScalarMaybeUndef, ConstValue};
|
||||
match result.val {
|
||||
ConstValue::Scalar(Scalar::Bits{ bits: b, ..}) => match result.ty.sty {
|
||||
ty::TyBool => Some(Constant::Bool(b == 1)),
|
||||
ty::TyUint(_) | ty::TyInt(_) => Some(Constant::Int(b)),
|
||||
ty::TyFloat(FloatTy::F32) => Some(Constant::F32(f32::from_bits(b as u32))),
|
||||
ty::TyFloat(FloatTy::F64) => Some(Constant::F64(f64::from_bits(b as u64))),
|
||||
ty::Bool => Some(Constant::Bool(b == 1)),
|
||||
ty::Uint(_) | ty::Int(_) => Some(Constant::Int(b)),
|
||||
ty::Float(FloatTy::F32) => Some(Constant::F32(f32::from_bits(b as u32))),
|
||||
ty::Float(FloatTy::F64) => Some(Constant::F64(f64::from_bits(b as u64))),
|
||||
// FIXME: implement other conversion
|
||||
_ => None,
|
||||
},
|
||||
ConstValue::ScalarPair(Scalar::Ptr(ptr),
|
||||
ScalarMaybeUndef::Scalar(
|
||||
Scalar::Bits { bits: n, .. })) => match result.ty.sty {
|
||||
ty::TyRef(_, tam, _) => match tam.sty {
|
||||
ty::TyStr => {
|
||||
ty::Ref(_, tam, _) => match tam.sty {
|
||||
ty::Str => {
|
||||
let alloc = tcx
|
||||
.alloc_map
|
||||
.lock()
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use rustc::ty::Ty;
|
||||
use rustc::hir::*;
|
||||
use std::collections::HashMap;
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
use crate::utils::{is_copy, match_path, paths, span_note_and_lint};
|
||||
use rustc::hir::{Item, ItemKind};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
|
||||
/// **What it does:** Checks for types that implement `Copy` as well as
|
||||
/// `Iterator`.
|
||||
///
|
||||
/// **Why is this bad?** Implicit copies can be confusing when working with
|
||||
/// iterator combinators.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// #[derive(Copy, Clone)]
|
||||
/// struct Countdown(u8);
|
||||
///
|
||||
/// impl Iterator for Countdown {
|
||||
/// // ...
|
||||
/// }
|
||||
///
|
||||
/// let a: Vec<_> = my_iterator.take(1).collect();
|
||||
/// let b: Vec<_> = my_iterator.collect();
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
pub COPY_ITERATOR,
|
||||
pedantic,
|
||||
"implementing `Iterator` on a `Copy` type"
|
||||
}
|
||||
|
||||
pub struct CopyIterator;
|
||||
|
||||
impl LintPass for CopyIterator {
|
||||
fn get_lints(&self) -> LintArray {
|
||||
lint_array![COPY_ITERATOR]
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for CopyIterator {
|
||||
fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx Item) {
|
||||
if let ItemKind::Impl(_, _, _, _, Some(ref trait_ref), _, _) = item.node {
|
||||
let ty = cx.tcx.type_of(cx.tcx.hir.local_def_id(item.id));
|
||||
|
||||
if is_copy(cx, ty) && match_path(&trait_ref.path, &paths::ITERATOR) {
|
||||
span_note_and_lint(
|
||||
cx,
|
||||
COPY_ITERATOR,
|
||||
item.span,
|
||||
"you are implementing `Iterator` on a `Copy` type",
|
||||
item.span,
|
||||
"consider implementing `IntoIterator` instead",
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
//! calculate cyclomatic complexity and warn about overly complex functions
|
||||
|
||||
use rustc::cfg::CFG;
|
||||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass, LintContext};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use rustc::hir::*;
|
||||
use rustc::ty;
|
||||
use rustc::hir::intravisit::{walk_expr, NestedVisitorMap, Visitor};
|
||||
|
@ -159,9 +159,9 @@ impl<'a, 'tcx> Visitor<'tcx> for CCHelper<'a, 'tcx> {
|
|||
walk_expr(self, e);
|
||||
let ty = self.cx.tables.node_id_to_type(callee.hir_id);
|
||||
match ty.sty {
|
||||
ty::TyFnDef(..) | ty::TyFnPtr(_) => {
|
||||
ty::FnDef(..) | ty::FnPtr(_) => {
|
||||
let sig = ty.fn_sig(self.cx.tcx);
|
||||
if sig.skip_binder().output().sty == ty::TyNever {
|
||||
if sig.skip_binder().output().sty == ty::Never {
|
||||
self.divergence += 1;
|
||||
}
|
||||
},
|
||||
|
@ -186,7 +186,7 @@ impl<'a, 'tcx> Visitor<'tcx> for CCHelper<'a, 'tcx> {
|
|||
}
|
||||
|
||||
#[cfg(feature = "debugging")]
|
||||
#[allow(too_many_arguments)]
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn report_cc_bug(_: &LateContext<'_, '_>, cc: u64, narms: u64, div: u64, shorts: u64, returns: u64, span: Span, _: NodeId) {
|
||||
span_bug!(
|
||||
span,
|
||||
|
@ -200,7 +200,7 @@ fn report_cc_bug(_: &LateContext<'_, '_>, cc: u64, narms: u64, div: u64, shorts:
|
|||
);
|
||||
}
|
||||
#[cfg(not(feature = "debugging"))]
|
||||
#[allow(too_many_arguments)]
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn report_cc_bug(cx: &LateContext<'_, '_>, cc: u64, narms: u64, div: u64, shorts: u64, returns: u64, span: Span, id: NodeId) {
|
||||
if !is_allowed(cx, CYCLOMATIC_COMPLEXITY, id) {
|
||||
cx.sess().span_note_without_error(
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use rustc::hir::*;
|
||||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use if_chain::if_chain;
|
||||
use rustc::ty::TypeVariants;
|
||||
use rustc::ty::TyKind;
|
||||
|
||||
use crate::utils::{any_parent_is_automatically_derived, match_def_path, opt_def_id, paths, span_lint_and_sugg};
|
||||
|
||||
|
@ -51,7 +51,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for DefaultTraitAccess {
|
|||
// TODO: Work out a way to put "whatever the imported way of referencing
|
||||
// this type in this file" rather than a fully-qualified type.
|
||||
let expr_ty = cx.tables.expr_ty(expr);
|
||||
if let TypeVariants::TyAdt(..) = expr_ty.sty {
|
||||
if let TyKind::Adt(..) = expr_ty.sty {
|
||||
let replacement = format!("{}::default()", expr_ty);
|
||||
span_lint_and_sugg(
|
||||
cx,
|
||||
|
|
|
@ -82,3 +82,13 @@ declare_deprecated_lint! {
|
|||
pub MISALIGNED_TRANSMUTE,
|
||||
"this lint has been split into cast_ptr_alignment and transmute_ptr_to_ptr"
|
||||
}
|
||||
|
||||
/// **What it does:** Nothing. This lint has been deprecated.
|
||||
///
|
||||
/// **Deprecation reason:** This lint is too subjective, not having a good reason for being in clippy.
|
||||
/// Additionally, compound assignment operators may be overloaded separately from their non-assigning
|
||||
/// counterparts, so this lint may suggest a change in behavior or the code may not compile.
|
||||
declare_deprecated_lint! {
|
||||
pub ASSIGN_OPS,
|
||||
"using compound assignment operators (e.g. `+=`) is harmless"
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use if_chain::if_chain;
|
||||
use rustc::ty::{self, Ty};
|
||||
use rustc::hir::*;
|
||||
|
@ -141,18 +141,18 @@ fn check_copy_clone<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, item: &Item, trait_ref
|
|||
}
|
||||
|
||||
match ty.sty {
|
||||
ty::TyAdt(def, _) if def.is_union() => return,
|
||||
ty::Adt(def, _) if def.is_union() => return,
|
||||
|
||||
// Some types are not Clone by default but could be cloned “by hand” if necessary
|
||||
ty::TyAdt(def, substs) => for variant in &def.variants {
|
||||
ty::Adt(def, substs) => for variant in &def.variants {
|
||||
for field in &variant.fields {
|
||||
if let ty::TyFnDef(..) = field.ty(cx.tcx, substs).sty {
|
||||
if let ty::FnDef(..) = field.ty(cx.tcx, substs).sty {
|
||||
return;
|
||||
}
|
||||
}
|
||||
for subst in substs {
|
||||
if let ty::subst::UnpackedKind::Type(subst) = subst.unpack() {
|
||||
if let ty::TyParam(_) = subst.sty {
|
||||
if let ty::Param(_) = subst.sty {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use itertools::Itertools;
|
||||
use pulldown_cmark;
|
||||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use syntax::ast;
|
||||
use syntax::source_map::{BytePos, Span};
|
||||
use syntax_pos::Pos;
|
||||
|
@ -86,7 +86,7 @@ impl<'a> Iterator for Parser<'a> {
|
|||
/// `syntax::parse::lexer::comments::strip_doc_comment_decoration` because we
|
||||
/// need to keep track of
|
||||
/// the spans but this function is inspired from the later.
|
||||
#[allow(cast_possible_truncation)]
|
||||
#[allow(clippy::cast_possible_truncation)]
|
||||
pub fn strip_doc_comment_decoration(comment: &str, span: Span) -> (String, Vec<(usize, Span)>) {
|
||||
// one-line comments lose their prefix
|
||||
const ONELINERS: &[&str] = &["///!", "///", "//!", "//"];
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
//! Lint on unnecessary double comparisons. Some examples:
|
||||
|
||||
use rustc::hir::*;
|
||||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use syntax::source_map::Span;
|
||||
|
||||
use crate::utils::{snippet, span_lint_and_sugg, SpanlessEq};
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use syntax::ast::*;
|
||||
use rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintContext, LintPass};
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
|
||||
/// **What it does:** Checks for unnecessary double parentheses.
|
||||
///
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use if_chain::if_chain;
|
||||
use rustc::ty;
|
||||
use rustc::hir::*;
|
||||
|
@ -128,7 +128,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
|||
let arg = &args[0];
|
||||
let arg_ty = cx.tables.expr_ty(arg);
|
||||
|
||||
if let ty::TyRef(..) = arg_ty.sty {
|
||||
if let ty::Ref(..) = arg_ty.sty {
|
||||
if match_def_path(cx.tcx, def_id, &paths::DROP) {
|
||||
lint = DROP_REF;
|
||||
msg = DROP_REF_SUMMARY.to_string();
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use rustc::hir::*;
|
||||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use if_chain::if_chain;
|
||||
use syntax::source_map::Spanned;
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//! lint on if expressions with an else if, but without a final else branch
|
||||
|
||||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintPass, in_external_macro, LintContext};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use syntax::ast::*;
|
||||
|
||||
use crate::utils::span_lint_and_sugg;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//! lint when there is an enum with no variants
|
||||
|
||||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use rustc::hir::*;
|
||||
use crate::utils::span_lint_and_then;
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use rustc::hir::*;
|
||||
use rustc::hir::intravisit::{walk_expr, NestedVisitorMap, Visitor};
|
||||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use if_chain::if_chain;
|
||||
use syntax::source_map::Span;
|
||||
use crate::utils::SpanlessEq;
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
//! lint on C-like enums that are `repr(isize/usize)` and have values that
|
||||
//! don't fit into an `i32`
|
||||
|
||||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use rustc::hir::*;
|
||||
use rustc::ty;
|
||||
use rustc::ty::subst::Substs;
|
||||
|
@ -43,7 +43,7 @@ impl LintPass for UnportableVariant {
|
|||
}
|
||||
|
||||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnportableVariant {
|
||||
#[allow(cast_possible_truncation, cast_sign_loss)]
|
||||
#[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]
|
||||
fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx Item) {
|
||||
if cx.tcx.data_layout.pointer_size.bits() != 64 {
|
||||
return;
|
||||
|
@ -63,19 +63,19 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnportableVariant {
|
|||
let constant = cx.tcx.const_eval(param_env.and(cid)).ok();
|
||||
if let Some(Constant::Int(val)) = constant.and_then(|c| miri_to_const(cx.tcx, c)) {
|
||||
let mut ty = cx.tcx.type_of(did);
|
||||
if let ty::TyAdt(adt, _) = ty.sty {
|
||||
if let ty::Adt(adt, _) = ty.sty {
|
||||
if adt.is_enum() {
|
||||
ty = adt.repr.discr_type().to_ty(cx.tcx);
|
||||
}
|
||||
}
|
||||
match ty.sty {
|
||||
ty::TyInt(IntTy::Isize) => {
|
||||
ty::Int(IntTy::Isize) => {
|
||||
let val = ((val as i128) << 64) >> 64;
|
||||
if val <= i128::from(i32::max_value()) && val >= i128::from(i32::min_value()) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
ty::TyUint(UintTy::Usize) if val > u128::from(u32::max_value()) => {},
|
||||
ty::Uint(UintTy::Usize) if val > u128::from(u32::max_value()) => {},
|
||||
_ => continue,
|
||||
}
|
||||
span_lint(
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
use rustc::hir::*;
|
||||
use rustc::hir::def::Def;
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use syntax::ast::NodeId;
|
||||
use syntax::source_map::Span;
|
||||
use crate::utils::span_lint;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//! lint on enum variants that are prefixed or suffixed by the same characters
|
||||
|
||||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintPass, Lint};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use syntax::ast::*;
|
||||
use syntax::source_map::Span;
|
||||
use syntax::symbol::LocalInternedString;
|
||||
|
@ -147,7 +147,7 @@ fn partial_rmatch(post: &str, name: &str) -> usize {
|
|||
}
|
||||
|
||||
// FIXME: #600
|
||||
#[allow(while_let_on_iterator)]
|
||||
#[allow(clippy::while_let_on_iterator)]
|
||||
fn check_variant(
|
||||
cx: &EarlyContext<'_>,
|
||||
threshold: u64,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use rustc::hir::*;
|
||||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use crate::utils::{in_macro, implements_trait, is_copy, multispan_sugg, snippet, span_lint, span_lint_and_then, SpanlessEq};
|
||||
|
||||
/// **What it does:** Checks for equal operands to comparison, logical and
|
||||
|
@ -83,7 +83,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EqOp {
|
|||
BinOpKind::Lt | BinOpKind::Le | BinOpKind::Ge | BinOpKind::Gt => (cx.tcx.lang_items().ord_trait(), true),
|
||||
};
|
||||
if let Some(trait_id) = trait_id {
|
||||
#[allow(match_same_arms)]
|
||||
#[allow(clippy::match_same_arms)]
|
||||
match (&left.node, &right.node) {
|
||||
// do not suggest to dereference literals
|
||||
(&ExprKind::Lit(..), _) | (_, &ExprKind::Lit(..)) => {},
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate::consts::{constant_simple, Constant};
|
||||
use rustc::hir::*;
|
||||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use syntax::source_map::Span;
|
||||
use crate::utils::{in_macro, span_lint};
|
||||
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
use rustc::hir::*;
|
||||
use rustc::hir::intravisit as visit;
|
||||
use rustc::hir::map::Node::{NodeExpr, NodeStmt};
|
||||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use rustc::middle::expr_use_visitor::*;
|
||||
use rustc::middle::mem_categorization::{cmt_, Categorization};
|
||||
use rustc::ty::{self, Ty};
|
||||
|
@ -100,7 +99,7 @@ impl<'a, 'tcx> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> {
|
|||
let map = &self.cx.tcx.hir;
|
||||
if map.is_argument(consume_pat.id) {
|
||||
// Skip closure arguments
|
||||
if let Some(NodeExpr(..)) = map.find(map.get_parent_node(consume_pat.id)) {
|
||||
if let Some(Node::Expr(..)) = map.find(map.get_parent_node(consume_pat.id)) {
|
||||
return;
|
||||
}
|
||||
if is_non_trait_box(cmt.ty) && !self.is_large_box(cmt.ty) {
|
||||
|
@ -110,7 +109,7 @@ impl<'a, 'tcx> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> {
|
|||
}
|
||||
if let Categorization::Rvalue(..) = cmt.cat {
|
||||
let id = map.hir_to_node_id(cmt.hir_id);
|
||||
if let Some(NodeStmt(st)) = map.find(map.get_parent_node(id)) {
|
||||
if let Some(Node::Stmt(st)) = map.find(map.get_parent_node(id)) {
|
||||
if let StmtKind::Decl(ref decl, _) = st.node {
|
||||
if let DeclKind::Local(ref loc) = decl.node {
|
||||
if let Some(ref ex) = loc.init {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use rustc::ty;
|
||||
use rustc::hir::*;
|
||||
use crate::utils::{is_adjusted, iter_input_pats, snippet_opt, span_lint_and_then};
|
||||
|
@ -67,9 +67,9 @@ fn check_closure(cx: &LateContext<'_, '_>, expr: &Expr) {
|
|||
let fn_ty = cx.tables.expr_ty(caller);
|
||||
match fn_ty.sty {
|
||||
// Is it an unsafe function? They don't implement the closure traits
|
||||
ty::TyFnDef(..) | ty::TyFnPtr(_) => {
|
||||
ty::FnDef(..) | ty::FnPtr(_) => {
|
||||
let sig = fn_ty.fn_sig(cx.tcx);
|
||||
if sig.skip_binder().unsafety == Unsafety::Unsafe || sig.skip_binder().output().sty == ty::TyNever {
|
||||
if sig.skip_binder().unsafety == Unsafety::Unsafe || sig.skip_binder().output().sty == ty::Never {
|
||||
return;
|
||||
}
|
||||
},
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use rustc::hir::intravisit::{walk_expr, NestedVisitorMap, Visitor};
|
||||
use rustc::hir::*;
|
||||
use rustc::ty;
|
||||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use if_chain::if_chain;
|
||||
use syntax::ast;
|
||||
use crate::utils::{get_parent_expr, span_lint, span_note_and_lint};
|
||||
|
@ -109,7 +109,9 @@ impl<'a, 'tcx> DivergenceVisitor<'a, 'tcx> {
|
|||
self.visit_expr(e);
|
||||
for arm in arms {
|
||||
if let Some(ref guard) = arm.guard {
|
||||
self.visit_expr(guard);
|
||||
match guard {
|
||||
Guard::If(if_expr) => self.visit_expr(if_expr),
|
||||
}
|
||||
}
|
||||
// make sure top level arm expressions aren't linted
|
||||
self.maybe_walk_expr(&*arm.body);
|
||||
|
@ -130,9 +132,9 @@ impl<'a, 'tcx> Visitor<'tcx> for DivergenceVisitor<'a, 'tcx> {
|
|||
ExprKind::Call(ref func, _) => {
|
||||
let typ = self.cx.tables.expr_ty(func);
|
||||
match typ.sty {
|
||||
ty::TyFnDef(..) | ty::TyFnPtr(_) => {
|
||||
ty::FnDef(..) | ty::FnPtr(_) => {
|
||||
let sig = typ.fn_sig(self.cx.tcx);
|
||||
if let ty::TyNever = self.cx.tcx.erase_late_bound_regions(&sig).output().sty {
|
||||
if let ty::Never = self.cx.tcx.erase_late_bound_regions(&sig).output().sty {
|
||||
self.report_diverging_sub_expr(e);
|
||||
}
|
||||
},
|
||||
|
@ -189,9 +191,9 @@ fn check_for_unsequenced_reads(vis: &mut ReadVisitor<'_, '_>) {
|
|||
};
|
||||
|
||||
let stop_early = match parent_node {
|
||||
map::Node::NodeExpr(expr) => check_expr(vis, expr),
|
||||
map::Node::NodeStmt(stmt) => check_stmt(vis, stmt),
|
||||
map::Node::NodeItem(_) => {
|
||||
Node::Expr(expr) => check_expr(vis, expr),
|
||||
Node::Stmt(stmt) => check_stmt(vis, stmt),
|
||||
Node::Item(_) => {
|
||||
// We reached the top of the function, stop.
|
||||
break;
|
||||
},
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use rustc::hir;
|
||||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use if_chain::if_chain;
|
||||
use rustc::ty::TypeVariants;
|
||||
use rustc::ty::TyKind;
|
||||
use std::f32;
|
||||
use std::f64;
|
||||
use std::fmt;
|
||||
|
@ -46,7 +46,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ExcessivePrecision {
|
|||
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr) {
|
||||
if_chain! {
|
||||
let ty = cx.tables.expr_ty(expr);
|
||||
if let TypeVariants::TyFloat(fty) = ty.sty;
|
||||
if let TyKind::Float(fty) = ty.sty;
|
||||
if let hir::ExprKind::Lit(ref lit) = expr.node;
|
||||
if let LitKind::Float(sym, _) | LitKind::FloatUnsuffixed(sym) = lit.node;
|
||||
if let Some(sugg) = self.check(sym, fty);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use rustc::hir::*;
|
||||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use if_chain::if_chain;
|
||||
use crate::utils::{is_expn_of, match_def_path, resolve_node, span_lint};
|
||||
use crate::utils::opt_def_id;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use if_chain::if_chain;
|
||||
use rustc::hir;
|
||||
use rustc::ty;
|
||||
|
@ -130,7 +130,7 @@ fn lint_impl_body<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, impl_span: Span, impl_it
|
|||
|
||||
fn match_type(tcx: ty::TyCtxt<'_, '_, '_>, ty: ty::Ty<'_>, path: &[&str]) -> bool {
|
||||
match ty.sty {
|
||||
ty::TyAdt(adt, _) => match_def_path(tcx, adt.did, path),
|
||||
ty::Adt(adt, _) => match_def_path(tcx, adt.did, path),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use rustc::hir::*;
|
||||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use if_chain::if_chain;
|
||||
use rustc::ty;
|
||||
use syntax::ast::LitKind;
|
||||
|
@ -122,7 +122,7 @@ fn get_single_string_arg(cx: &LateContext<'_, '_>, expr: &Expr) -> Option<Span>
|
|||
if match_def_path(cx.tcx, fun_def_id, &paths::DISPLAY_FMT_METHOD);
|
||||
then {
|
||||
let ty = walk_ptrs_ty(cx.tables.pat_ty(&pat[0]));
|
||||
if ty.sty == ty::TyStr || match_type(cx, ty, &paths::STRING) {
|
||||
if ty.sty == ty::Str || match_type(cx, ty, &paths::STRING) {
|
||||
if let ExprKind::Tup(ref values) = match_expr.node {
|
||||
return Some(values[0].span);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use syntax::ast;
|
||||
use crate::utils::{differing_macro_contexts, in_macro, snippet_opt, span_note_and_lint};
|
||||
use syntax::ptr::P;
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use matches::matches;
|
||||
use rustc::hir::intravisit;
|
||||
use rustc::hir;
|
||||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use rustc::ty;
|
||||
use rustc::hir::def::Def;
|
||||
use std::collections::HashSet;
|
||||
|
@ -85,9 +85,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Functions {
|
|||
span: Span,
|
||||
nodeid: ast::NodeId,
|
||||
) {
|
||||
use rustc::hir::map::Node::*;
|
||||
|
||||
let is_impl = if let Some(NodeItem(item)) = cx.tcx.hir.find(cx.tcx.hir.get_parent_node(nodeid)) {
|
||||
let is_impl = if let Some(hir::Node::Item(item)) = cx.tcx.hir.find(cx.tcx.hir.get_parent_node(nodeid)) {
|
||||
matches!(item.node, hir::ItemKind::Impl(_, _, _, _, Some(_), _, _))
|
||||
} else {
|
||||
false
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use rustc::hir::*;
|
||||
use syntax::ast::NodeId;
|
||||
use crate::utils::{in_macro, match_def_path, match_trait_method, same_tys, snippet, span_lint_and_then};
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate::consts::{constant_simple, Constant};
|
||||
use rustc::hir::*;
|
||||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use syntax::source_map::Span;
|
||||
use crate::utils::{in_macro, snippet, span_lint, unsext, clip};
|
||||
use rustc::ty;
|
||||
|
@ -59,12 +59,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for IdentityOp {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(cast_possible_wrap)]
|
||||
#[allow(clippy::cast_possible_wrap)]
|
||||
fn check(cx: &LateContext<'_, '_>, e: &Expr, m: i8, span: Span, arg: Span) {
|
||||
if let Some(Constant::Int(v)) = constant_simple(cx, cx.tables, e) {
|
||||
let check = match cx.tables.expr_ty(e).sty {
|
||||
ty::TyInt(ity) => unsext(cx.tcx, -1_i128, ity),
|
||||
ty::TyUint(uty) => clip(cx.tcx, !0, uty),
|
||||
ty::Int(ity) => unsext(cx.tcx, -1_i128, ity),
|
||||
ty::Uint(uty) => clip(cx.tcx, !0, uty),
|
||||
_ => return,
|
||||
};
|
||||
if match m {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use rustc::hir::*;
|
||||
use crate::utils::{match_qpath, paths, snippet, span_lint_and_then};
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
//! lint on if branches that could be swapped so no `!` operation is necessary
|
||||
//! on the condition
|
||||
|
||||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintPass, in_external_macro, LintContext};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use syntax::ast::*;
|
||||
|
||||
use crate::utils::span_help_and_lint;
|
||||
|
|
|
@ -5,8 +5,8 @@ use crate::utils;
|
|||
use crate::utils::higher;
|
||||
use crate::utils::higher::Range;
|
||||
use rustc::hir::*;
|
||||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use rustc::ty;
|
||||
use syntax::ast::RangeLimits;
|
||||
|
||||
|
@ -99,7 +99,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for IndexingSlicing {
|
|||
let ty = cx.tables.expr_ty(array);
|
||||
if let Some(range) = higher::range(cx, index) {
|
||||
// Ranged indexes, i.e. &x[n..m], &x[n..], &x[..n] and &x[..]
|
||||
if let ty::TyArray(_, s) = ty.sty {
|
||||
if let ty::Array(_, s) = ty.sty {
|
||||
let size: u128 = s.assert_usize(cx.tcx).unwrap().into();
|
||||
// Index is a constant range.
|
||||
if let Some((start, end)) = to_const_range(cx, range, size) {
|
||||
|
@ -131,7 +131,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for IndexingSlicing {
|
|||
);
|
||||
} else {
|
||||
// Catchall non-range index, i.e. [n] or [n << m]
|
||||
if let ty::TyArray(..) = ty.sty {
|
||||
if let ty::Array(..) = ty.sty {
|
||||
// Index is a constant uint.
|
||||
if let Some(..) = constant(cx, cx.tables, index) {
|
||||
// Let rustc's `const_err` lint handle constant `usize` indexing on arrays.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use super::utils::{get_arg_name, match_var, remove_blocks, snippet, span_lint_and_sugg};
|
||||
use rustc::hir::*;
|
||||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use if_chain::if_chain;
|
||||
|
||||
/// **What it does:** Checks for matches being used to destructure a single-variant enum
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use rustc::hir::*;
|
||||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use crate::utils::{get_trait_def_id, higher, implements_trait, match_qpath, paths, span_lint};
|
||||
|
||||
/// **What it does:** Checks for iteration that is guaranteed to be infinite.
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
//! lint on inherent implementations
|
||||
|
||||
use rustc::hir::*;
|
||||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use std::collections::HashMap;
|
||||
use std::default::Default;
|
||||
use syntax_pos::Span;
|
||||
use crate::utils::span_lint_and_then;
|
||||
|
||||
/// **What it does:** Checks for multiple inherent implementations of a struct
|
||||
///
|
||||
|
@ -81,12 +82,17 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
|||
.map(|(span, _)| span);
|
||||
if let Some(initial_span) = impl_spans.nth(0) {
|
||||
impl_spans.for_each(|additional_span| {
|
||||
cx.span_lint_note(
|
||||
span_lint_and_then(
|
||||
cx,
|
||||
MULTIPLE_INHERENT_IMPL,
|
||||
*additional_span,
|
||||
"Multiple implementations of this structure",
|
||||
*initial_span,
|
||||
"First implementation here",
|
||||
|db| {
|
||||
db.span_note(
|
||||
*initial_span,
|
||||
"First implementation here",
|
||||
);
|
||||
},
|
||||
)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//! checks for `#[inline]` on trait methods without bodies
|
||||
|
||||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use rustc::hir::*;
|
||||
use syntax::ast::{Attribute, Name};
|
||||
use crate::utils::span_lint_and_then;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//! lint on blocks unnecessarily using >= with a + 1 or - 1
|
||||
|
||||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use syntax::ast::*;
|
||||
|
||||
use crate::utils::{snippet_opt, span_lint_and_then};
|
||||
|
@ -53,7 +53,7 @@ enum Side {
|
|||
}
|
||||
|
||||
impl IntPlusOne {
|
||||
#[allow(cast_sign_loss)]
|
||||
#[allow(clippy::cast_sign_loss)]
|
||||
fn check_lit(&self, lit: &Lit, target_value: i128) -> bool {
|
||||
if let LitKind::Int(value, ..) = lit.node {
|
||||
return value == (target_value as u128);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use if_chain::if_chain;
|
||||
use rustc::ty;
|
||||
use rustc::hir::*;
|
||||
|
@ -40,7 +40,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidRef {
|
|||
if let ExprKind::Call(ref path, ref args) = expr.node;
|
||||
if let ExprKind::Path(ref qpath) = path.node;
|
||||
if args.len() == 0;
|
||||
if let ty::TyRef(..) = cx.tables.expr_ty(expr).sty;
|
||||
if let ty::Ref(..) = cx.tables.expr_ty(expr).sty;
|
||||
if let Some(def_id) = opt_def_id(cx.tables.qpath_def(qpath, path.hir_id));
|
||||
then {
|
||||
let msg = if match_def_path(cx.tcx, def_id, &paths::MEM_ZEROED) |
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
//! lint when items are used after statements
|
||||
|
||||
use matches::matches;
|
||||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use syntax::ast::*;
|
||||
use crate::utils::{in_macro, span_lint};
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//! lint when there is a large size difference between variants on an enum
|
||||
|
||||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use rustc::hir::*;
|
||||
use crate::utils::{snippet_opt, span_lint_and_then};
|
||||
use rustc::ty::layout::LayoutOf;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use rustc::hir::def_id::DefId;
|
||||
use rustc::hir::*;
|
||||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use rustc::ty;
|
||||
use std::collections::HashSet;
|
||||
use syntax::ast::{Lit, LitKind, Name};
|
||||
|
@ -265,12 +265,12 @@ fn has_is_empty(cx: &LateContext<'_, '_>, expr: &Expr) -> bool {
|
|||
|
||||
let ty = &walk_ptrs_ty(cx.tables.expr_ty(expr));
|
||||
match ty.sty {
|
||||
ty::TyDynamic(ref tt, ..) => cx.tcx
|
||||
ty::Dynamic(ref tt, ..) => cx.tcx
|
||||
.associated_items(tt.principal().expect("trait impl not found").def_id())
|
||||
.any(|item| is_is_empty(cx, &item)),
|
||||
ty::TyProjection(ref proj) => has_is_empty_impl(cx, proj.item_def_id),
|
||||
ty::TyAdt(id, _) => has_is_empty_impl(cx, id.did),
|
||||
ty::TyArray(..) | ty::TySlice(..) | ty::TyStr => true,
|
||||
ty::Projection(ref proj) => has_is_empty_impl(cx, proj.item_def_id),
|
||||
ty::Adt(id, _) => has_is_empty_impl(cx, id.did),
|
||||
ty::Array(..) | ty::Slice(..) | ty::Str => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use if_chain::if_chain;
|
||||
use rustc::hir;
|
||||
use rustc::hir::BindingAnnotation;
|
||||
|
|
|
@ -5,13 +5,10 @@
|
|||
#![feature(slice_patterns)]
|
||||
#![feature(stmt_expr_attributes)]
|
||||
#![feature(range_contains)]
|
||||
#![feature(macro_vis_matcher)]
|
||||
#![allow(unknown_lints, shadow_reuse, missing_docs_in_private_items)]
|
||||
#![allow(unknown_lints, clippy::shadow_reuse, clippy::missing_docs_in_private_items)]
|
||||
#![recursion_limit = "256"]
|
||||
#![allow(stable_features)]
|
||||
#![feature(iterator_find_map)]
|
||||
#![feature(macro_at_most_once_rep)]
|
||||
#![feature(tool_attributes)]
|
||||
#![feature(tool_lints)]
|
||||
#![warn(rust_2018_idioms)]
|
||||
|
||||
use toml;
|
||||
|
@ -21,40 +18,40 @@ use rustc;
|
|||
|
||||
macro_rules! declare_clippy_lint {
|
||||
{ pub $name:tt, style, $description:tt } => {
|
||||
declare_lint! { pub $name, Warn, $description, report_in_external_macro: true }
|
||||
declare_tool_lint! { pub clippy::$name, Warn, $description, report_in_external_macro: true }
|
||||
};
|
||||
{ pub $name:tt, correctness, $description:tt } => {
|
||||
declare_lint! { pub $name, Deny, $description, report_in_external_macro: true }
|
||||
declare_tool_lint! { pub clippy::$name, Deny, $description, report_in_external_macro: true }
|
||||
};
|
||||
{ pub $name:tt, complexity, $description:tt } => {
|
||||
declare_lint! { pub $name, Warn, $description, report_in_external_macro: true }
|
||||
declare_tool_lint! { pub clippy::$name, Warn, $description, report_in_external_macro: true }
|
||||
};
|
||||
{ pub $name:tt, perf, $description:tt } => {
|
||||
declare_lint! { pub $name, Warn, $description, report_in_external_macro: true }
|
||||
declare_tool_lint! { pub clippy::$name, Warn, $description, report_in_external_macro: true }
|
||||
};
|
||||
{ pub $name:tt, pedantic, $description:tt } => {
|
||||
declare_lint! { pub $name, Allow, $description, report_in_external_macro: true }
|
||||
declare_tool_lint! { pub clippy::$name, Allow, $description, report_in_external_macro: true }
|
||||
};
|
||||
{ pub $name:tt, restriction, $description:tt } => {
|
||||
declare_lint! { pub $name, Allow, $description, report_in_external_macro: true }
|
||||
declare_tool_lint! { pub clippy::$name, Allow, $description, report_in_external_macro: true }
|
||||
};
|
||||
{ pub $name:tt, cargo, $description:tt } => {
|
||||
declare_lint! { pub $name, Allow, $description, report_in_external_macro: true }
|
||||
declare_tool_lint! { pub clippy::$name, Allow, $description, report_in_external_macro: true }
|
||||
};
|
||||
{ pub $name:tt, nursery, $description:tt } => {
|
||||
declare_lint! { pub $name, Allow, $description, report_in_external_macro: true }
|
||||
declare_tool_lint! { pub clippy::$name, Allow, $description, report_in_external_macro: true }
|
||||
};
|
||||
{ pub $name:tt, internal, $description:tt } => {
|
||||
declare_lint! { pub $name, Allow, $description, report_in_external_macro: true }
|
||||
declare_tool_lint! { pub clippy::$name, Allow, $description, report_in_external_macro: true }
|
||||
};
|
||||
{ pub $name:tt, internal_warn, $description:tt } => {
|
||||
declare_lint! { pub $name, Warn, $description, report_in_external_macro: true }
|
||||
declare_tool_lint! { pub clippy::$name, Warn, $description, report_in_external_macro: true }
|
||||
};
|
||||
}
|
||||
|
||||
pub mod consts;
|
||||
mod consts;
|
||||
#[macro_use]
|
||||
pub mod utils;
|
||||
mod utils;
|
||||
|
||||
// begin lints modules, do not remove this comment, it’s used in `update_lints`
|
||||
pub mod approx_const;
|
||||
|
@ -69,6 +66,7 @@ pub mod bytecount;
|
|||
pub mod collapsible_if;
|
||||
pub mod const_static_lifetime;
|
||||
pub mod copies;
|
||||
pub mod copy_iterator;
|
||||
pub mod cyclomatic_complexity;
|
||||
pub mod default_trait_access;
|
||||
pub mod derive;
|
||||
|
@ -145,6 +143,7 @@ pub mod panic_unimplemented;
|
|||
pub mod partialeq_ne_impl;
|
||||
pub mod precedence;
|
||||
pub mod ptr;
|
||||
pub mod ptr_offset_with_cast;
|
||||
pub mod question_mark;
|
||||
pub mod ranges;
|
||||
pub mod redundant_field_names;
|
||||
|
@ -267,6 +266,10 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) {
|
|||
"misaligned_transmute",
|
||||
"this lint has been split into cast_ptr_alignment and transmute_ptr_to_ptr",
|
||||
);
|
||||
store.register_removed(
|
||||
"assign_ops",
|
||||
"using compound assignment operators (e.g. `+=`) is harmless",
|
||||
);
|
||||
// end deprecated lints, do not remove this comment, it’s used in `update_lints`
|
||||
|
||||
reg.register_late_lint_pass(box serde_api::Serde);
|
||||
|
@ -341,6 +344,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) {
|
|||
reg.register_late_lint_pass(box types::InvalidUpcastComparisons);
|
||||
reg.register_late_lint_pass(box regex::Pass::default());
|
||||
reg.register_late_lint_pass(box copies::CopyAndPaste);
|
||||
reg.register_late_lint_pass(box copy_iterator::CopyIterator);
|
||||
reg.register_late_lint_pass(box format::Pass);
|
||||
reg.register_early_lint_pass(box formatting::Formatting);
|
||||
reg.register_late_lint_pass(box swap::Swap);
|
||||
|
@ -406,11 +410,11 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) {
|
|||
reg.register_late_lint_pass(box default_trait_access::DefaultTraitAccess);
|
||||
reg.register_late_lint_pass(box indexing_slicing::IndexingSlicing);
|
||||
reg.register_late_lint_pass(box non_copy_const::NonCopyConst);
|
||||
reg.register_late_lint_pass(box ptr_offset_with_cast::Pass);
|
||||
|
||||
reg.register_lint_group("clippy_restriction", vec![
|
||||
reg.register_lint_group("clippy::restriction", Some("clippy_restriction"), vec![
|
||||
arithmetic::FLOAT_ARITHMETIC,
|
||||
arithmetic::INTEGER_ARITHMETIC,
|
||||
assign_ops::ASSIGN_OPS,
|
||||
else_if_without_else::ELSE_IF_WITHOUT_ELSE,
|
||||
indexing_slicing::INDEXING_SLICING,
|
||||
inherent_impl::MULTIPLE_INHERENT_IMPL,
|
||||
|
@ -431,9 +435,10 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) {
|
|||
write::USE_DEBUG,
|
||||
]);
|
||||
|
||||
reg.register_lint_group("clippy_pedantic", vec![
|
||||
reg.register_lint_group("clippy::pedantic", Some("clippy_pedantic"), vec![
|
||||
attrs::INLINE_ALWAYS,
|
||||
copies::MATCH_SAME_ARMS,
|
||||
copy_iterator::COPY_ITERATOR,
|
||||
default_trait_access::DEFAULT_TRAIT_ACCESS,
|
||||
derive::EXPL_IMPL_CLONE_ON_COPY,
|
||||
doc::DOC_MARKDOWN,
|
||||
|
@ -468,13 +473,13 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) {
|
|||
use_self::USE_SELF,
|
||||
]);
|
||||
|
||||
reg.register_lint_group("clippy_internal", vec![
|
||||
reg.register_lint_group("clippy::internal", Some("clippy_internal"), vec![
|
||||
utils::internal_lints::CLIPPY_LINTS_INTERNAL,
|
||||
utils::internal_lints::LINT_WITHOUT_LINT_PASS,
|
||||
utils::internal_lints::DEFAULT_HASH_TYPES,
|
||||
]);
|
||||
|
||||
reg.register_lint_group("clippy", vec![
|
||||
reg.register_lint_group("clippy::all", Some("clippy"), vec![
|
||||
approx_const::APPROX_CONSTANT,
|
||||
assign_ops::ASSIGN_OP_PATTERN,
|
||||
assign_ops::MISREFACTORED_ASSIGN_OP,
|
||||
|
@ -629,9 +634,11 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) {
|
|||
ptr::CMP_NULL,
|
||||
ptr::MUT_FROM_REF,
|
||||
ptr::PTR_ARG,
|
||||
ptr_offset_with_cast::PTR_OFFSET_WITH_CAST,
|
||||
question_mark::QUESTION_MARK,
|
||||
ranges::ITERATOR_STEP_BY_ZERO,
|
||||
ranges::RANGE_MINUS_ONE,
|
||||
ranges::RANGE_PLUS_ONE,
|
||||
ranges::RANGE_ZIP_WITH_LEN,
|
||||
redundant_field_names::REDUNDANT_FIELD_NAMES,
|
||||
reference::DEREF_ADDROF,
|
||||
|
@ -687,7 +694,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) {
|
|||
zero_div_zero::ZERO_DIVIDED_BY_ZERO,
|
||||
]);
|
||||
|
||||
reg.register_lint_group("clippy_style", vec![
|
||||
reg.register_lint_group("clippy::style", Some("clippy_style"), vec![
|
||||
assign_ops::ASSIGN_OP_PATTERN,
|
||||
bit_mask::VERBOSE_BIT_MASK,
|
||||
blacklisted_name::BLACKLISTED_NAME,
|
||||
|
@ -753,7 +760,6 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) {
|
|||
ptr::CMP_NULL,
|
||||
ptr::PTR_ARG,
|
||||
question_mark::QUESTION_MARK,
|
||||
ranges::RANGE_MINUS_ONE,
|
||||
redundant_field_names::REDUNDANT_FIELD_NAMES,
|
||||
regex::REGEX_MACRO,
|
||||
regex::TRIVIAL_REGEX,
|
||||
|
@ -772,7 +778,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) {
|
|||
write::WRITELN_EMPTY_STRING,
|
||||
]);
|
||||
|
||||
reg.register_lint_group("clippy_complexity", vec![
|
||||
reg.register_lint_group("clippy::complexity", Some("clippy_complexity"), vec![
|
||||
assign_ops::MISREFACTORED_ASSIGN_OP,
|
||||
booleans::NONMINIMAL_BOOL,
|
||||
cyclomatic_complexity::CYCLOMATIC_COMPLEXITY,
|
||||
|
@ -813,6 +819,9 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) {
|
|||
overflow_check_conditional::OVERFLOW_CHECK_CONDITIONAL,
|
||||
partialeq_ne_impl::PARTIALEQ_NE_IMPL,
|
||||
precedence::PRECEDENCE,
|
||||
ptr_offset_with_cast::PTR_OFFSET_WITH_CAST,
|
||||
ranges::RANGE_MINUS_ONE,
|
||||
ranges::RANGE_PLUS_ONE,
|
||||
ranges::RANGE_ZIP_WITH_LEN,
|
||||
reference::DEREF_ADDROF,
|
||||
reference::REF_IN_DEREF,
|
||||
|
@ -837,7 +846,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) {
|
|||
zero_div_zero::ZERO_DIVIDED_BY_ZERO,
|
||||
]);
|
||||
|
||||
reg.register_lint_group("clippy_correctness", vec![
|
||||
reg.register_lint_group("clippy::correctness", Some("clippy_correctness"), vec![
|
||||
approx_const::APPROX_CONSTANT,
|
||||
attrs::DEPRECATED_SEMVER,
|
||||
attrs::USELESS_ATTRIBUTE,
|
||||
|
@ -891,7 +900,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) {
|
|||
unused_io_amount::UNUSED_IO_AMOUNT,
|
||||
]);
|
||||
|
||||
reg.register_lint_group("clippy_perf", vec![
|
||||
reg.register_lint_group("clippy::perf", Some("clippy_perf"), vec![
|
||||
bytecount::NAIVE_BYTECOUNT,
|
||||
entry::MAP_ENTRY,
|
||||
escape::BOXED_LOCAL,
|
||||
|
@ -909,16 +918,15 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) {
|
|||
vec::USELESS_VEC,
|
||||
]);
|
||||
|
||||
reg.register_lint_group("clippy_cargo", vec![
|
||||
reg.register_lint_group("clippy::cargo", Some("clippy_cargo"), vec![
|
||||
multiple_crate_versions::MULTIPLE_CRATE_VERSIONS,
|
||||
]);
|
||||
|
||||
reg.register_lint_group("clippy_nursery", vec![
|
||||
reg.register_lint_group("clippy::nursery", Some("clippy_nursery"), vec![
|
||||
attrs::EMPTY_LINE_AFTER_OUTER_ATTR,
|
||||
fallible_impl_from::FALLIBLE_IMPL_FROM,
|
||||
mutex_atomic::MUTEX_INTEGER,
|
||||
needless_borrow::NEEDLESS_BORROW,
|
||||
ranges::RANGE_PLUS_ONE,
|
||||
unwrap::PANICKING_UNWRAP,
|
||||
unwrap::UNNECESSARY_UNWRAP,
|
||||
]);
|
||||
|
@ -926,7 +934,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) {
|
|||
|
||||
// only exists to let the dogfood integration test works.
|
||||
// Don't run clippy as an executable directly
|
||||
#[allow(dead_code, print_stdout)]
|
||||
#[allow(dead_code, clippy::print_stdout)]
|
||||
fn main() {
|
||||
panic!("Please use the cargo-clippy executable");
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate::reexport::*;
|
||||
use matches::matches;
|
||||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass, in_external_macro, LintContext};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use rustc::hir::def::Def;
|
||||
use rustc::hir::*;
|
||||
use rustc::hir::intravisit::*;
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
//! Lints concerned with the grouping of digits with underscores in integral or
|
||||
//! floating-point literal expressions.
|
||||
|
||||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintPass, in_external_macro, LintContext};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use if_chain::if_chain;
|
||||
use syntax::ast::*;
|
||||
use syntax_pos;
|
||||
|
|
|
@ -4,9 +4,8 @@ use rustc::hir::*;
|
|||
use rustc::hir::def::Def;
|
||||
use rustc::hir::def_id;
|
||||
use rustc::hir::intravisit::{walk_block, walk_decl, walk_expr, walk_pat, walk_stmt, NestedVisitorMap, Visitor};
|
||||
use rustc::hir::map::Node::{NodeBlock, NodeExpr, NodeStmt};
|
||||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass, in_external_macro, LintContext};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use if_chain::if_chain;
|
||||
use rustc::middle::region;
|
||||
// use rustc::middle::region::CodeExtent;
|
||||
|
@ -759,8 +758,8 @@ struct FixedOffsetVar {
|
|||
|
||||
fn is_slice_like<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ty: Ty<'_>) -> bool {
|
||||
let is_slice = match ty.sty {
|
||||
ty::TyRef(_, subty, _) => is_slice_like(cx, subty),
|
||||
ty::TySlice(..) | ty::TyArray(..) => true,
|
||||
ty::Ref(_, subty, _) => is_slice_like(cx, subty),
|
||||
ty::Slice(..) | ty::Array(..) => true,
|
||||
_ => false,
|
||||
};
|
||||
|
||||
|
@ -1149,8 +1148,8 @@ fn check_for_loop_reverse_range<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, arg: &'tcx
|
|||
Constant::Int(start_idx),
|
||||
Constant::Int(end_idx),
|
||||
) => (match ty.sty {
|
||||
ty::TyInt(ity) => sext(cx.tcx, start_idx, ity) > sext(cx.tcx, end_idx, ity),
|
||||
ty::TyUint(_) => start_idx > end_idx,
|
||||
ty::Int(ity) => sext(cx.tcx, start_idx, ity) > sext(cx.tcx, end_idx, ity),
|
||||
ty::Uint(_) => start_idx > end_idx,
|
||||
_ => false,
|
||||
}, start_idx == end_idx),
|
||||
_ => (false, false),
|
||||
|
@ -1239,7 +1238,7 @@ fn check_for_loop_arg(cx: &LateContext<'_, '_>, pat: &Pat, arg: &Expr, expr: &Ex
|
|||
match cx.tables.expr_ty(&args[0]).sty {
|
||||
// If the length is greater than 32 no traits are implemented for array and
|
||||
// therefore we cannot use `&`.
|
||||
ty::TypeVariants::TyArray(_, size) if size.assert_usize(cx.tcx).expect("array size") > 32 => (),
|
||||
ty::TyKind::Array(_, size) if size.assert_usize(cx.tcx).expect("array size") > 32 => (),
|
||||
_ => lint_iter_method(cx, args, arg, method_name),
|
||||
};
|
||||
} else {
|
||||
|
@ -1330,7 +1329,7 @@ fn check_for_loop_explicit_counter<'a, 'tcx>(
|
|||
let parent_scope = map.get_enclosing_scope(expr.id)
|
||||
.and_then(|id| map.get_enclosing_scope(id));
|
||||
if let Some(parent_id) = parent_scope {
|
||||
if let NodeBlock(block) = map.get(parent_id) {
|
||||
if let Node::Block(block) = map.get(parent_id) {
|
||||
for (id, _) in visitor
|
||||
.states
|
||||
.iter()
|
||||
|
@ -1381,7 +1380,7 @@ fn check_for_loop_over_map_kv<'a, 'tcx>(
|
|||
if pat.len() == 2 {
|
||||
let arg_span = arg.span;
|
||||
let (new_pat_span, kind, ty, mutbl) = match cx.tables.expr_ty(arg).sty {
|
||||
ty::TyRef(_, ty, mutbl) => match (&pat[0].node, &pat[1].node) {
|
||||
ty::Ref(_, ty, mutbl) => match (&pat[0].node, &pat[1].node) {
|
||||
(key, _) if pat_is_wild(key, body) => (pat[1].span, "value", ty, mutbl),
|
||||
(_, value) if pat_is_wild(value, body) => (pat[0].span, "key", ty, MutImmutable),
|
||||
_ => return,
|
||||
|
@ -1506,7 +1505,7 @@ fn check_for_mutability(cx: &LateContext<'_, '_>, bound: &Expr) -> Option<NodeId
|
|||
if let Def::Local(node_id) = def {
|
||||
let node_str = cx.tcx.hir.get(node_id);
|
||||
if_chain! {
|
||||
if let map::Node::NodeBinding(pat) = node_str;
|
||||
if let Node::Binding(pat) = node_str;
|
||||
if let PatKind::Binding(bind_ann, _, _, _) = pat.node;
|
||||
if let BindingAnnotation::Mutable = bind_ann;
|
||||
then {
|
||||
|
@ -1721,7 +1720,7 @@ impl<'a, 'tcx> Visitor<'tcx> for VarVisitor<'a, 'tcx> {
|
|||
for expr in args {
|
||||
let ty = self.cx.tables.expr_ty_adjusted(expr);
|
||||
self.prefer_mutable = false;
|
||||
if let ty::TyRef(_, _, mutbl) = ty.sty {
|
||||
if let ty::Ref(_, _, mutbl) = ty.sty {
|
||||
if mutbl == MutMutable {
|
||||
self.prefer_mutable = true;
|
||||
}
|
||||
|
@ -1733,7 +1732,7 @@ impl<'a, 'tcx> Visitor<'tcx> for VarVisitor<'a, 'tcx> {
|
|||
let def_id = self.cx.tables.type_dependent_defs()[expr.hir_id].def_id();
|
||||
for (ty, expr) in self.cx.tcx.fn_sig(def_id).inputs().skip_binder().iter().zip(args) {
|
||||
self.prefer_mutable = false;
|
||||
if let ty::TyRef(_, _, mutbl) = ty.sty {
|
||||
if let ty::Ref(_, _, mutbl) = ty.sty {
|
||||
if mutbl == MutMutable {
|
||||
self.prefer_mutable = true;
|
||||
}
|
||||
|
@ -1814,7 +1813,7 @@ fn is_ref_iterable_type(cx: &LateContext<'_, '_>, e: &Expr) -> bool {
|
|||
fn is_iterable_array(ty: Ty<'_>, cx: &LateContext<'_, '_>) -> bool {
|
||||
// IntoIterator is currently only implemented for array sizes <= 32 in rustc
|
||||
match ty.sty {
|
||||
ty::TyArray(_, n) => (0..=32).contains(&n.assert_usize(cx.tcx).expect("array length")),
|
||||
ty::Array(_, n) => (0..=32).contains(&n.assert_usize(cx.tcx).expect("array length")),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
@ -2047,7 +2046,7 @@ fn is_conditional(expr: &Expr) -> bool {
|
|||
fn is_nested(cx: &LateContext<'_, '_>, match_expr: &Expr, iter_expr: &Expr) -> bool {
|
||||
if_chain! {
|
||||
if let Some(loop_block) = get_enclosing_block(cx, match_expr.id);
|
||||
if let Some(map::Node::NodeExpr(loop_expr)) = cx.tcx.hir.find(cx.tcx.hir.get_parent_node(loop_block.id));
|
||||
if let Some(Node::Expr(loop_expr)) = cx.tcx.hir.find(cx.tcx.hir.get_parent_node(loop_block.id));
|
||||
then {
|
||||
return is_loop_nested(cx, loop_expr, iter_expr)
|
||||
}
|
||||
|
@ -2068,13 +2067,13 @@ fn is_loop_nested(cx: &LateContext<'_, '_>, loop_expr: &Expr, iter_expr: &Expr)
|
|||
return false;
|
||||
}
|
||||
match cx.tcx.hir.find(parent) {
|
||||
Some(NodeExpr(expr)) => match expr.node {
|
||||
Some(Node::Expr(expr)) => match expr.node {
|
||||
ExprKind::Loop(..) | ExprKind::While(..) => {
|
||||
return true;
|
||||
},
|
||||
_ => (),
|
||||
},
|
||||
Some(NodeBlock(block)) => {
|
||||
Some(Node::Block(block)) => {
|
||||
let mut block_visitor = LoopNestVisitor {
|
||||
id,
|
||||
iterator: iter_name,
|
||||
|
@ -2085,7 +2084,7 @@ fn is_loop_nested(cx: &LateContext<'_, '_>, loop_expr: &Expr, iter_expr: &Expr)
|
|||
return false;
|
||||
}
|
||||
},
|
||||
Some(NodeStmt(_)) => (),
|
||||
Some(Node::Stmt(_)) => (),
|
||||
_ => {
|
||||
return false;
|
||||
},
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use if_chain::if_chain;
|
||||
use rustc::hir::*;
|
||||
use rustc::ty;
|
||||
|
@ -54,7 +54,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
|||
walk_ptrs_ty_depth(cx.tables.pat_ty(&first_arg.pat)).1 == 1
|
||||
{
|
||||
// the argument is not an &mut T
|
||||
if let ty::TyRef(_, _, mutbl) = ty.sty {
|
||||
if let ty::Ref(_, _, mutbl) = ty.sty {
|
||||
if mutbl == MutImmutable {
|
||||
span_help_and_lint(cx, MAP_CLONE, expr.span, &format!(
|
||||
"you seem to be using .map() to clone the contents of an {}, consider \
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use rustc::hir;
|
||||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use if_chain::if_chain;
|
||||
use rustc::ty;
|
||||
use rustc_errors::Applicability;
|
||||
|
@ -86,8 +86,8 @@ impl LintPass for Pass {
|
|||
|
||||
fn is_unit_type(ty: ty::Ty<'_>) -> bool {
|
||||
match ty.sty {
|
||||
ty::TyTuple(slice) => slice.is_empty(),
|
||||
ty::TyNever => true,
|
||||
ty::Tuple(slice) => slice.is_empty(),
|
||||
ty::Never => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
@ -95,7 +95,7 @@ fn is_unit_type(ty: ty::Ty<'_>) -> bool {
|
|||
fn is_unit_function(cx: &LateContext<'_, '_>, expr: &hir::Expr) -> bool {
|
||||
let ty = cx.tables.expr_ty(expr);
|
||||
|
||||
if let ty::TyFnDef(id, _) = ty.sty {
|
||||
if let ty::FnDef(id, _) = ty.sty {
|
||||
if let Some(fn_type) = cx.tcx.fn_sig(id).no_late_bound_regions() {
|
||||
return is_unit_type(fn_type.output());
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use rustc::hir::*;
|
||||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass, in_external_macro, LintContext};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use if_chain::if_chain;
|
||||
use rustc::ty::{self, Ty};
|
||||
use std::cmp::Ordering;
|
||||
|
@ -224,7 +224,7 @@ fn check_single_match(cx: &LateContext<'_, '_>, ex: &Expr, arms: &[Arm], expr: &
|
|||
return;
|
||||
};
|
||||
let ty = cx.tables.expr_ty(ex);
|
||||
if ty.sty != ty::TyBool || is_allowed(cx, MATCH_BOOL, ex.id) {
|
||||
if ty.sty != ty::Bool || is_allowed(cx, MATCH_BOOL, ex.id) {
|
||||
check_single_match_single_pattern(cx, ex, arms, expr, els);
|
||||
check_single_match_opt_like(cx, ex, arms, expr, ty, els);
|
||||
}
|
||||
|
@ -295,7 +295,7 @@ fn check_single_match_opt_like(cx: &LateContext<'_, '_>, ex: &Expr, arms: &[Arm]
|
|||
|
||||
fn check_match_bool(cx: &LateContext<'_, '_>, ex: &Expr, arms: &[Arm], expr: &Expr) {
|
||||
// type of expression == bool
|
||||
if cx.tables.expr_ty(ex).sty == ty::TyBool {
|
||||
if cx.tables.expr_ty(ex).sty == ty::Bool {
|
||||
span_lint_and_then(
|
||||
cx,
|
||||
MATCH_BOOL,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use rustc::hir::{Expr, ExprKind};
|
||||
use crate::utils::{match_def_path, opt_def_id, paths, span_lint};
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use matches::matches;
|
||||
use rustc::hir;
|
||||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass, in_external_macro, Lint, LintContext};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use if_chain::if_chain;
|
||||
use rustc::ty::{self, Ty};
|
||||
use rustc::hir::def::Def;
|
||||
|
@ -714,7 +714,7 @@ impl LintPass for Pass {
|
|||
}
|
||||
|
||||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
||||
#[allow(cyclomatic_complexity)]
|
||||
#[allow(clippy::cyclomatic_complexity)]
|
||||
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr) {
|
||||
if in_macro(expr.span) {
|
||||
return;
|
||||
|
@ -784,7 +784,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
|||
}
|
||||
|
||||
match self_ty.sty {
|
||||
ty::TyRef(_, ty, _) if ty.sty == ty::TyStr => for &(method, pos) in &PATTERN_METHODS {
|
||||
ty::Ref(_, ty, _) if ty.sty == ty::Str => for &(method, pos) in &PATTERN_METHODS {
|
||||
if method_call.ident.name == method && args.len() > pos {
|
||||
lint_single_char_pattern(cx, expr, &args[pos]);
|
||||
}
|
||||
|
@ -922,7 +922,7 @@ fn lint_or_fun_call(cx: &LateContext<'_, '_>, expr: &hir::Expr, method_span: Spa
|
|||
}
|
||||
|
||||
/// Check for `*or(foo())`.
|
||||
#[allow(too_many_arguments)]
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn check_general_case(
|
||||
cx: &LateContext<'_, '_>,
|
||||
name: &str,
|
||||
|
@ -1113,8 +1113,8 @@ fn lint_expect_fun_call(cx: &LateContext<'_, '_>, expr: &hir::Expr, method_span:
|
|||
/// Checks for the `CLONE_ON_COPY` lint.
|
||||
fn lint_clone_on_copy(cx: &LateContext<'_, '_>, expr: &hir::Expr, arg: &hir::Expr, arg_ty: Ty<'_>) {
|
||||
let ty = cx.tables.expr_ty(expr);
|
||||
if let ty::TyRef(_, inner, _) = arg_ty.sty {
|
||||
if let ty::TyRef(_, innermost, _) = inner.sty {
|
||||
if let ty::Ref(_, inner, _) = arg_ty.sty {
|
||||
if let ty::Ref(_, innermost, _) = inner.sty {
|
||||
span_lint_and_then(
|
||||
cx,
|
||||
CLONE_DOUBLE_REF,
|
||||
|
@ -1124,7 +1124,7 @@ fn lint_clone_on_copy(cx: &LateContext<'_, '_>, expr: &hir::Expr, arg: &hir::Exp
|
|||
|db| if let Some(snip) = sugg::Sugg::hir_opt(cx, arg) {
|
||||
let mut ty = innermost;
|
||||
let mut n = 0;
|
||||
while let ty::TyRef(_, inner, _) = ty.sty {
|
||||
while let ty::Ref(_, inner, _) = ty.sty {
|
||||
ty = inner;
|
||||
n += 1;
|
||||
}
|
||||
|
@ -1142,17 +1142,17 @@ fn lint_clone_on_copy(cx: &LateContext<'_, '_>, expr: &hir::Expr, arg: &hir::Exp
|
|||
if is_copy(cx, ty) {
|
||||
let snip;
|
||||
if let Some(snippet) = sugg::Sugg::hir_opt(cx, arg) {
|
||||
if let ty::TyRef(..) = cx.tables.expr_ty(arg).sty {
|
||||
if let ty::Ref(..) = cx.tables.expr_ty(arg).sty {
|
||||
let parent = cx.tcx.hir.get_parent_node(expr.id);
|
||||
match cx.tcx.hir.get(parent) {
|
||||
hir::map::NodeExpr(parent) => match parent.node {
|
||||
hir::Node::Expr(parent) => match parent.node {
|
||||
// &*x is a nop, &x.clone() is not
|
||||
hir::ExprKind::AddrOf(..) |
|
||||
// (*x).func() is useless, x.clone().func() can work in case func borrows mutably
|
||||
hir::ExprKind::MethodCall(..) => return,
|
||||
_ => {},
|
||||
}
|
||||
hir::map::NodeStmt(stmt) => {
|
||||
hir::Node::Stmt(stmt) => {
|
||||
if let hir::StmtKind::Decl(ref decl, _) = stmt.node {
|
||||
if let hir::DeclKind::Local(ref loc) = decl.node {
|
||||
if let hir::PatKind::Ref(..) = loc.pat.node {
|
||||
|
@ -1182,7 +1182,7 @@ fn lint_clone_on_copy(cx: &LateContext<'_, '_>, expr: &hir::Expr, arg: &hir::Exp
|
|||
fn lint_clone_on_ref_ptr(cx: &LateContext<'_, '_>, expr: &hir::Expr, arg: &hir::Expr) {
|
||||
let obj_ty = walk_ptrs_ty(cx.tables.expr_ty(arg));
|
||||
|
||||
if let ty::TyAdt(_, subst) = obj_ty.sty {
|
||||
if let ty::Adt(_, 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) {
|
||||
|
@ -1210,7 +1210,7 @@ fn lint_string_extend(cx: &LateContext<'_, '_>, expr: &hir::Expr, args: &[hir::E
|
|||
if let Some(arglists) = method_chain_args(arg, &["chars"]) {
|
||||
let target = &arglists[0][0];
|
||||
let self_ty = walk_ptrs_ty(cx.tables.expr_ty(target));
|
||||
let ref_str = if self_ty.sty == ty::TyStr {
|
||||
let ref_str = if self_ty.sty == ty::Str {
|
||||
""
|
||||
} else if match_type(cx, self_ty, &paths::STRING) {
|
||||
"&"
|
||||
|
@ -1442,11 +1442,11 @@ fn lint_iter_skip_next(cx: &LateContext<'_, '_>, expr: &hir::Expr) {
|
|||
fn derefs_to_slice(cx: &LateContext<'_, '_>, expr: &hir::Expr, ty: Ty<'_>) -> Option<sugg::Sugg<'static>> {
|
||||
fn may_slice(cx: &LateContext<'_, '_>, ty: Ty<'_>) -> bool {
|
||||
match ty.sty {
|
||||
ty::TySlice(_) => true,
|
||||
ty::TyAdt(def, _) if def.is_box() => may_slice(cx, ty.boxed_ty()),
|
||||
ty::TyAdt(..) => match_type(cx, ty, &paths::VEC),
|
||||
ty::TyArray(_, size) => size.assert_usize(cx.tcx).expect("array length") < 32,
|
||||
ty::TyRef(_, inner, _) => may_slice(cx, inner),
|
||||
ty::Slice(_) => true,
|
||||
ty::Adt(def, _) if def.is_box() => may_slice(cx, ty.boxed_ty()),
|
||||
ty::Adt(..) => match_type(cx, ty, &paths::VEC),
|
||||
ty::Array(_, size) => size.assert_usize(cx.tcx).expect("array length") < 32,
|
||||
ty::Ref(_, inner, _) => may_slice(cx, inner),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
@ -1459,9 +1459,9 @@ fn derefs_to_slice(cx: &LateContext<'_, '_>, expr: &hir::Expr, ty: Ty<'_>) -> Op
|
|||
}
|
||||
} else {
|
||||
match ty.sty {
|
||||
ty::TySlice(_) => sugg::Sugg::hir_opt(cx, expr),
|
||||
ty::TyAdt(def, _) if def.is_box() && may_slice(cx, ty.boxed_ty()) => sugg::Sugg::hir_opt(cx, expr),
|
||||
ty::TyRef(_, inner, _) => if may_slice(cx, inner) {
|
||||
ty::Slice(_) => sugg::Sugg::hir_opt(cx, expr),
|
||||
ty::Adt(def, _) if def.is_box() && may_slice(cx, ty.boxed_ty()) => sugg::Sugg::hir_opt(cx, expr),
|
||||
ty::Ref(_, inner, _) => if may_slice(cx, inner) {
|
||||
sugg::Sugg::hir_opt(cx, expr)
|
||||
} else {
|
||||
None
|
||||
|
@ -1812,7 +1812,7 @@ fn lint_chars_cmp(
|
|||
then {
|
||||
let self_ty = walk_ptrs_ty(cx.tables.expr_ty_adjusted(&args[0][0]));
|
||||
|
||||
if self_ty.sty != ty::TyStr {
|
||||
if self_ty.sty != ty::Str {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1939,7 +1939,7 @@ fn lint_asref(cx: &LateContext<'_, '_>, expr: &hir::Expr, call_name: &str, as_re
|
|||
|
||||
/// Given a `Result<T, E>` type, return its error type (`E`).
|
||||
fn get_error_type<'a>(cx: &LateContext<'_, '_>, ty: Ty<'a>) -> Option<Ty<'a>> {
|
||||
if let ty::TyAdt(_, substs) = ty.sty {
|
||||
if let ty::Adt(_, substs) = ty.sty {
|
||||
if match_type(cx, ty, &paths::RESULT) {
|
||||
substs.types().nth(1)
|
||||
} else {
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use crate::consts::{constant_simple, Constant};
|
||||
use crate::utils::{match_def_path, opt_def_id, paths, span_lint};
|
||||
use rustc::hir::*;
|
||||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use std::cmp::Ordering;
|
||||
|
||||
/// **What it does:** Checks for expressions where `std::cmp::min` and `max` are
|
||||
|
|
|
@ -2,8 +2,8 @@ use crate::reexport::*;
|
|||
use matches::matches;
|
||||
use rustc::hir::*;
|
||||
use rustc::hir::intravisit::FnKind;
|
||||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use if_chain::if_chain;
|
||||
use rustc::ty;
|
||||
use syntax::source_map::{ExpnFormat, Span};
|
||||
|
@ -465,7 +465,7 @@ fn is_allowed<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) -> bool {
|
|||
}
|
||||
|
||||
fn is_float(cx: &LateContext<'_, '_>, expr: &Expr) -> bool {
|
||||
matches!(walk_ptrs_ty(cx.tables.expr_ty(expr)).sty, ty::TyFloat(_))
|
||||
matches!(walk_ptrs_ty(cx.tables.expr_ty(expr)).sty, ty::Float(_))
|
||||
}
|
||||
|
||||
fn check_to_owned(cx: &LateContext<'_, '_>, expr: &Expr, other: &Expr) {
|
||||
|
@ -522,7 +522,7 @@ fn check_to_owned(cx: &LateContext<'_, '_>, expr: &Expr, other: &Expr) {
|
|||
let parent_fn = cx.tcx.hir.get_parent(expr.id);
|
||||
let parent_impl = cx.tcx.hir.get_parent(parent_fn);
|
||||
if parent_impl != CRATE_NODE_ID {
|
||||
if let map::NodeItem(item) = cx.tcx.hir.get(parent_impl) {
|
||||
if let Node::Item(item) = cx.tcx.hir.get(parent_impl) {
|
||||
if let ItemKind::Impl(.., Some(ref trait_ref), _, _) = item.node {
|
||||
if trait_ref.path.def.def_id() == partial_eq_trait_id {
|
||||
// we are implementing PartialEq, don't suggest not doing `to_owned`, otherwise
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintPass, LintContext, in_external_macro};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use if_chain::if_chain;
|
||||
use std::collections::HashMap;
|
||||
use std::char;
|
||||
|
|
|
@ -19,13 +19,13 @@
|
|||
//
|
||||
|
||||
use rustc::hir;
|
||||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass, LintContext};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use rustc::ty;
|
||||
use syntax::ast;
|
||||
use syntax::attr;
|
||||
use syntax::source_map::Span;
|
||||
use crate::utils::in_macro;
|
||||
use crate::utils::{span_lint, in_macro};
|
||||
|
||||
/// **What it does:** Warns if there is missing doc for any documentable item
|
||||
/// (public or private).
|
||||
|
@ -87,7 +87,8 @@ impl MissingDoc {
|
|||
.iter()
|
||||
.any(|a| a.is_value_str() && a.name() == "doc");
|
||||
if !has_doc {
|
||||
cx.span_lint(
|
||||
span_lint(
|
||||
cx,
|
||||
MISSING_DOCS_IN_PRIVATE_ITEMS,
|
||||
sp,
|
||||
&format!("missing documentation for {}", desc),
|
||||
|
|
|
@ -10,10 +10,11 @@
|
|||
//
|
||||
|
||||
use rustc::hir;
|
||||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use syntax::ast;
|
||||
use syntax::source_map::Span;
|
||||
use crate::utils::span_lint;
|
||||
|
||||
/// **What it does:** it lints if an exported function, method, trait method with default impl,
|
||||
/// or trait method impl is not `#[inline]`.
|
||||
|
@ -74,7 +75,8 @@ fn check_missing_inline_attrs(cx: &LateContext<'_, '_>,
|
|||
.iter()
|
||||
.any(|a| a.name() == "inline" );
|
||||
if !has_inline {
|
||||
cx.span_lint(
|
||||
span_lint(
|
||||
cx,
|
||||
MISSING_INLINE_IN_PUBLIC_ITEMS,
|
||||
sp,
|
||||
&format!("missing `#[inline]` for {}", desc),
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
//! lint on multiple versions of a crate being used
|
||||
|
||||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use syntax::ast::*;
|
||||
use crate::utils::span_lint;
|
||||
|
||||
use cargo_metadata;
|
||||
use itertools::Itertools;
|
||||
|
@ -43,7 +44,8 @@ impl EarlyLintPass for Pass {
|
|||
let metadata = match cargo_metadata::metadata_deps(None, true) {
|
||||
Ok(metadata) => metadata,
|
||||
Err(_) => {
|
||||
cx.span_lint(
|
||||
span_lint(
|
||||
cx,
|
||||
MULTIPLE_CRATE_VERSIONS,
|
||||
krate.span,
|
||||
"could not read cargo metadata"
|
||||
|
@ -62,7 +64,8 @@ impl EarlyLintPass for Pass {
|
|||
if group.len() > 1 {
|
||||
let versions = group.into_iter().map(|p| p.version).join(", ");
|
||||
|
||||
cx.span_lint(
|
||||
span_lint(
|
||||
cx,
|
||||
MULTIPLE_CRATE_VERSIONS,
|
||||
krate.span,
|
||||
&format!("multiple versions for dependency `{}`: {}", name, versions),
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use rustc::hir;
|
||||
use rustc::hir::intravisit;
|
||||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass, in_external_macro, LintContext};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use rustc::ty;
|
||||
use crate::utils::{higher, span_lint};
|
||||
|
||||
|
@ -71,7 +71,7 @@ impl<'a, 'tcx> intravisit::Visitor<'tcx> for MutVisitor<'a, 'tcx> {
|
|||
expr.span,
|
||||
"generally you want to avoid `&mut &mut _` if possible",
|
||||
);
|
||||
} else if let ty::TyRef(
|
||||
} else if let ty::Ref(
|
||||
_,
|
||||
_,
|
||||
hir::MutMutable,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use rustc::ty::{self, Ty};
|
||||
use rustc::ty::subst::Subst;
|
||||
use rustc::hir::*;
|
||||
|
@ -58,16 +58,16 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnnecessaryMutPassed {
|
|||
|
||||
fn check_arguments<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, arguments: &[Expr], type_definition: Ty<'tcx>, name: &str) {
|
||||
match type_definition.sty {
|
||||
ty::TyFnDef(..) | ty::TyFnPtr(_) => {
|
||||
ty::FnDef(..) | ty::FnPtr(_) => {
|
||||
let parameters = type_definition.fn_sig(cx.tcx).skip_binder().inputs();
|
||||
for (argument, parameter) in arguments.iter().zip(parameters.iter()) {
|
||||
match parameter.sty {
|
||||
ty::TyRef(
|
||||
ty::Ref(
|
||||
_,
|
||||
_,
|
||||
MutImmutable,
|
||||
) |
|
||||
ty::TyRawPtr(ty::TypeAndMut {
|
||||
ty::RawPtr(ty::TypeAndMut {
|
||||
mutbl: MutImmutable,
|
||||
..
|
||||
}) => if let ExprKind::AddrOf(MutMutable, _) = argument.node {
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
//! This lint is **warn** by default
|
||||
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use rustc::ty::{self, Ty};
|
||||
use rustc::hir::Expr;
|
||||
use syntax::ast;
|
||||
|
@ -60,7 +60,7 @@ pub struct MutexAtomic;
|
|||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MutexAtomic {
|
||||
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
|
||||
let ty = cx.tables.expr_ty(expr);
|
||||
if let ty::TyAdt(_, subst) = ty.sty {
|
||||
if let ty::Adt(_, subst) = ty.sty {
|
||||
if match_type(cx, ty, &paths::MUTEX) {
|
||||
let mutex_param = subst.type_at(0);
|
||||
if let Some(atomic_name) = get_atomic_name(mutex_param) {
|
||||
|
@ -70,8 +70,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MutexAtomic {
|
|||
atomic_name
|
||||
);
|
||||
match mutex_param.sty {
|
||||
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),
|
||||
ty::Uint(t) if t != ast::UintTy::Usize => span_lint(cx, MUTEX_INTEGER, expr.span, &msg),
|
||||
ty::Int(t) if t != ast::IntTy::Isize => span_lint(cx, MUTEX_INTEGER, expr.span, &msg),
|
||||
_ => span_lint(cx, MUTEX_ATOMIC, expr.span, &msg),
|
||||
};
|
||||
}
|
||||
|
@ -82,10 +82,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MutexAtomic {
|
|||
|
||||
fn get_atomic_name(ty: Ty<'_>) -> Option<(&'static str)> {
|
||||
match ty.sty {
|
||||
ty::TyBool => Some("AtomicBool"),
|
||||
ty::TyUint(_) => Some("AtomicUsize"),
|
||||
ty::TyInt(_) => Some("AtomicIsize"),
|
||||
ty::TyRawPtr(_) => Some("AtomicPtr"),
|
||||
ty::Bool => Some("AtomicBool"),
|
||||
ty::Uint(_) => Some("AtomicUsize"),
|
||||
ty::Int(_) => Some("AtomicIsize"),
|
||||
ty::RawPtr(_) => Some("AtomicPtr"),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
//!
|
||||
//! This lint is **warn** by default
|
||||
|
||||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use rustc::hir::*;
|
||||
use syntax::ast::LitKind;
|
||||
use syntax::source_map::Spanned;
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
//!
|
||||
//! This lint is **warn** by default
|
||||
|
||||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use if_chain::if_chain;
|
||||
use rustc::hir::{BindingAnnotation, Expr, ExprKind, MutImmutable, Pat, PatKind};
|
||||
use rustc::ty;
|
||||
|
@ -54,7 +54,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessBorrow {
|
|||
return;
|
||||
}
|
||||
if let ExprKind::AddrOf(MutImmutable, ref inner) = e.node {
|
||||
if let ty::TyRef(..) = cx.tables.expr_ty(inner).sty {
|
||||
if let ty::Ref(..) = cx.tables.expr_ty(inner).sty {
|
||||
for adj3 in cx.tables.expr_adjustments(e).windows(3) {
|
||||
if let [Adjustment {
|
||||
kind: Adjust::Deref(_),
|
||||
|
@ -90,9 +90,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessBorrow {
|
|||
}
|
||||
if_chain! {
|
||||
if let PatKind::Binding(BindingAnnotation::Ref, _, name, _) = pat.node;
|
||||
if let ty::TyRef(_, tam, mutbl) = cx.tables.pat_ty(pat).sty;
|
||||
if let ty::Ref(_, tam, mutbl) = cx.tables.pat_ty(pat).sty;
|
||||
if mutbl == MutImmutable;
|
||||
if let ty::TyRef(_, _, mutbl) = tam.sty;
|
||||
if let ty::Ref(_, _, mutbl) = tam.sty;
|
||||
// only lint immutable refs, because borrowed `&mut T` cannot be moved out
|
||||
if mutbl == MutImmutable;
|
||||
then {
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
//!
|
||||
//! This lint is **warn** by default
|
||||
|
||||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use if_chain::if_chain;
|
||||
use rustc::hir::{BindingAnnotation, MutImmutable, Pat, PatKind};
|
||||
use crate::utils::{in_macro, snippet, span_lint_and_then};
|
||||
|
|
|
@ -27,8 +27,8 @@
|
|||
//! ```
|
||||
//!
|
||||
//! This lint is **warn** by default.
|
||||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use syntax::ast;
|
||||
use syntax::source_map::{original_sp, DUMMY_SP};
|
||||
use std::borrow::Cow;
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
use matches::matches;
|
||||
use rustc::hir::*;
|
||||
use rustc::hir::map::*;
|
||||
use rustc::hir::intravisit::FnKind;
|
||||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use if_chain::if_chain;
|
||||
use rustc::ty::{self, RegionKind, TypeFoldable};
|
||||
use rustc::traits;
|
||||
|
@ -90,7 +89,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 let Some(Node::Item(item)) = cx.tcx.hir.find(cx.tcx.hir.get_parent_node(node_id)) {
|
||||
if matches!(item.node, ItemKind::Impl(_, _, _, _, Some(_), _, _) |
|
||||
ItemKind::Trait(..))
|
||||
{
|
||||
|
@ -205,7 +204,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessPassByValue {
|
|||
|
||||
// Dereference suggestion
|
||||
let sugg = |db: &mut DiagnosticBuilder<'_>| {
|
||||
if let ty::TypeVariants::TyAdt(def, ..) = ty.sty {
|
||||
if let ty::TyKind::Adt(def, ..) = ty.sty {
|
||||
if let Some(span) = cx.tcx.hir.span_if_local(def.did) {
|
||||
if cx.param_env.can_type_implement_copy(cx.tcx, ty).is_ok() {
|
||||
db.span_help(span, "consider marking this type as Copy");
|
||||
|
@ -340,7 +339,7 @@ impl<'a, 'tcx> MovedVariablesCtxt<'a, 'tcx> {
|
|||
|
||||
if let Some(node) = self.cx.tcx.hir.find(id) {
|
||||
match node {
|
||||
map::Node::NodeExpr(e) => {
|
||||
Node::Expr(e) => {
|
||||
// `match` and `if let`
|
||||
if let ExprKind::Match(ref c, ..) = e.node {
|
||||
self.spans_need_deref
|
||||
|
@ -350,7 +349,7 @@ impl<'a, 'tcx> MovedVariablesCtxt<'a, 'tcx> {
|
|||
}
|
||||
},
|
||||
|
||||
map::Node::NodeStmt(s) => {
|
||||
Node::Stmt(s) => {
|
||||
// `let <pat> = x;`
|
||||
if_chain! {
|
||||
if let StmtKind::Decl(ref decl, _) = s.node;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use rustc::ty;
|
||||
use rustc::hir::{Expr, ExprKind};
|
||||
use crate::utils::span_lint;
|
||||
|
@ -35,7 +35,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
|||
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
|
||||
if let ExprKind::Struct(_, ref fields, Some(ref base)) = expr.node {
|
||||
let ty = cx.tables.expr_ty(expr);
|
||||
if let ty::TyAdt(def, _) = ty.sty {
|
||||
if let ty::Adt(def, _) = ty.sty {
|
||||
if fields.len() == def.non_enum_variant().fields.len() {
|
||||
span_lint(
|
||||
cx,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use rustc::hir::*;
|
||||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass, in_external_macro, LintContext};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use if_chain::if_chain;
|
||||
|
||||
use crate::utils::{self, paths, span_lint};
|
||||
|
@ -20,7 +20,7 @@ use crate::utils::{self, paths, span_lint};
|
|||
///
|
||||
/// ```rust
|
||||
/// use std::cmp::Ordering;
|
||||
///
|
||||
///
|
||||
/// // Bad
|
||||
/// let a = 1.0;
|
||||
/// let b = std::f64::NAN;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use rustc::hir::*;
|
||||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use if_chain::if_chain;
|
||||
use syntax::source_map::{Span, Spanned};
|
||||
|
||||
|
@ -32,7 +32,7 @@ impl LintPass for NegMultiply {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(match_same_arms)]
|
||||
#[allow(clippy::match_same_arms)]
|
||||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NegMultiply {
|
||||
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) {
|
||||
if let ExprKind::Binary(Spanned { node: BinOpKind::Mul, .. }, ref l, ref r) = e.node {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use rustc::hir::def_id::DefId;
|
||||
use rustc::hir;
|
||||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass, in_external_macro, LintContext};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use if_chain::if_chain;
|
||||
use rustc::ty::{self, Ty};
|
||||
use syntax::source_map::Span;
|
||||
|
@ -21,7 +21,7 @@ use crate::utils::sugg::DiagnosticBuilderExt;
|
|||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// ```rust,ignore
|
||||
/// ```rust
|
||||
/// struct Foo(Bar);
|
||||
///
|
||||
/// impl Foo {
|
||||
|
@ -63,7 +63,7 @@ declare_clippy_lint! {
|
|||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// ```rust,ignore
|
||||
/// ```rust
|
||||
/// struct Foo;
|
||||
///
|
||||
/// impl Foo {
|
||||
|
@ -169,7 +169,7 @@ fn create_new_without_default_suggest_msg(ty: Ty<'_>) -> String {
|
|||
|
||||
fn can_derive_default<'t, 'c>(ty: Ty<'t>, cx: &LateContext<'c, 't>, default_trait_id: DefId) -> Option<Span> {
|
||||
match ty.sty {
|
||||
ty::TyAdt(adt_def, substs) if adt_def.is_struct() => {
|
||||
ty::Adt(adt_def, substs) if adt_def.is_struct() => {
|
||||
for field in adt_def.all_fields() {
|
||||
let f_ty = field.ty(cx.tcx, substs);
|
||||
if !implements_trait(cx, f_ty, default_trait_id, &[]) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use rustc::hir::def::Def;
|
||||
use rustc::hir::{BinOpKind, BlockCheckMode, Expr, ExprKind, Stmt, StmtKind, UnsafeSource};
|
||||
use crate::utils::{has_drop, in_macro, snippet_opt, span_lint, span_lint_and_sugg};
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
//! This lint is **deny** by default.
|
||||
|
||||
use rustc::lint::{LateContext, LateLintPass, Lint, LintArray, LintPass};
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use rustc::hir::*;
|
||||
use rustc::hir::def::Def;
|
||||
use rustc::ty::{self, TypeFlags};
|
||||
|
@ -212,7 +212,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonCopyConst {
|
|||
if parent_id == cur_expr.id {
|
||||
break;
|
||||
}
|
||||
if let Some(map::NodeExpr(parent_expr)) = cx.tcx.hir.find(parent_id) {
|
||||
if let Some(Node::Expr(parent_expr)) = cx.tcx.hir.find(parent_id) {
|
||||
match &parent_expr.node {
|
||||
ExprKind::AddrOf(..) => {
|
||||
// `&e` => `e` must be referenced
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{LintArray, LintPass, EarlyContext, EarlyLintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use syntax::source_map::Span;
|
||||
use syntax::symbol::LocalInternedString;
|
||||
use syntax::ast::*;
|
||||
|
@ -114,6 +114,9 @@ impl<'a, 'tcx: 'a, 'b> Visitor<'tcx> for SimilarNamesNameVisitor<'a, 'tcx, 'b> {
|
|||
_ => walk_pat(self, pat),
|
||||
}
|
||||
}
|
||||
fn visit_mac(&mut self, _mac: &Mac) {
|
||||
// do not check macs
|
||||
}
|
||||
}
|
||||
|
||||
fn get_whitelist(interned_name: &str) -> Option<&'static [&'static str]> {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use if_chain::if_chain;
|
||||
use rustc::hir::*;
|
||||
use crate::utils::{match_type, method_chain_args, paths, snippet, span_help_and_lint};
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use rustc::hir::{Expr, ExprKind};
|
||||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use syntax::ast::LitKind;
|
||||
use syntax::source_map::{Span, Spanned};
|
||||
use crate::utils::{match_type, paths, span_lint, walk_ptrs_ty};
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use if_chain::if_chain;
|
||||
use rustc::hir::*;
|
||||
use crate::utils::{span_lint, SpanlessEq};
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use rustc::hir::*;
|
||||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use if_chain::if_chain;
|
||||
use syntax::ast::LitKind;
|
||||
use syntax::ptr::P;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use if_chain::if_chain;
|
||||
use rustc::hir::*;
|
||||
use crate::utils::{is_automatically_derived, span_lint};
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use syntax::ast::*;
|
||||
use syntax::source_map::Spanned;
|
||||
use crate::utils::{in_macro, snippet, span_lint_and_sugg};
|
||||
|
|
|
@ -2,10 +2,9 @@
|
|||
|
||||
use std::borrow::Cow;
|
||||
use rustc::hir::*;
|
||||
use rustc::hir::map::NodeItem;
|
||||
use rustc::hir::QPath;
|
||||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use if_chain::if_chain;
|
||||
use rustc::ty;
|
||||
use syntax::ast::NodeId;
|
||||
|
@ -112,7 +111,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for PointerPass {
|
|||
|
||||
fn check_impl_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx ImplItem) {
|
||||
if let ImplItemKind::Method(ref sig, body_id) = item.node {
|
||||
if let Some(NodeItem(it)) = cx.tcx.hir.find(cx.tcx.hir.get_parent(item.id)) {
|
||||
if let Some(Node::Item(it)) = cx.tcx.hir.find(cx.tcx.hir.get_parent(item.id)) {
|
||||
if let ItemKind::Impl(_, _, _, _, Some(_), _, _) = it.node {
|
||||
return; // ignore trait impls
|
||||
}
|
||||
|
@ -152,7 +151,7 @@ fn check_fn(cx: &LateContext<'_, '_>, decl: &FnDecl, fn_id: NodeId, opt_body_id:
|
|||
let fn_ty = sig.skip_binder();
|
||||
|
||||
for (idx, (arg, ty)) in decl.inputs.iter().zip(fn_ty.inputs()).enumerate() {
|
||||
if let ty::TyRef(
|
||||
if let ty::Ref(
|
||||
_,
|
||||
ty,
|
||||
MutImmutable
|
||||
|
|
|
@ -0,0 +1,151 @@
|
|||
use rustc::{declare_tool_lint, hir, lint, lint_array};
|
||||
use crate::utils;
|
||||
use std::fmt;
|
||||
|
||||
/// **What it does:** Checks for usage of the `offset` pointer method with a `usize` casted to an
|
||||
/// `isize`.
|
||||
///
|
||||
/// **Why is this bad?** If we’re always increasing the pointer address, we can avoid the numeric
|
||||
/// cast by using the `add` method instead.
|
||||
///
|
||||
/// **Known problems:** None
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// let vec = vec![b'a', b'b', b'c'];
|
||||
/// let ptr = vec.as_ptr();
|
||||
/// let offset = 1_usize;
|
||||
///
|
||||
/// unsafe { ptr.offset(offset as isize); }
|
||||
/// ```
|
||||
///
|
||||
/// Could be written:
|
||||
///
|
||||
/// ```rust
|
||||
/// let vec = vec![b'a', b'b', b'c'];
|
||||
/// let ptr = vec.as_ptr();
|
||||
/// let offset = 1_usize;
|
||||
///
|
||||
/// unsafe { ptr.add(offset); }
|
||||
/// ```
|
||||
declare_clippy_lint! {
|
||||
pub PTR_OFFSET_WITH_CAST,
|
||||
complexity,
|
||||
"uneeded pointer offset cast"
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct Pass;
|
||||
|
||||
impl lint::LintPass for Pass {
|
||||
fn get_lints(&self) -> lint::LintArray {
|
||||
lint_array!(PTR_OFFSET_WITH_CAST)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> lint::LateLintPass<'a, 'tcx> for Pass {
|
||||
fn check_expr(&mut self, cx: &lint::LateContext<'a, 'tcx>, expr: &'tcx hir::Expr) {
|
||||
// Check if the expressions is a ptr.offset or ptr.wrapping_offset method call
|
||||
let (receiver_expr, arg_expr, method) = match expr_as_ptr_offset_call(cx, expr) {
|
||||
Some(call_arg) => call_arg,
|
||||
None => return,
|
||||
};
|
||||
|
||||
// Check if the argument to the method call is a cast from usize
|
||||
let cast_lhs_expr = match expr_as_cast_from_usize(cx, arg_expr) {
|
||||
Some(cast_lhs_expr) => cast_lhs_expr,
|
||||
None => return,
|
||||
};
|
||||
|
||||
let msg = format!("use of `{}` with a `usize` casted to an `isize`", method);
|
||||
if let Some(sugg) = build_suggestion(cx, method, receiver_expr, cast_lhs_expr) {
|
||||
utils::span_lint_and_sugg(cx, PTR_OFFSET_WITH_CAST, expr.span, &msg, "try", sugg);
|
||||
} else {
|
||||
utils::span_lint(cx, PTR_OFFSET_WITH_CAST, expr.span, &msg);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// If the given expression is a cast from a usize, return the lhs of the cast
|
||||
fn expr_as_cast_from_usize<'a, 'tcx>(
|
||||
cx: &lint::LateContext<'a, 'tcx>,
|
||||
expr: &'tcx hir::Expr,
|
||||
) -> Option<&'tcx hir::Expr> {
|
||||
if let hir::ExprKind::Cast(ref cast_lhs_expr, _) = expr.node {
|
||||
if is_expr_ty_usize(cx, &cast_lhs_expr) {
|
||||
return Some(cast_lhs_expr);
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
// If the given expression is a ptr::offset or ptr::wrapping_offset method call, return the
|
||||
// receiver, the arg of the method call, and the method.
|
||||
fn expr_as_ptr_offset_call<'a, 'tcx>(
|
||||
cx: &lint::LateContext<'a, 'tcx>,
|
||||
expr: &'tcx hir::Expr,
|
||||
) -> Option<(&'tcx hir::Expr, &'tcx hir::Expr, Method)> {
|
||||
if let hir::ExprKind::MethodCall(ref path_segment, _, ref args) = expr.node {
|
||||
if is_expr_ty_raw_ptr(cx, &args[0]) {
|
||||
if path_segment.ident.name == "offset" {
|
||||
return Some((&args[0], &args[1], Method::Offset));
|
||||
}
|
||||
if path_segment.ident.name == "wrapping_offset" {
|
||||
return Some((&args[0], &args[1], Method::WrappingOffset));
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
// Is the type of the expression a usize?
|
||||
fn is_expr_ty_usize<'a, 'tcx>(
|
||||
cx: &lint::LateContext<'a, 'tcx>,
|
||||
expr: &hir::Expr,
|
||||
) -> bool {
|
||||
cx.tables.expr_ty(expr) == cx.tcx.types.usize
|
||||
}
|
||||
|
||||
// Is the type of the expression a raw pointer?
|
||||
fn is_expr_ty_raw_ptr<'a, 'tcx>(
|
||||
cx: &lint::LateContext<'a, 'tcx>,
|
||||
expr: &hir::Expr,
|
||||
) -> bool {
|
||||
cx.tables.expr_ty(expr).is_unsafe_ptr()
|
||||
}
|
||||
|
||||
fn build_suggestion<'a, 'tcx>(
|
||||
cx: &lint::LateContext<'a, 'tcx>,
|
||||
method: Method,
|
||||
receiver_expr: &hir::Expr,
|
||||
cast_lhs_expr: &hir::Expr,
|
||||
) -> Option<String> {
|
||||
let receiver = utils::snippet_opt(cx, receiver_expr.span)?;
|
||||
let cast_lhs = utils::snippet_opt(cx, cast_lhs_expr.span)?;
|
||||
Some(format!("{}.{}({})", receiver, method.suggestion(), cast_lhs))
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
enum Method {
|
||||
Offset,
|
||||
WrappingOffset,
|
||||
}
|
||||
|
||||
impl Method {
|
||||
fn suggestion(self) -> &'static str {
|
||||
match self {
|
||||
Method::Offset => "add",
|
||||
Method::WrappingOffset => "wrapping_add",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Method {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Method::Offset => write!(f, "offset"),
|
||||
Method::WrappingOffset => write!(f, "wrapping_offset"),
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
use rustc::lint::*;
|
||||
use rustc::{declare_lint, lint_array};
|
||||
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
||||
use rustc::{declare_tool_lint, lint_array};
|
||||
use if_chain::if_chain;
|
||||
use rustc::hir::*;
|
||||
use rustc::hir::def::Def;
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue