Rustup
This commit is contained in:
30
Cargo.lock
generated
30
Cargo.lock
generated
@@ -9,8 +9,8 @@ dependencies = [
|
|||||||
"quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_derive 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_derive 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
@@ -61,8 +61,8 @@ name = "cargo_metadata"
|
|||||||
version = "0.2.3"
|
version = "0.2.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_derive 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_derive 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_json 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_json 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -82,8 +82,8 @@ dependencies = [
|
|||||||
"duct 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"duct 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_derive 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_derive 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -289,22 +289,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.12"
|
version = "1.0.14"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.12"
|
version = "1.0.14"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
"quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_derive_internals 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_derive_internals 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_derive_internals"
|
name = "serde_derive_internals"
|
||||||
version = "0.15.1"
|
version = "0.16.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@@ -319,7 +319,7 @@ dependencies = [
|
|||||||
"dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"itoa 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"itoa 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -364,7 +364,7 @@ name = "toml"
|
|||||||
version = "0.4.5"
|
version = "0.4.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -442,9 +442,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
"checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
|
"checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
|
||||||
"checksum semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a3186ec9e65071a2095434b1f5bb24838d4e8e130f584c790f6033c79943537"
|
"checksum semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a3186ec9e65071a2095434b1f5bb24838d4e8e130f584c790f6033c79943537"
|
||||||
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
||||||
"checksum serde 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)" = "7f61b753dd58ec5d4c735f794dbddde1f28b977f652afbcde89d75bc77902216"
|
"checksum serde 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)" = "bcb6a7637a47663ee073391a139ed07851f27ed2532c2abc88c6bf27a16cdf34"
|
||||||
"checksum serde_derive 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)" = "2a169fa5384d751ada1da9f3992b81830151a03c875e40dcb37c9fb31aafc68f"
|
"checksum serde_derive 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)" = "812ff66056fd9a9a5b7c119714243b0862cf98340e7d4b5ee05a932c40d5ea6c"
|
||||||
"checksum serde_derive_internals 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)" = "37aee4e0da52d801acfbc0cc219eb1eda7142112339726e427926a6f6ee65d3a"
|
"checksum serde_derive_internals 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bd381f6d01a6616cdba8530492d453b7761b456ba974e98768a18cad2cd76f58"
|
||||||
"checksum serde_json 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d243424e06f9f9c39e3cd36147470fd340db785825e367625f79298a6ac6b7ac"
|
"checksum serde_json 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d243424e06f9f9c39e3cd36147470fd340db785825e367625f79298a6ac6b7ac"
|
||||||
"checksum shared_child 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "099b38928dbe4a0a01fcd8c233183072f14a7d126a34bed05880869be66e14cc"
|
"checksum shared_child 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "099b38928dbe4a0a01fcd8c233183072f14a7d126a34bed05880869be66e14cc"
|
||||||
"checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad"
|
"checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad"
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ use rustc::ty::{self, TyCtxt};
|
|||||||
use semver::Version;
|
use semver::Version;
|
||||||
use syntax::ast::{Attribute, Lit, LitKind, MetaItemKind, NestedMetaItem, NestedMetaItemKind};
|
use syntax::ast::{Attribute, Lit, LitKind, MetaItemKind, NestedMetaItem, NestedMetaItemKind};
|
||||||
use syntax::codemap::Span;
|
use syntax::codemap::Span;
|
||||||
use utils::{in_macro, match_def_path, paths, snippet_opt, span_lint, span_lint_and_then};
|
use utils::{in_macro, match_def_path, paths, snippet_opt, span_lint, span_lint_and_then, opt_def_id};
|
||||||
|
|
||||||
/// **What it does:** Checks for items annotated with `#[inline(always)]`,
|
/// **What it does:** Checks for items annotated with `#[inline(always)]`,
|
||||||
/// unless the annotated function is empty or simply panics.
|
/// unless the annotated function is empty or simply panics.
|
||||||
@@ -211,8 +211,11 @@ fn is_relevant_expr(tcx: TyCtxt, tables: &ty::TypeckTables, expr: &Expr) -> bool
|
|||||||
ExprRet(Some(ref e)) => is_relevant_expr(tcx, tables, e),
|
ExprRet(Some(ref e)) => is_relevant_expr(tcx, tables, e),
|
||||||
ExprRet(None) | ExprBreak(_, None) => false,
|
ExprRet(None) | ExprBreak(_, None) => false,
|
||||||
ExprCall(ref path_expr, _) => if let ExprPath(ref qpath) = path_expr.node {
|
ExprCall(ref path_expr, _) => if let ExprPath(ref qpath) = path_expr.node {
|
||||||
let fun_id = tables.qpath_def(qpath, path_expr.hir_id).def_id();
|
if let Some(fun_id) = opt_def_id(tables.qpath_def(qpath, path_expr.hir_id)) {
|
||||||
!match_def_path(tcx, fun_id, &paths::BEGIN_PANIC)
|
!match_def_path(tcx, fun_id, &paths::BEGIN_PANIC)
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
true
|
true
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use rustc::lint::*;
|
use rustc::lint::*;
|
||||||
use rustc::ty;
|
use rustc::ty;
|
||||||
use rustc::hir::*;
|
use rustc::hir::*;
|
||||||
use utils::{is_copy, match_def_path, paths, span_note_and_lint};
|
use utils::{is_copy, match_def_path, paths, span_note_and_lint, opt_def_id};
|
||||||
|
|
||||||
/// **What it does:** Checks for calls to `std::mem::drop` with a reference
|
/// **What it does:** Checks for calls to `std::mem::drop` with a reference
|
||||||
/// instead of an owned value.
|
/// instead of an owned value.
|
||||||
@@ -119,8 +119,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
|||||||
let ExprCall(ref path, ref args) = expr.node,
|
let ExprCall(ref path, ref args) = expr.node,
|
||||||
let ExprPath(ref qpath) = path.node,
|
let ExprPath(ref qpath) = path.node,
|
||||||
args.len() == 1,
|
args.len() == 1,
|
||||||
|
let Some(def_id) = opt_def_id(cx.tables.qpath_def(qpath, path.hir_id)),
|
||||||
], {
|
], {
|
||||||
let def_id = cx.tables.qpath_def(qpath, path.hir_id).def_id();
|
|
||||||
let lint;
|
let lint;
|
||||||
let msg;
|
let msg;
|
||||||
let arg = &args[0];
|
let arg = &args[0];
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
use rustc::hir::def_id::DefId;
|
|
||||||
use rustc::hir::intravisit::{walk_expr, NestedVisitorMap, Visitor};
|
use rustc::hir::intravisit::{walk_expr, NestedVisitorMap, Visitor};
|
||||||
use rustc::hir::*;
|
use rustc::hir::*;
|
||||||
use rustc::ty;
|
use rustc::ty;
|
||||||
use rustc::lint::*;
|
use rustc::lint::*;
|
||||||
|
use syntax::ast;
|
||||||
use utils::{get_parent_expr, span_lint, span_note_and_lint};
|
use utils::{get_parent_expr, span_lint, span_note_and_lint};
|
||||||
|
|
||||||
/// **What it does:** Checks for a read and a write to the same variable where
|
/// **What it does:** Checks for a read and a write to the same variable where
|
||||||
@@ -65,14 +65,15 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EvalOrderDependence {
|
|||||||
ExprAssign(ref lhs, _) | ExprAssignOp(_, ref lhs, _) => if let ExprPath(ref qpath) = lhs.node {
|
ExprAssign(ref lhs, _) | ExprAssignOp(_, ref lhs, _) => if let ExprPath(ref qpath) = lhs.node {
|
||||||
if let QPath::Resolved(_, ref path) = *qpath {
|
if let QPath::Resolved(_, ref path) = *qpath {
|
||||||
if path.segments.len() == 1 {
|
if path.segments.len() == 1 {
|
||||||
let var = cx.tables.qpath_def(qpath, lhs.hir_id).def_id();
|
if let def::Def::Local(var) = cx.tables.qpath_def(qpath, lhs.hir_id) {
|
||||||
let mut visitor = ReadVisitor {
|
let mut visitor = ReadVisitor {
|
||||||
cx: cx,
|
cx: cx,
|
||||||
var: var,
|
var: var,
|
||||||
write_expr: expr,
|
write_expr: expr,
|
||||||
last_expr: expr,
|
last_expr: expr,
|
||||||
};
|
};
|
||||||
check_for_unsequenced_reads(&mut visitor);
|
check_for_unsequenced_reads(&mut visitor);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -280,7 +281,7 @@ fn check_stmt<'a, 'tcx>(vis: &mut ReadVisitor<'a, 'tcx>, stmt: &'tcx Stmt) -> St
|
|||||||
struct ReadVisitor<'a, 'tcx: 'a> {
|
struct ReadVisitor<'a, 'tcx: 'a> {
|
||||||
cx: &'a LateContext<'a, 'tcx>,
|
cx: &'a LateContext<'a, 'tcx>,
|
||||||
/// The id of the variable we're looking for.
|
/// The id of the variable we're looking for.
|
||||||
var: DefId,
|
var: ast::NodeId,
|
||||||
/// The expressions where the write to the variable occurred (for reporting
|
/// The expressions where the write to the variable occurred (for reporting
|
||||||
/// in the lint).
|
/// in the lint).
|
||||||
write_expr: &'tcx Expr,
|
write_expr: &'tcx Expr,
|
||||||
@@ -297,22 +298,23 @@ impl<'a, 'tcx> Visitor<'tcx> for ReadVisitor<'a, 'tcx> {
|
|||||||
|
|
||||||
match expr.node {
|
match expr.node {
|
||||||
ExprPath(ref qpath) => {
|
ExprPath(ref qpath) => {
|
||||||
if let QPath::Resolved(None, ref path) = *qpath {
|
if_let_chain! {[
|
||||||
if path.segments.len() == 1 && self.cx.tables.qpath_def(qpath, expr.hir_id).def_id() == self.var {
|
let QPath::Resolved(None, ref path) = *qpath,
|
||||||
if is_in_assignment_position(self.cx, expr) {
|
path.segments.len() == 1,
|
||||||
// This is a write, not a read.
|
let def::Def::Local(local_id) = self.cx.tables.qpath_def(qpath, expr.hir_id),
|
||||||
} else {
|
local_id == self.var,
|
||||||
span_note_and_lint(
|
// Check that this is a read, not a write.
|
||||||
self.cx,
|
!is_in_assignment_position(self.cx, expr),
|
||||||
EVAL_ORDER_DEPENDENCE,
|
], {
|
||||||
expr.span,
|
span_note_and_lint(
|
||||||
"unsequenced read of a variable",
|
self.cx,
|
||||||
self.write_expr.span,
|
EVAL_ORDER_DEPENDENCE,
|
||||||
"whether read occurs before this write depends on evaluation order"
|
expr.span,
|
||||||
);
|
"unsequenced read of a variable",
|
||||||
}
|
self.write_expr.span,
|
||||||
}
|
"whether read occurs before this write depends on evaluation order"
|
||||||
}
|
);
|
||||||
|
}}
|
||||||
}
|
}
|
||||||
// We're about to descend a closure. Since we don't know when (or
|
// We're about to descend a closure. Since we don't know when (or
|
||||||
// if) the closure will be evaluated, any reads in it might not
|
// if) the closure will be evaluated, any reads in it might not
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use rustc::ty;
|
|||||||
use syntax::ast::LitKind;
|
use syntax::ast::LitKind;
|
||||||
use syntax::symbol::InternedString;
|
use syntax::symbol::InternedString;
|
||||||
use utils::paths;
|
use utils::paths;
|
||||||
use utils::{is_expn_of, match_def_path, match_type, resolve_node, span_lint, walk_ptrs_ty};
|
use utils::{is_expn_of, match_def_path, match_type, resolve_node, span_lint, walk_ptrs_ty, opt_def_id};
|
||||||
|
|
||||||
/// **What it does:** Checks for the use of `format!("string literal with no
|
/// **What it does:** Checks for the use of `format!("string literal with no
|
||||||
/// argument")` and `format!("{}", foo)` where `foo` is a string.
|
/// argument")` and `format!("{}", foo)` where `foo` is a string.
|
||||||
@@ -47,7 +47,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
|||||||
if_let_chain!{[
|
if_let_chain!{[
|
||||||
let ExprPath(ref qpath) = fun.node,
|
let ExprPath(ref qpath) = fun.node,
|
||||||
args.len() == 2,
|
args.len() == 2,
|
||||||
match_def_path(cx.tcx, resolve_node(cx, qpath, fun.hir_id).def_id(), &paths::FMT_ARGUMENTS_NEWV1),
|
let Some(fun_def_id) = opt_def_id(resolve_node(cx, qpath, fun.hir_id)),
|
||||||
|
match_def_path(cx.tcx, fun_def_id, &paths::FMT_ARGUMENTS_NEWV1),
|
||||||
// ensure the format string is `"{..}"` with only one argument and no text
|
// ensure the format string is `"{..}"` with only one argument and no text
|
||||||
check_static_str(cx, &args[0]),
|
check_static_str(cx, &args[0]),
|
||||||
// ensure the format argument is `{}` ie. Display with no fancy option
|
// ensure the format argument is `{}` ie. Display with no fancy option
|
||||||
@@ -128,7 +129,8 @@ fn check_arg_is_display(cx: &LateContext, expr: &Expr) -> bool {
|
|||||||
let ExprCall(_, ref args) = exprs[0].node,
|
let ExprCall(_, ref args) = exprs[0].node,
|
||||||
args.len() == 2,
|
args.len() == 2,
|
||||||
let ExprPath(ref qpath) = args[1].node,
|
let ExprPath(ref qpath) = args[1].node,
|
||||||
match_def_path(cx.tcx, resolve_node(cx, qpath, args[1].hir_id).def_id(), &paths::DISPLAY_FMT_METHOD),
|
let Some(fun_def_id) = opt_def_id(resolve_node(cx, qpath, args[1].hir_id)),
|
||||||
|
match_def_path(cx.tcx, fun_def_id, &paths::DISPLAY_FMT_METHOD),
|
||||||
], {
|
], {
|
||||||
let ty = walk_ptrs_ty(cx.tables.pat_ty(&pat[0]));
|
let ty = walk_ptrs_ty(cx.tables.pat_ty(&pat[0]));
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ use rustc::hir::intravisit;
|
|||||||
use rustc::hir;
|
use rustc::hir;
|
||||||
use rustc::lint::*;
|
use rustc::lint::*;
|
||||||
use rustc::ty;
|
use rustc::ty;
|
||||||
|
use rustc::hir::def::Def;
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::abi::Abi;
|
use syntax::abi::Abi;
|
||||||
@@ -166,9 +167,9 @@ impl<'a, 'tcx> Functions {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn raw_ptr_arg(arg: &hir::Arg, ty: &hir::Ty) -> Option<hir::def_id::DefId> {
|
fn raw_ptr_arg(arg: &hir::Arg, ty: &hir::Ty) -> Option<ast::NodeId> {
|
||||||
if let (&hir::PatKind::Binding(_, def_id, _, _), &hir::TyPtr(_)) = (&arg.pat.node, &ty.node) {
|
if let (&hir::PatKind::Binding(_, id, _, _), &hir::TyPtr(_)) = (&arg.pat.node, &ty.node) {
|
||||||
Some(def_id)
|
Some(id)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
@@ -176,7 +177,7 @@ fn raw_ptr_arg(arg: &hir::Arg, ty: &hir::Ty) -> Option<hir::def_id::DefId> {
|
|||||||
|
|
||||||
struct DerefVisitor<'a, 'tcx: 'a> {
|
struct DerefVisitor<'a, 'tcx: 'a> {
|
||||||
cx: &'a LateContext<'a, 'tcx>,
|
cx: &'a LateContext<'a, 'tcx>,
|
||||||
ptrs: HashSet<hir::def_id::DefId>,
|
ptrs: HashSet<ast::NodeId>,
|
||||||
tables: &'a ty::TypeckTables<'tcx>,
|
tables: &'a ty::TypeckTables<'tcx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -216,14 +217,15 @@ impl<'a, 'tcx> hir::intravisit::Visitor<'tcx> for DerefVisitor<'a, 'tcx> {
|
|||||||
impl<'a, 'tcx: 'a> DerefVisitor<'a, 'tcx> {
|
impl<'a, 'tcx: 'a> DerefVisitor<'a, 'tcx> {
|
||||||
fn check_arg(&self, ptr: &hir::Expr) {
|
fn check_arg(&self, ptr: &hir::Expr) {
|
||||||
if let hir::ExprPath(ref qpath) = ptr.node {
|
if let hir::ExprPath(ref qpath) = ptr.node {
|
||||||
let def = self.cx.tables.qpath_def(qpath, ptr.hir_id);
|
if let Def::Local(id) = self.cx.tables.qpath_def(qpath, ptr.hir_id) {
|
||||||
if self.ptrs.contains(&def.def_id()) {
|
if self.ptrs.contains(&id) {
|
||||||
span_lint(
|
span_lint(
|
||||||
self.cx,
|
self.cx,
|
||||||
NOT_UNSAFE_PTR_ARG_DEREF,
|
NOT_UNSAFE_PTR_ARG_DEREF,
|
||||||
ptr.span,
|
ptr.span,
|
||||||
"this public function dereferences a raw pointer but is not marked `unsafe`",
|
"this public function dereferences a raw pointer but is not marked `unsafe`",
|
||||||
);
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
use rustc::lint::*;
|
use rustc::lint::*;
|
||||||
use rustc::hir;
|
use rustc::hir;
|
||||||
use rustc::hir::BindingAnnotation;
|
use rustc::hir::BindingAnnotation;
|
||||||
|
use rustc::hir::def::Def;
|
||||||
|
use syntax::ast;
|
||||||
use utils::{snippet, span_lint_and_then};
|
use utils::{snippet, span_lint_and_then};
|
||||||
|
|
||||||
/// **What it does:** Checks for variable declarations immediately followed by a
|
/// **What it does:** Checks for variable declarations immediately followed by a
|
||||||
@@ -65,19 +67,19 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LetIfSeq {
|
|||||||
let Some(expr) = it.peek(),
|
let Some(expr) = it.peek(),
|
||||||
let hir::StmtDecl(ref decl, _) = stmt.node,
|
let hir::StmtDecl(ref decl, _) = stmt.node,
|
||||||
let hir::DeclLocal(ref decl) = decl.node,
|
let hir::DeclLocal(ref decl) = decl.node,
|
||||||
let hir::PatKind::Binding(mode, def_id, ref name, None) = decl.pat.node,
|
let hir::PatKind::Binding(mode, canonical_id, ref name, None) = decl.pat.node,
|
||||||
let hir::StmtExpr(ref if_, _) = expr.node,
|
let hir::StmtExpr(ref if_, _) = expr.node,
|
||||||
let hir::ExprIf(ref cond, ref then, ref else_) = if_.node,
|
let hir::ExprIf(ref cond, ref then, ref else_) = if_.node,
|
||||||
!used_in_expr(cx, def_id, cond),
|
!used_in_expr(cx, canonical_id, cond),
|
||||||
let hir::ExprBlock(ref then) = then.node,
|
let hir::ExprBlock(ref then) = then.node,
|
||||||
let Some(value) = check_assign(cx, def_id, &*then),
|
let Some(value) = check_assign(cx, canonical_id, &*then),
|
||||||
!used_in_expr(cx, def_id, value),
|
!used_in_expr(cx, canonical_id, value),
|
||||||
], {
|
], {
|
||||||
let span = stmt.span.to(if_.span);
|
let span = stmt.span.to(if_.span);
|
||||||
|
|
||||||
let (default_multi_stmts, default) = if let Some(ref else_) = *else_ {
|
let (default_multi_stmts, default) = if let Some(ref else_) = *else_ {
|
||||||
if let hir::ExprBlock(ref else_) = else_.node {
|
if let hir::ExprBlock(ref else_) = else_.node {
|
||||||
if let Some(default) = check_assign(cx, def_id, else_) {
|
if let Some(default) = check_assign(cx, canonical_id, else_) {
|
||||||
(else_.stmts.len() > 1, default)
|
(else_.stmts.len() > 1, default)
|
||||||
} else if let Some(ref default) = decl.init {
|
} else if let Some(ref default) = decl.init {
|
||||||
(true, &**default)
|
(true, &**default)
|
||||||
@@ -130,7 +132,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LetIfSeq {
|
|||||||
|
|
||||||
struct UsedVisitor<'a, 'tcx: 'a> {
|
struct UsedVisitor<'a, 'tcx: 'a> {
|
||||||
cx: &'a LateContext<'a, 'tcx>,
|
cx: &'a LateContext<'a, 'tcx>,
|
||||||
id: hir::def_id::DefId,
|
id: ast::NodeId,
|
||||||
used: bool,
|
used: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,7 +140,8 @@ impl<'a, 'tcx> hir::intravisit::Visitor<'tcx> for UsedVisitor<'a, 'tcx> {
|
|||||||
fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
|
fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
|
||||||
if_let_chain! {[
|
if_let_chain! {[
|
||||||
let hir::ExprPath(ref qpath) = expr.node,
|
let hir::ExprPath(ref qpath) = expr.node,
|
||||||
self.id == self.cx.tables.qpath_def(qpath, expr.hir_id).def_id(),
|
let Def::Local(local_id) = self.cx.tables.qpath_def(qpath, expr.hir_id),
|
||||||
|
self.id == local_id,
|
||||||
], {
|
], {
|
||||||
self.used = true;
|
self.used = true;
|
||||||
return;
|
return;
|
||||||
@@ -152,7 +155,7 @@ impl<'a, 'tcx> hir::intravisit::Visitor<'tcx> for UsedVisitor<'a, 'tcx> {
|
|||||||
|
|
||||||
fn check_assign<'a, 'tcx>(
|
fn check_assign<'a, 'tcx>(
|
||||||
cx: &LateContext<'a, 'tcx>,
|
cx: &LateContext<'a, 'tcx>,
|
||||||
decl: hir::def_id::DefId,
|
decl: ast::NodeId,
|
||||||
block: &'tcx hir::Block,
|
block: &'tcx hir::Block,
|
||||||
) -> Option<&'tcx hir::Expr> {
|
) -> Option<&'tcx hir::Expr> {
|
||||||
if_let_chain! {[
|
if_let_chain! {[
|
||||||
@@ -161,7 +164,8 @@ fn check_assign<'a, 'tcx>(
|
|||||||
let hir::StmtSemi(ref expr, _) = expr.node,
|
let hir::StmtSemi(ref expr, _) = expr.node,
|
||||||
let hir::ExprAssign(ref var, ref value) = expr.node,
|
let hir::ExprAssign(ref var, ref value) = expr.node,
|
||||||
let hir::ExprPath(ref qpath) = var.node,
|
let hir::ExprPath(ref qpath) = var.node,
|
||||||
decl == cx.tables.qpath_def(qpath, var.hir_id).def_id(),
|
let Def::Local(local_id) = cx.tables.qpath_def(qpath, var.hir_id),
|
||||||
|
decl == local_id,
|
||||||
], {
|
], {
|
||||||
let mut v = UsedVisitor {
|
let mut v = UsedVisitor {
|
||||||
cx: cx,
|
cx: cx,
|
||||||
@@ -183,7 +187,7 @@ fn check_assign<'a, 'tcx>(
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn used_in_expr<'a, 'tcx: 'a>(cx: &LateContext<'a, 'tcx>, id: hir::def_id::DefId, expr: &'tcx hir::Expr) -> bool {
|
fn used_in_expr<'a, 'tcx: 'a>(cx: &LateContext<'a, 'tcx>, id: ast::NodeId, expr: &'tcx hir::Expr) -> bool {
|
||||||
let mut v = UsedVisitor {
|
let mut v = UsedVisitor {
|
||||||
cx: cx,
|
cx: cx,
|
||||||
id: id,
|
id: id,
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ use itertools::Itertools;
|
|||||||
use reexport::*;
|
use reexport::*;
|
||||||
use rustc::hir::*;
|
use rustc::hir::*;
|
||||||
use rustc::hir::def::Def;
|
use rustc::hir::def::Def;
|
||||||
use rustc::hir::def_id::DefId;
|
|
||||||
use rustc::hir::intravisit::{walk_block, walk_decl, walk_expr, walk_pat, walk_stmt, NestedVisitorMap, Visitor};
|
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::hir::map::Node::{NodeBlock, NodeExpr, NodeStmt};
|
||||||
use rustc::lint::*;
|
use rustc::lint::*;
|
||||||
@@ -594,13 +593,14 @@ fn check_for_loop<'a, 'tcx>(
|
|||||||
detect_manual_memcpy(cx, pat, arg, body, expr);
|
detect_manual_memcpy(cx, pat, arg, body, expr);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn same_var<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &Expr, var: DefId) -> bool {
|
fn same_var<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &Expr, var: ast::NodeId) -> bool {
|
||||||
if_let_chain! {[
|
if_let_chain! {[
|
||||||
let ExprPath(ref qpath) = expr.node,
|
let ExprPath(ref qpath) = expr.node,
|
||||||
let QPath::Resolved(None, ref path) = *qpath,
|
let QPath::Resolved(None, ref path) = *qpath,
|
||||||
path.segments.len() == 1,
|
path.segments.len() == 1,
|
||||||
|
let Def::Local(local_id) = cx.tables.qpath_def(qpath, expr.hir_id),
|
||||||
// our variable!
|
// our variable!
|
||||||
cx.tables.qpath_def(qpath, expr.hir_id).def_id() == var
|
local_id == var
|
||||||
], {
|
], {
|
||||||
return true;
|
return true;
|
||||||
}}
|
}}
|
||||||
@@ -644,8 +644,8 @@ fn is_slice_like<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ty: Ty) -> bool {
|
|||||||
is_slice || match_type(cx, ty, &paths::VEC) || match_type(cx, ty, &paths::VEC_DEQUE)
|
is_slice || match_type(cx, ty, &paths::VEC) || match_type(cx, ty, &paths::VEC_DEQUE)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_fixed_offset_var<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &Expr, var: DefId) -> Option<FixedOffsetVar> {
|
fn get_fixed_offset_var<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &Expr, var: ast::NodeId) -> Option<FixedOffsetVar> {
|
||||||
fn extract_offset<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, e: &Expr, var: DefId) -> Option<String> {
|
fn extract_offset<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, e: &Expr, var: ast::NodeId) -> Option<String> {
|
||||||
match e.node {
|
match e.node {
|
||||||
ExprLit(ref l) => match l.node {
|
ExprLit(ref l) => match l.node {
|
||||||
ast::LitKind::Int(x, _ty) => Some(x.to_string()),
|
ast::LitKind::Int(x, _ty) => Some(x.to_string()),
|
||||||
@@ -700,12 +700,12 @@ fn get_fixed_offset_var<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &Expr, var:
|
|||||||
fn get_indexed_assignments<'a, 'tcx>(
|
fn get_indexed_assignments<'a, 'tcx>(
|
||||||
cx: &LateContext<'a, 'tcx>,
|
cx: &LateContext<'a, 'tcx>,
|
||||||
body: &Expr,
|
body: &Expr,
|
||||||
var: DefId,
|
var: ast::NodeId,
|
||||||
) -> Vec<(FixedOffsetVar, FixedOffsetVar)> {
|
) -> Vec<(FixedOffsetVar, FixedOffsetVar)> {
|
||||||
fn get_assignment<'a, 'tcx>(
|
fn get_assignment<'a, 'tcx>(
|
||||||
cx: &LateContext<'a, 'tcx>,
|
cx: &LateContext<'a, 'tcx>,
|
||||||
e: &Expr,
|
e: &Expr,
|
||||||
var: DefId,
|
var: ast::NodeId,
|
||||||
) -> Option<(FixedOffsetVar, FixedOffsetVar)> {
|
) -> Option<(FixedOffsetVar, FixedOffsetVar)> {
|
||||||
if let Expr_::ExprAssign(ref lhs, ref rhs) = e.node {
|
if let Expr_::ExprAssign(ref lhs, ref rhs) = e.node {
|
||||||
match (get_fixed_offset_var(cx, lhs, var), get_fixed_offset_var(cx, rhs, var)) {
|
match (get_fixed_offset_var(cx, lhs, var), get_fixed_offset_var(cx, rhs, var)) {
|
||||||
@@ -759,7 +759,7 @@ fn detect_manual_memcpy<'a, 'tcx>(
|
|||||||
}) = higher::range(arg)
|
}) = higher::range(arg)
|
||||||
{
|
{
|
||||||
// the var must be a single name
|
// the var must be a single name
|
||||||
if let PatKind::Binding(_, def_id, _, _) = pat.node {
|
if let PatKind::Binding(_, canonical_id, _, _) = pat.node {
|
||||||
let print_sum = |arg1: &Offset, arg2: &Offset| -> String {
|
let print_sum = |arg1: &Offset, arg2: &Offset| -> String {
|
||||||
match (&arg1.value[..], arg1.negate, &arg2.value[..], arg2.negate) {
|
match (&arg1.value[..], arg1.negate, &arg2.value[..], arg2.negate) {
|
||||||
("0", _, "0", _) => "".into(),
|
("0", _, "0", _) => "".into(),
|
||||||
@@ -802,7 +802,7 @@ fn detect_manual_memcpy<'a, 'tcx>(
|
|||||||
|
|
||||||
// The only statements in the for loops can be indexed assignments from
|
// The only statements in the for loops can be indexed assignments from
|
||||||
// indexed retrievals.
|
// indexed retrievals.
|
||||||
let manual_copies = get_indexed_assignments(cx, body, def_id);
|
let manual_copies = get_indexed_assignments(cx, body, canonical_id);
|
||||||
|
|
||||||
let big_sugg = manual_copies
|
let big_sugg = manual_copies
|
||||||
.into_iter()
|
.into_iter()
|
||||||
@@ -852,10 +852,10 @@ fn check_for_loop_range<'a, 'tcx>(
|
|||||||
}) = higher::range(arg)
|
}) = higher::range(arg)
|
||||||
{
|
{
|
||||||
// the var must be a single name
|
// the var must be a single name
|
||||||
if let PatKind::Binding(_, def_id, ref ident, _) = pat.node {
|
if let PatKind::Binding(_, canonical_id, ref ident, _) = pat.node {
|
||||||
let mut visitor = VarVisitor {
|
let mut visitor = VarVisitor {
|
||||||
cx: cx,
|
cx: cx,
|
||||||
var: def_id,
|
var: canonical_id,
|
||||||
indexed: HashMap::new(),
|
indexed: HashMap::new(),
|
||||||
referenced: HashSet::new(),
|
referenced: HashSet::new(),
|
||||||
nonindex: false,
|
nonindex: false,
|
||||||
@@ -1298,15 +1298,15 @@ impl<'tcx> Visitor<'tcx> for UsedVisitor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct DefIdUsedVisitor<'a, 'tcx: 'a> {
|
struct LocalUsedVisitor <'a, 'tcx: 'a> {
|
||||||
cx: &'a LateContext<'a, 'tcx>,
|
cx: &'a LateContext<'a, 'tcx>,
|
||||||
def_id: DefId,
|
local: ast::NodeId,
|
||||||
used: bool,
|
used: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx: 'a> Visitor<'tcx> for DefIdUsedVisitor<'a, 'tcx> {
|
impl<'a, 'tcx: 'a> Visitor<'tcx> for LocalUsedVisitor<'a, 'tcx> {
|
||||||
fn visit_expr(&mut self, expr: &'tcx Expr) {
|
fn visit_expr(&mut self, expr: &'tcx Expr) {
|
||||||
if same_var(self.cx, expr, self.def_id) {
|
if same_var(self.cx, expr, self.local) {
|
||||||
self.used = true;
|
self.used = true;
|
||||||
} else {
|
} else {
|
||||||
walk_expr(self, expr);
|
walk_expr(self, expr);
|
||||||
@@ -1322,7 +1322,7 @@ struct VarVisitor<'a, 'tcx: 'a> {
|
|||||||
/// context reference
|
/// context reference
|
||||||
cx: &'a LateContext<'a, 'tcx>,
|
cx: &'a LateContext<'a, 'tcx>,
|
||||||
/// var name to look for as index
|
/// var name to look for as index
|
||||||
var: DefId,
|
var: ast::NodeId,
|
||||||
/// indexed variables, the extend is `None` for global
|
/// indexed variables, the extend is `None` for global
|
||||||
indexed: HashMap<Name, Option<region::Scope>>,
|
indexed: HashMap<Name, Option<region::Scope>>,
|
||||||
/// Any names that are used outside an index operation.
|
/// Any names that are used outside an index operation.
|
||||||
@@ -1344,9 +1344,9 @@ impl<'a, 'tcx> Visitor<'tcx> for VarVisitor<'a, 'tcx> {
|
|||||||
seqvar.segments.len() == 1,
|
seqvar.segments.len() == 1,
|
||||||
], {
|
], {
|
||||||
let index_used = same_var(self.cx, idx, self.var) || {
|
let index_used = same_var(self.cx, idx, self.var) || {
|
||||||
let mut used_visitor = DefIdUsedVisitor {
|
let mut used_visitor = LocalUsedVisitor {
|
||||||
cx: self.cx,
|
cx: self.cx,
|
||||||
def_id: self.var,
|
local: self.var,
|
||||||
used: false,
|
used: false,
|
||||||
};
|
};
|
||||||
walk_expr(&mut used_visitor, idx);
|
walk_expr(&mut used_visitor, idx);
|
||||||
@@ -1356,9 +1356,7 @@ impl<'a, 'tcx> Visitor<'tcx> for VarVisitor<'a, 'tcx> {
|
|||||||
if index_used {
|
if index_used {
|
||||||
let def = self.cx.tables.qpath_def(seqpath, seqexpr.hir_id);
|
let def = self.cx.tables.qpath_def(seqpath, seqexpr.hir_id);
|
||||||
match def {
|
match def {
|
||||||
Def::Local(..) | Def::Upvar(..) => {
|
Def::Local(node_id) | Def::Upvar(node_id, ..) => {
|
||||||
let def_id = def.def_id();
|
|
||||||
let node_id = self.cx.tcx.hir.as_local_node_id(def_id).expect("local/upvar are local nodes");
|
|
||||||
let hir_id = self.cx.tcx.hir.node_to_hir_id(node_id);
|
let hir_id = self.cx.tcx.hir.node_to_hir_id(node_id);
|
||||||
|
|
||||||
let parent_id = self.cx.tcx.hir.get_parent(expr.id);
|
let parent_id = self.cx.tcx.hir.get_parent(expr.id);
|
||||||
@@ -1381,8 +1379,9 @@ impl<'a, 'tcx> Visitor<'tcx> for VarVisitor<'a, 'tcx> {
|
|||||||
let ExprPath(ref qpath) = expr.node,
|
let ExprPath(ref qpath) = expr.node,
|
||||||
let QPath::Resolved(None, ref path) = *qpath,
|
let QPath::Resolved(None, ref path) = *qpath,
|
||||||
path.segments.len() == 1,
|
path.segments.len() == 1,
|
||||||
|
let Def::Local(local_id) = self.cx.tables.qpath_def(qpath, expr.hir_id),
|
||||||
], {
|
], {
|
||||||
if self.cx.tables.qpath_def(qpath, expr.hir_id).def_id() == self.var {
|
if local_id == self.var {
|
||||||
// we are not indexing anything, record that
|
// we are not indexing anything, record that
|
||||||
self.nonindex = true;
|
self.nonindex = true;
|
||||||
} else {
|
} else {
|
||||||
@@ -1672,11 +1671,7 @@ impl<'a, 'tcx> Visitor<'tcx> for InitializeVisitor<'a, 'tcx> {
|
|||||||
fn var_def_id(cx: &LateContext, expr: &Expr) -> Option<NodeId> {
|
fn var_def_id(cx: &LateContext, expr: &Expr) -> Option<NodeId> {
|
||||||
if let ExprPath(ref qpath) = expr.node {
|
if let ExprPath(ref qpath) = expr.node {
|
||||||
let path_res = cx.tables.qpath_def(qpath, expr.hir_id);
|
let path_res = cx.tables.qpath_def(qpath, expr.hir_id);
|
||||||
if let Def::Local(def_id) = path_res {
|
if let Def::Local(node_id) = path_res {
|
||||||
let node_id = cx.tcx
|
|
||||||
.hir
|
|
||||||
.as_local_node_id(def_id)
|
|
||||||
.expect("That DefId should be valid");
|
|
||||||
return Some(node_id);
|
return Some(node_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use rustc::lint::*;
|
use rustc::lint::*;
|
||||||
use rustc::hir::{Expr, ExprCall, ExprPath};
|
use rustc::hir::{Expr, ExprCall, ExprPath};
|
||||||
use utils::{match_def_path, paths, span_lint};
|
use utils::{match_def_path, paths, span_lint, opt_def_id};
|
||||||
|
|
||||||
/// **What it does:** Checks for usage of `std::mem::forget(t)` where `t` is
|
/// **What it does:** Checks for usage of `std::mem::forget(t)` where `t` is
|
||||||
/// `Drop`.
|
/// `Drop`.
|
||||||
@@ -32,15 +32,16 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MemForget {
|
|||||||
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) {
|
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) {
|
||||||
if let ExprCall(ref path_expr, ref args) = e.node {
|
if let ExprCall(ref path_expr, ref args) = e.node {
|
||||||
if let ExprPath(ref qpath) = path_expr.node {
|
if let ExprPath(ref qpath) = path_expr.node {
|
||||||
let def_id = cx.tables.qpath_def(qpath, path_expr.hir_id).def_id();
|
if let Some(def_id) = opt_def_id(cx.tables.qpath_def(qpath, path_expr.hir_id)) {
|
||||||
if match_def_path(cx.tcx, def_id, &paths::MEM_FORGET) {
|
if match_def_path(cx.tcx, def_id, &paths::MEM_FORGET) {
|
||||||
let forgot_ty = cx.tables.expr_ty(&args[0]);
|
let forgot_ty = cx.tables.expr_ty(&args[0]);
|
||||||
|
|
||||||
if match forgot_ty.ty_adt_def() {
|
if match forgot_ty.ty_adt_def() {
|
||||||
Some(def) => def.has_dtor(cx.tcx),
|
Some(def) => def.has_dtor(cx.tcx),
|
||||||
_ => false,
|
_ => false,
|
||||||
} {
|
} {
|
||||||
span_lint(cx, MEM_FORGET, e.span, "usage of mem::forget on Drop type");
|
span_lint(cx, MEM_FORGET, e.span, "usage of mem::forget on Drop type");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ use consts::{constant_simple, Constant};
|
|||||||
use rustc::lint::*;
|
use rustc::lint::*;
|
||||||
use rustc::hir::*;
|
use rustc::hir::*;
|
||||||
use std::cmp::{Ordering, PartialOrd};
|
use std::cmp::{Ordering, PartialOrd};
|
||||||
use utils::{match_def_path, paths, span_lint};
|
use utils::{match_def_path, paths, span_lint, opt_def_id};
|
||||||
|
|
||||||
/// **What it does:** Checks for expressions where `std::cmp::min` and `max` are
|
/// **What it does:** Checks for expressions where `std::cmp::min` and `max` are
|
||||||
/// used to clamp values, but switched so that the result is constant.
|
/// used to clamp values, but switched so that the result is constant.
|
||||||
@@ -60,15 +60,15 @@ enum MinMax {
|
|||||||
fn min_max<'a>(cx: &LateContext, expr: &'a Expr) -> Option<(MinMax, Constant, &'a Expr)> {
|
fn min_max<'a>(cx: &LateContext, expr: &'a Expr) -> Option<(MinMax, Constant, &'a Expr)> {
|
||||||
if let ExprCall(ref path, ref args) = expr.node {
|
if let ExprCall(ref path, ref args) = expr.node {
|
||||||
if let ExprPath(ref qpath) = path.node {
|
if let ExprPath(ref qpath) = path.node {
|
||||||
let def_id = cx.tables.qpath_def(qpath, path.hir_id).def_id();
|
opt_def_id(cx.tables.qpath_def(qpath, path.hir_id)).and_then(|def_id| {
|
||||||
|
if match_def_path(cx.tcx, def_id, &paths::CMP_MIN) {
|
||||||
if match_def_path(cx.tcx, def_id, &paths::CMP_MIN) {
|
fetch_const(cx, args, MinMax::Min)
|
||||||
fetch_const(cx, args, MinMax::Min)
|
} else if match_def_path(cx.tcx, def_id, &paths::CMP_MAX) {
|
||||||
} else if match_def_path(cx.tcx, def_id, &paths::CMP_MAX) {
|
fetch_const(cx, args, MinMax::Max)
|
||||||
fetch_const(cx, args, MinMax::Max)
|
} else {
|
||||||
} else {
|
None
|
||||||
None
|
}
|
||||||
}
|
})
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -574,11 +574,7 @@ fn in_attributes_expansion(expr: &Expr) -> bool {
|
|||||||
/// Test whether `def` is a variable defined outside a macro.
|
/// Test whether `def` is a variable defined outside a macro.
|
||||||
fn non_macro_local(cx: &LateContext, def: &def::Def) -> bool {
|
fn non_macro_local(cx: &LateContext, def: &def::Def) -> bool {
|
||||||
match *def {
|
match *def {
|
||||||
def::Def::Local(def_id) | def::Def::Upvar(def_id, _, _) => {
|
def::Def::Local(id) | def::Def::Upvar(id, _, _) => {
|
||||||
let id = cx.tcx
|
|
||||||
.hir
|
|
||||||
.as_local_node_id(def_id)
|
|
||||||
.expect("local variables should be found in the same crate");
|
|
||||||
!in_macro(cx.tcx.hir.span(id))
|
!in_macro(cx.tcx.hir.span(id))
|
||||||
},
|
},
|
||||||
_ => false,
|
_ => false,
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
use rustc::hir::*;
|
use rustc::hir::*;
|
||||||
use rustc::hir::intravisit::FnKind;
|
use rustc::hir::intravisit::FnKind;
|
||||||
use rustc::hir::def_id::DefId;
|
|
||||||
use rustc::lint::*;
|
use rustc::lint::*;
|
||||||
use rustc::ty::{self, TypeFoldable};
|
use rustc::ty::{self, TypeFoldable};
|
||||||
use rustc::traits;
|
use rustc::traits;
|
||||||
@@ -129,8 +128,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessPassByValue {
|
|||||||
!implements_trait(cx, ty, asref_trait, &[]),
|
!implements_trait(cx, ty, asref_trait, &[]),
|
||||||
!implements_borrow_trait,
|
!implements_borrow_trait,
|
||||||
|
|
||||||
let PatKind::Binding(mode, defid, ..) = arg.pat.node,
|
let PatKind::Binding(mode, canonical_id, ..) = arg.pat.node,
|
||||||
!moved_vars.contains(&defid),
|
!moved_vars.contains(&canonical_id),
|
||||||
], {
|
], {
|
||||||
// Note: `toplevel_ref_arg` warns if `BindByRef`
|
// Note: `toplevel_ref_arg` warns if `BindByRef`
|
||||||
if mode == BindingAnnotation::Mutable || mode == BindingAnnotation::RefMut {
|
if mode == BindingAnnotation::Mutable || mode == BindingAnnotation::RefMut {
|
||||||
@@ -139,7 +138,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessPassByValue {
|
|||||||
|
|
||||||
// Suggestion logic
|
// Suggestion logic
|
||||||
let sugg = |db: &mut DiagnosticBuilder| {
|
let sugg = |db: &mut DiagnosticBuilder| {
|
||||||
let deref_span = spans_need_deref.get(&defid);
|
let deref_span = spans_need_deref.get(&canonical_id);
|
||||||
if_let_chain! {[
|
if_let_chain! {[
|
||||||
match_type(cx, ty, &paths::VEC),
|
match_type(cx, ty, &paths::VEC),
|
||||||
let TyPath(QPath::Resolved(_, ref path)) = input.node,
|
let TyPath(QPath::Resolved(_, ref path)) = input.node,
|
||||||
@@ -186,11 +185,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessPassByValue {
|
|||||||
|
|
||||||
struct MovedVariablesCtxt<'a, 'tcx: 'a> {
|
struct MovedVariablesCtxt<'a, 'tcx: 'a> {
|
||||||
cx: &'a LateContext<'a, 'tcx>,
|
cx: &'a LateContext<'a, 'tcx>,
|
||||||
moved_vars: HashSet<DefId>,
|
moved_vars: HashSet<NodeId>,
|
||||||
/// Spans which need to be prefixed with `*` for dereferencing the
|
/// Spans which need to be prefixed with `*` for dereferencing the
|
||||||
/// suggested additional
|
/// suggested additional
|
||||||
/// reference.
|
/// reference.
|
||||||
spans_need_deref: HashMap<DefId, HashSet<Span>>,
|
spans_need_deref: HashMap<NodeId, HashSet<Span>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> MovedVariablesCtxt<'a, 'tcx> {
|
impl<'a, 'tcx> MovedVariablesCtxt<'a, 'tcx> {
|
||||||
@@ -205,12 +204,9 @@ impl<'a, 'tcx> MovedVariablesCtxt<'a, 'tcx> {
|
|||||||
fn move_common(&mut self, _consume_id: NodeId, _span: Span, cmt: mc::cmt<'tcx>) {
|
fn move_common(&mut self, _consume_id: NodeId, _span: Span, cmt: mc::cmt<'tcx>) {
|
||||||
let cmt = unwrap_downcast_or_interior(cmt);
|
let cmt = unwrap_downcast_or_interior(cmt);
|
||||||
|
|
||||||
if_let_chain! {[
|
if let mc::Categorization::Local(vid) = cmt.cat {
|
||||||
let mc::Categorization::Local(vid) = cmt.cat,
|
self.moved_vars.insert(vid);
|
||||||
let Some(def_id) = self.cx.tcx.hir.opt_local_def_id(vid),
|
}
|
||||||
], {
|
|
||||||
self.moved_vars.insert(def_id);
|
|
||||||
}}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn non_moving_pat(&mut self, matched_pat: &Pat, cmt: mc::cmt<'tcx>) {
|
fn non_moving_pat(&mut self, matched_pat: &Pat, cmt: mc::cmt<'tcx>) {
|
||||||
@@ -218,7 +214,6 @@ impl<'a, 'tcx> MovedVariablesCtxt<'a, 'tcx> {
|
|||||||
|
|
||||||
if_let_chain! {[
|
if_let_chain! {[
|
||||||
let mc::Categorization::Local(vid) = cmt.cat,
|
let mc::Categorization::Local(vid) = cmt.cat,
|
||||||
let Some(def_id) = self.cx.tcx.hir.opt_local_def_id(vid),
|
|
||||||
], {
|
], {
|
||||||
let mut id = matched_pat.id;
|
let mut id = matched_pat.id;
|
||||||
loop {
|
loop {
|
||||||
@@ -235,7 +230,7 @@ impl<'a, 'tcx> MovedVariablesCtxt<'a, 'tcx> {
|
|||||||
// `match` and `if let`
|
// `match` and `if let`
|
||||||
if let ExprMatch(ref c, ..) = e.node {
|
if let ExprMatch(ref c, ..) = e.node {
|
||||||
self.spans_need_deref
|
self.spans_need_deref
|
||||||
.entry(def_id)
|
.entry(vid)
|
||||||
.or_insert_with(HashSet::new)
|
.or_insert_with(HashSet::new)
|
||||||
.insert(c.span);
|
.insert(c.span);
|
||||||
}
|
}
|
||||||
@@ -248,7 +243,7 @@ impl<'a, 'tcx> MovedVariablesCtxt<'a, 'tcx> {
|
|||||||
let DeclLocal(ref local) = decl.node,
|
let DeclLocal(ref local) = decl.node,
|
||||||
], {
|
], {
|
||||||
self.spans_need_deref
|
self.spans_need_deref
|
||||||
.entry(def_id)
|
.entry(vid)
|
||||||
.or_insert_with(HashSet::new)
|
.or_insert_with(HashSet::new)
|
||||||
.insert(local.init
|
.insert(local.init
|
||||||
.as_ref()
|
.as_ref()
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use rustc::hir::*;
|
use rustc::hir::*;
|
||||||
use rustc::lint::*;
|
use rustc::lint::*;
|
||||||
use syntax::ast::LitKind;
|
use syntax::ast::LitKind;
|
||||||
use utils::{is_direct_expn_of, match_def_path, paths, resolve_node, span_lint};
|
use utils::{is_direct_expn_of, match_def_path, paths, resolve_node, span_lint, opt_def_id};
|
||||||
|
|
||||||
/// **What it does:** Checks for missing parameters in `panic!`.
|
/// **What it does:** Checks for missing parameters in `panic!`.
|
||||||
///
|
///
|
||||||
@@ -40,7 +40,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
|||||||
let ExprCall(ref fun, ref params) = ex.node,
|
let ExprCall(ref fun, ref params) = ex.node,
|
||||||
params.len() == 2,
|
params.len() == 2,
|
||||||
let ExprPath(ref qpath) = fun.node,
|
let ExprPath(ref qpath) = fun.node,
|
||||||
match_def_path(cx.tcx, resolve_node(cx, qpath, fun.hir_id).def_id(), &paths::BEGIN_PANIC),
|
let Some(fun_def_id) = opt_def_id(resolve_node(cx, qpath, fun.hir_id)),
|
||||||
|
match_def_path(cx.tcx, fun_def_id, &paths::BEGIN_PANIC),
|
||||||
let ExprLit(ref lit) = params[0].node,
|
let ExprLit(ref lit) = params[0].node,
|
||||||
is_direct_expn_of(expr.span, "panic").is_some(),
|
is_direct_expn_of(expr.span, "panic").is_some(),
|
||||||
let LitKind::Str(ref string, _) = lit.node,
|
let LitKind::Str(ref string, _) = lit.node,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use rustc::hir::*;
|
use rustc::hir::*;
|
||||||
use rustc::hir::map::Node::{NodeImplItem, NodeItem};
|
use rustc::hir::map::Node::{NodeImplItem, NodeItem};
|
||||||
use rustc::lint::*;
|
use rustc::lint::*;
|
||||||
use utils::paths;
|
use utils::{paths, opt_def_id};
|
||||||
use utils::{is_expn_of, match_def_path, match_path, resolve_node, span_lint};
|
use utils::{is_expn_of, match_def_path, match_path, resolve_node, span_lint};
|
||||||
use format::get_argument_fmtstr_parts;
|
use format::get_argument_fmtstr_parts;
|
||||||
|
|
||||||
@@ -72,9 +72,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
|||||||
if_let_chain! {[
|
if_let_chain! {[
|
||||||
let ExprCall(ref fun, ref args) = expr.node,
|
let ExprCall(ref fun, ref args) = expr.node,
|
||||||
let ExprPath(ref qpath) = fun.node,
|
let ExprPath(ref qpath) = fun.node,
|
||||||
|
let Some(fun_id) = opt_def_id(resolve_node(cx, qpath, fun.hir_id)),
|
||||||
], {
|
], {
|
||||||
let fun = resolve_node(cx, qpath, fun.hir_id);
|
|
||||||
let fun_id = fun.def_id();
|
|
||||||
|
|
||||||
// Search for `std::io::_print(..)` which is unique in a
|
// Search for `std::io::_print(..)` which is unique in a
|
||||||
// `print!` expansion.
|
// `print!` expansion.
|
||||||
@@ -96,9 +95,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
|||||||
args.len() == 1,
|
args.len() == 1,
|
||||||
let ExprCall(ref args_fun, ref args_args) = args[0].node,
|
let ExprCall(ref args_fun, ref args_args) = args[0].node,
|
||||||
let ExprPath(ref qpath) = args_fun.node,
|
let ExprPath(ref qpath) = args_fun.node,
|
||||||
match_def_path(cx.tcx,
|
let Some(const_def_id) = opt_def_id(resolve_node(cx, qpath, args_fun.hir_id)),
|
||||||
resolve_node(cx, qpath, args_fun.hir_id).def_id(),
|
match_def_path(cx.tcx, const_def_id, &paths::FMT_ARGUMENTS_NEWV1),
|
||||||
&paths::FMT_ARGUMENTS_NEWV1),
|
|
||||||
args_args.len() == 2,
|
args_args.len() == 2,
|
||||||
let ExprAddrOf(_, ref match_expr) = args_args[1].node,
|
let ExprAddrOf(_, ref match_expr) = args_args[1].node,
|
||||||
let ExprMatch(ref args, _, _) = match_expr.node,
|
let ExprMatch(ref args, _, _) = match_expr.node,
|
||||||
@@ -125,10 +123,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
|||||||
// `::std::fmt::ArgumentV1::new(__arg0, ::std::fmt::Debug::fmt)`
|
// `::std::fmt::ArgumentV1::new(__arg0, ::std::fmt::Debug::fmt)`
|
||||||
else if args.len() == 2 && match_def_path(cx.tcx, fun_id, &paths::FMT_ARGUMENTV1_NEW) {
|
else if args.len() == 2 && match_def_path(cx.tcx, fun_id, &paths::FMT_ARGUMENTV1_NEW) {
|
||||||
if let ExprPath(ref qpath) = args[1].node {
|
if let ExprPath(ref qpath) = args[1].node {
|
||||||
let def_id = cx.tables.qpath_def(qpath, args[1].hir_id).def_id();
|
if let Some(def_id) = opt_def_id(cx.tables.qpath_def(qpath, args[1].hir_id)) {
|
||||||
if match_def_path(cx.tcx, def_id, &paths::DEBUG_FMT_METHOD) && !is_in_debug_impl(cx, expr) &&
|
if match_def_path(cx.tcx, def_id, &paths::DEBUG_FMT_METHOD) && !is_in_debug_impl(cx, expr) && is_expn_of(expr.span, "panic").is_none() {
|
||||||
is_expn_of(expr.span, "panic").is_none() {
|
span_lint(cx, USE_DEBUG, args[0].span, "use of `Debug`-based formatting");
|
||||||
span_lint(cx, USE_DEBUG, args[0].span, "use of `Debug`-based formatting");
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ use std::error::Error;
|
|||||||
use syntax::ast::{LitKind, NodeId};
|
use syntax::ast::{LitKind, NodeId};
|
||||||
use syntax::codemap::{BytePos, Span};
|
use syntax::codemap::{BytePos, Span};
|
||||||
use syntax::symbol::InternedString;
|
use syntax::symbol::InternedString;
|
||||||
use utils::{is_expn_of, match_def_path, match_type, paths, span_help_and_lint, span_lint};
|
use utils::{is_expn_of, match_def_path, match_type, paths, span_help_and_lint, span_lint, opt_def_id};
|
||||||
|
|
||||||
/// **What it does:** Checks [regex](https://crates.io/crates/regex) creation
|
/// **What it does:** Checks [regex](https://crates.io/crates/regex) creation
|
||||||
/// (with `Regex::new`,`RegexBuilder::new` or `RegexSet::new`) for correct
|
/// (with `Regex::new`,`RegexBuilder::new` or `RegexSet::new`) for correct
|
||||||
@@ -116,8 +116,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
|||||||
let ExprCall(ref fun, ref args) = expr.node,
|
let ExprCall(ref fun, ref args) = expr.node,
|
||||||
let ExprPath(ref qpath) = fun.node,
|
let ExprPath(ref qpath) = fun.node,
|
||||||
args.len() == 1,
|
args.len() == 1,
|
||||||
|
let Some(def_id) = opt_def_id(cx.tables.qpath_def(qpath, fun.hir_id)),
|
||||||
], {
|
], {
|
||||||
let def_id = cx.tables.qpath_def(qpath, fun.hir_id).def_id();
|
|
||||||
if match_def_path(cx.tcx, def_id, &paths::REGEX_NEW) ||
|
if match_def_path(cx.tcx, def_id, &paths::REGEX_NEW) ||
|
||||||
match_def_path(cx.tcx, def_id, &paths::REGEX_BUILDER_NEW) {
|
match_def_path(cx.tcx, def_id, &paths::REGEX_BUILDER_NEW) {
|
||||||
check_regex(cx, &args[0], true);
|
check_regex(cx, &args[0], true);
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ use rustc::lint::*;
|
|||||||
use rustc::ty::{self, Ty};
|
use rustc::ty::{self, Ty};
|
||||||
use rustc::hir::*;
|
use rustc::hir::*;
|
||||||
use utils::{last_path_segment, match_def_path, paths, snippet, span_lint, span_lint_and_then};
|
use utils::{last_path_segment, match_def_path, paths, snippet, span_lint, span_lint_and_then};
|
||||||
use utils::sugg;
|
use utils::{sugg, opt_def_id};
|
||||||
|
|
||||||
/// **What it does:** Checks for transmutes that can't ever be correct on any
|
/// **What it does:** Checks for transmutes that can't ever be correct on any
|
||||||
/// architecture.
|
/// architecture.
|
||||||
@@ -88,97 +88,98 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Transmute {
|
|||||||
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) {
|
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) {
|
||||||
if let ExprCall(ref path_expr, ref args) = e.node {
|
if let ExprCall(ref path_expr, ref args) = e.node {
|
||||||
if let ExprPath(ref qpath) = path_expr.node {
|
if let ExprPath(ref qpath) = path_expr.node {
|
||||||
let def_id = cx.tables.qpath_def(qpath, path_expr.hir_id).def_id();
|
if let Some(def_id) = opt_def_id(cx.tables.qpath_def(qpath, path_expr.hir_id)) {
|
||||||
|
|
||||||
if match_def_path(cx.tcx, def_id, &paths::TRANSMUTE) {
|
if match_def_path(cx.tcx, def_id, &paths::TRANSMUTE) {
|
||||||
let from_ty = cx.tables.expr_ty(&args[0]);
|
let from_ty = cx.tables.expr_ty(&args[0]);
|
||||||
let to_ty = cx.tables.expr_ty(e);
|
let to_ty = cx.tables.expr_ty(e);
|
||||||
|
|
||||||
match (&from_ty.sty, &to_ty.sty) {
|
match (&from_ty.sty, &to_ty.sty) {
|
||||||
_ if from_ty == to_ty => span_lint(
|
_ if from_ty == to_ty => span_lint(
|
||||||
cx,
|
cx,
|
||||||
USELESS_TRANSMUTE,
|
USELESS_TRANSMUTE,
|
||||||
e.span,
|
e.span,
|
||||||
&format!("transmute from a type (`{}`) to itself", from_ty),
|
&format!("transmute from a type (`{}`) to itself", from_ty),
|
||||||
),
|
|
||||||
(&ty::TyRef(_, rty), &ty::TyRawPtr(ptr_ty)) => span_lint_and_then(
|
|
||||||
cx,
|
|
||||||
USELESS_TRANSMUTE,
|
|
||||||
e.span,
|
|
||||||
"transmute from a reference to a pointer",
|
|
||||||
|db| if let Some(arg) = sugg::Sugg::hir_opt(cx, &args[0]) {
|
|
||||||
let sugg = if ptr_ty == rty {
|
|
||||||
arg.as_ty(to_ty)
|
|
||||||
} else {
|
|
||||||
arg.as_ty(cx.tcx.mk_ptr(rty)).as_ty(to_ty)
|
|
||||||
};
|
|
||||||
|
|
||||||
db.span_suggestion(e.span, "try", sugg.to_string());
|
|
||||||
},
|
|
||||||
),
|
|
||||||
(&ty::TyInt(_), &ty::TyRawPtr(_)) | (&ty::TyUint(_), &ty::TyRawPtr(_)) => span_lint_and_then(
|
|
||||||
cx,
|
|
||||||
USELESS_TRANSMUTE,
|
|
||||||
e.span,
|
|
||||||
"transmute from an integer to a pointer",
|
|
||||||
|db| if let Some(arg) = sugg::Sugg::hir_opt(cx, &args[0]) {
|
|
||||||
db.span_suggestion(e.span, "try", arg.as_ty(&to_ty.to_string()).to_string());
|
|
||||||
},
|
|
||||||
),
|
|
||||||
(&ty::TyFloat(_), &ty::TyRef(..)) |
|
|
||||||
(&ty::TyFloat(_), &ty::TyRawPtr(_)) |
|
|
||||||
(&ty::TyChar, &ty::TyRef(..)) |
|
|
||||||
(&ty::TyChar, &ty::TyRawPtr(_)) => span_lint(
|
|
||||||
cx,
|
|
||||||
WRONG_TRANSMUTE,
|
|
||||||
e.span,
|
|
||||||
&format!("transmute from a `{}` to a pointer", from_ty),
|
|
||||||
),
|
|
||||||
(&ty::TyRawPtr(from_ptr), _) if from_ptr.ty == to_ty => span_lint(
|
|
||||||
cx,
|
|
||||||
CROSSPOINTER_TRANSMUTE,
|
|
||||||
e.span,
|
|
||||||
&format!(
|
|
||||||
"transmute from a type (`{}`) to the type that it points to (`{}`)",
|
|
||||||
from_ty,
|
|
||||||
to_ty
|
|
||||||
),
|
),
|
||||||
),
|
(&ty::TyRef(_, rty), &ty::TyRawPtr(ptr_ty)) => span_lint_and_then(
|
||||||
(_, &ty::TyRawPtr(to_ptr)) if to_ptr.ty == from_ty => span_lint(
|
cx,
|
||||||
cx,
|
USELESS_TRANSMUTE,
|
||||||
CROSSPOINTER_TRANSMUTE,
|
e.span,
|
||||||
e.span,
|
"transmute from a reference to a pointer",
|
||||||
&format!("transmute from a type (`{}`) to a pointer to that type (`{}`)", from_ty, to_ty),
|
|db| if let Some(arg) = sugg::Sugg::hir_opt(cx, &args[0]) {
|
||||||
),
|
let sugg = if ptr_ty == rty {
|
||||||
(&ty::TyRawPtr(from_pty), &ty::TyRef(_, to_rty)) => span_lint_and_then(
|
arg.as_ty(to_ty)
|
||||||
cx,
|
} else {
|
||||||
TRANSMUTE_PTR_TO_REF,
|
arg.as_ty(cx.tcx.mk_ptr(rty)).as_ty(to_ty)
|
||||||
e.span,
|
};
|
||||||
&format!(
|
|
||||||
"transmute from a pointer type (`{}`) to a reference type \
|
db.span_suggestion(e.span, "try", sugg.to_string());
|
||||||
(`{}`)",
|
},
|
||||||
from_ty,
|
|
||||||
to_ty
|
|
||||||
),
|
),
|
||||||
|db| {
|
(&ty::TyInt(_), &ty::TyRawPtr(_)) | (&ty::TyUint(_), &ty::TyRawPtr(_)) => span_lint_and_then(
|
||||||
let arg = sugg::Sugg::hir(cx, &args[0], "..");
|
cx,
|
||||||
let (deref, cast) = if to_rty.mutbl == Mutability::MutMutable {
|
USELESS_TRANSMUTE,
|
||||||
("&mut *", "*mut")
|
e.span,
|
||||||
} else {
|
"transmute from an integer to a pointer",
|
||||||
("&*", "*const")
|
|db| if let Some(arg) = sugg::Sugg::hir_opt(cx, &args[0]) {
|
||||||
};
|
db.span_suggestion(e.span, "try", arg.as_ty(&to_ty.to_string()).to_string());
|
||||||
|
},
|
||||||
|
),
|
||||||
|
(&ty::TyFloat(_), &ty::TyRef(..)) |
|
||||||
|
(&ty::TyFloat(_), &ty::TyRawPtr(_)) |
|
||||||
|
(&ty::TyChar, &ty::TyRef(..)) |
|
||||||
|
(&ty::TyChar, &ty::TyRawPtr(_)) => span_lint(
|
||||||
|
cx,
|
||||||
|
WRONG_TRANSMUTE,
|
||||||
|
e.span,
|
||||||
|
&format!("transmute from a `{}` to a pointer", from_ty),
|
||||||
|
),
|
||||||
|
(&ty::TyRawPtr(from_ptr), _) if from_ptr.ty == to_ty => span_lint(
|
||||||
|
cx,
|
||||||
|
CROSSPOINTER_TRANSMUTE,
|
||||||
|
e.span,
|
||||||
|
&format!(
|
||||||
|
"transmute from a type (`{}`) to the type that it points to (`{}`)",
|
||||||
|
from_ty,
|
||||||
|
to_ty
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(_, &ty::TyRawPtr(to_ptr)) if to_ptr.ty == from_ty => span_lint(
|
||||||
|
cx,
|
||||||
|
CROSSPOINTER_TRANSMUTE,
|
||||||
|
e.span,
|
||||||
|
&format!("transmute from a type (`{}`) to a pointer to that type (`{}`)", from_ty, to_ty),
|
||||||
|
),
|
||||||
|
(&ty::TyRawPtr(from_pty), &ty::TyRef(_, to_rty)) => span_lint_and_then(
|
||||||
|
cx,
|
||||||
|
TRANSMUTE_PTR_TO_REF,
|
||||||
|
e.span,
|
||||||
|
&format!(
|
||||||
|
"transmute from a pointer type (`{}`) to a reference type \
|
||||||
|
(`{}`)",
|
||||||
|
from_ty,
|
||||||
|
to_ty
|
||||||
|
),
|
||||||
|
|db| {
|
||||||
|
let arg = sugg::Sugg::hir(cx, &args[0], "..");
|
||||||
|
let (deref, cast) = if to_rty.mutbl == Mutability::MutMutable {
|
||||||
|
("&mut *", "*mut")
|
||||||
|
} else {
|
||||||
|
("&*", "*const")
|
||||||
|
};
|
||||||
|
|
||||||
let arg = if from_pty.ty == to_rty.ty {
|
let arg = if from_pty.ty == to_rty.ty {
|
||||||
arg
|
arg
|
||||||
} else {
|
} else {
|
||||||
arg.as_ty(&format!("{} {}", cast, get_type_snippet(cx, qpath, to_rty.ty)))
|
arg.as_ty(&format!("{} {}", cast, get_type_snippet(cx, qpath, to_rty.ty)))
|
||||||
};
|
};
|
||||||
|
|
||||||
db.span_suggestion(e.span, "try", sugg::make_unop(deref, arg).to_string());
|
db.span_suggestion(e.span, "try", sugg::make_unop(deref, arg).to_string());
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
_ => return,
|
_ => return,
|
||||||
};
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
use rustc::hir;
|
use rustc::hir;
|
||||||
use rustc::lint::LateContext;
|
use rustc::lint::LateContext;
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use utils::{is_expn_of, match_def_path, match_qpath, paths, resolve_node};
|
use utils::{is_expn_of, match_def_path, match_qpath, paths, resolve_node, opt_def_id};
|
||||||
|
|
||||||
/// Convert a hir binary operator to the corresponding `ast` type.
|
/// Convert a hir binary operator to the corresponding `ast` type.
|
||||||
pub fn binop(op: hir::BinOp_) -> ast::BinOpKind {
|
pub fn binop(op: hir::BinOp_) -> ast::BinOpKind {
|
||||||
@@ -181,13 +181,13 @@ pub fn vec_macro<'e>(cx: &LateContext, expr: &'e hir::Expr) -> Option<VecArgs<'e
|
|||||||
let hir::ExprCall(ref fun, ref args) = expr.node,
|
let hir::ExprCall(ref fun, ref args) = expr.node,
|
||||||
let hir::ExprPath(ref path) = fun.node,
|
let hir::ExprPath(ref path) = fun.node,
|
||||||
is_expn_of(fun.span, "vec").is_some(),
|
is_expn_of(fun.span, "vec").is_some(),
|
||||||
|
let Some(fun_def_id) = opt_def_id(resolve_node(cx, path, fun.hir_id)),
|
||||||
], {
|
], {
|
||||||
let fun_def = resolve_node(cx, path, fun.hir_id);
|
return if match_def_path(cx.tcx, fun_def_id, &paths::VEC_FROM_ELEM) && args.len() == 2 {
|
||||||
return if match_def_path(cx.tcx, fun_def.def_id(), &paths::VEC_FROM_ELEM) && args.len() == 2 {
|
|
||||||
// `vec![elem; size]` case
|
// `vec![elem; size]` case
|
||||||
Some(VecArgs::Repeat(&args[0], &args[1]))
|
Some(VecArgs::Repeat(&args[0], &args[1]))
|
||||||
}
|
}
|
||||||
else if match_def_path(cx.tcx, fun_def.def_id(), &paths::SLICE_INTO_VEC) && args.len() == 1 {
|
else if match_def_path(cx.tcx, fun_def_id, &paths::SLICE_INTO_VEC) && args.len() == 1 {
|
||||||
// `vec![a, b, c]` case
|
// `vec![a, b, c]` case
|
||||||
if_let_chain!{[
|
if_let_chain!{[
|
||||||
let hir::ExprBox(ref boxed) = args[0].node,
|
let hir::ExprBox(ref boxed) = args[0].node,
|
||||||
|
|||||||
@@ -360,7 +360,8 @@ fn print_item(cx: &LateContext, item: &hir::Item) {
|
|||||||
}
|
}
|
||||||
match item.node {
|
match item.node {
|
||||||
hir::ItemExternCrate(ref _renamed_from) => {
|
hir::ItemExternCrate(ref _renamed_from) => {
|
||||||
if let Some(crate_id) = cx.tcx.extern_mod_stmt_cnum(item.hir_id) {
|
let def_id = cx.tcx.hir.local_def_id(item.id);
|
||||||
|
if let Some(crate_id) = cx.tcx.extern_mod_stmt_cnum(def_id) {
|
||||||
let source = cx.tcx.used_crate_source(crate_id);
|
let source = cx.tcx.used_crate_source(crate_id);
|
||||||
if let Some(ref src) = source.dylib {
|
if let Some(ref src) = source.dylib {
|
||||||
println!("extern crate dylib source: {:?}", src.0);
|
println!("extern crate dylib source: {:?}", src.0);
|
||||||
|
|||||||
@@ -950,12 +950,10 @@ pub fn opt_def_id(def: Def) -> Option<DefId> {
|
|||||||
Def::Method(id) |
|
Def::Method(id) |
|
||||||
Def::Const(id) |
|
Def::Const(id) |
|
||||||
Def::AssociatedConst(id) |
|
Def::AssociatedConst(id) |
|
||||||
Def::Local(id) |
|
|
||||||
Def::Upvar(id, ..) |
|
|
||||||
Def::Macro(id, ..) |
|
Def::Macro(id, ..) |
|
||||||
Def::GlobalAsm(id) => Some(id),
|
Def::GlobalAsm(id) => Some(id),
|
||||||
|
|
||||||
Def::Label(..) | Def::PrimTy(..) | Def::SelfTy(..) | Def::Err => None,
|
Def::Upvar(..) | Def::Local(_) | Def::Label(..) | Def::PrimTy(..) | Def::SelfTy(..) | Def::Err => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -991,7 +989,8 @@ pub fn is_try(expr: &Expr) -> Option<&Expr> {
|
|||||||
match_qpath(path, &paths::RESULT_OK[1..]),
|
match_qpath(path, &paths::RESULT_OK[1..]),
|
||||||
let PatKind::Binding(_, defid, _, None) = pat[0].node,
|
let PatKind::Binding(_, defid, _, None) = pat[0].node,
|
||||||
let ExprPath(QPath::Resolved(None, ref path)) = arm.body.node,
|
let ExprPath(QPath::Resolved(None, ref path)) = arm.body.node,
|
||||||
path.def.def_id() == defid,
|
let Def::Local(lid) = path.def,
|
||||||
|
lid == defid,
|
||||||
], {
|
], {
|
||||||
return true;
|
return true;
|
||||||
}}
|
}}
|
||||||
|
|||||||
Reference in New Issue
Block a user