diff --git a/Cargo.lock b/Cargo.lock index d4ce1aaa4..a255b5ab9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9,8 +9,8 @@ dependencies = [ "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)", "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_derive 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.14 (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)", ] @@ -61,8 +61,8 @@ name = "cargo_metadata" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 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.14 (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)", "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)", - "serde 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 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.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -289,22 +289,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde" -version = "1.0.12" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde_derive" -version = "1.0.12" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "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)", ] [[package]] name = "serde_derive_internals" -version = "0.15.1" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "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)", "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)", - "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]] @@ -364,7 +364,7 @@ name = "toml" version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" 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]] @@ -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 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 serde 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)" = "7f61b753dd58ec5d4c735f794dbddde1f28b977f652afbcde89d75bc77902216" -"checksum serde_derive 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)" = "2a169fa5384d751ada1da9f3992b81830151a03c875e40dcb37c9fb31aafc68f" -"checksum serde_derive_internals 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)" = "37aee4e0da52d801acfbc0cc219eb1eda7142112339726e427926a6f6ee65d3a" +"checksum serde 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)" = "bcb6a7637a47663ee073391a139ed07851f27ed2532c2abc88c6bf27a16cdf34" +"checksum serde_derive 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)" = "812ff66056fd9a9a5b7c119714243b0862cf98340e7d4b5ee05a932c40d5ea6c" +"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 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" diff --git a/clippy_lints/src/attrs.rs b/clippy_lints/src/attrs.rs index 12339c039..83ec32615 100644 --- a/clippy_lints/src/attrs.rs +++ b/clippy_lints/src/attrs.rs @@ -7,7 +7,7 @@ use rustc::ty::{self, TyCtxt}; use semver::Version; use syntax::ast::{Attribute, Lit, LitKind, MetaItemKind, NestedMetaItem, NestedMetaItemKind}; 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)]`, /// 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(None) | ExprBreak(_, None) => false, 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(); - !match_def_path(tcx, fun_id, &paths::BEGIN_PANIC) + 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) + } else { + true + } } else { true }, diff --git a/clippy_lints/src/drop_forget_ref.rs b/clippy_lints/src/drop_forget_ref.rs index 6ca04d400..46b228e70 100644 --- a/clippy_lints/src/drop_forget_ref.rs +++ b/clippy_lints/src/drop_forget_ref.rs @@ -1,7 +1,7 @@ use rustc::lint::*; use rustc::ty; 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 /// 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 ExprPath(ref qpath) = path.node, 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 msg; let arg = &args[0]; diff --git a/clippy_lints/src/eval_order_dependence.rs b/clippy_lints/src/eval_order_dependence.rs index 621438b9a..42af59712 100644 --- a/clippy_lints/src/eval_order_dependence.rs +++ b/clippy_lints/src/eval_order_dependence.rs @@ -1,8 +1,8 @@ -use rustc::hir::def_id::DefId; use rustc::hir::intravisit::{walk_expr, NestedVisitorMap, Visitor}; use rustc::hir::*; use rustc::ty; use rustc::lint::*; +use syntax::ast; 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 @@ -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 { if let QPath::Resolved(_, ref path) = *qpath { if path.segments.len() == 1 { - let var = cx.tables.qpath_def(qpath, lhs.hir_id).def_id(); - let mut visitor = ReadVisitor { - cx: cx, - var: var, - write_expr: expr, - last_expr: expr, - }; - check_for_unsequenced_reads(&mut visitor); + if let def::Def::Local(var) = cx.tables.qpath_def(qpath, lhs.hir_id) { + let mut visitor = ReadVisitor { + cx: cx, + var: var, + write_expr: expr, + last_expr: expr, + }; + 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> { cx: &'a LateContext<'a, 'tcx>, /// 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 /// in the lint). write_expr: &'tcx Expr, @@ -297,22 +298,23 @@ impl<'a, 'tcx> Visitor<'tcx> for ReadVisitor<'a, 'tcx> { match expr.node { ExprPath(ref qpath) => { - if let QPath::Resolved(None, ref path) = *qpath { - if path.segments.len() == 1 && self.cx.tables.qpath_def(qpath, expr.hir_id).def_id() == self.var { - if is_in_assignment_position(self.cx, expr) { - // This is a write, not a read. - } else { - span_note_and_lint( - self.cx, - EVAL_ORDER_DEPENDENCE, - expr.span, - "unsequenced read of a variable", - self.write_expr.span, - "whether read occurs before this write depends on evaluation order" - ); - } - } - } + if_let_chain! {[ + let QPath::Resolved(None, ref path) = *qpath, + path.segments.len() == 1, + let def::Def::Local(local_id) = self.cx.tables.qpath_def(qpath, expr.hir_id), + local_id == self.var, + // Check that this is a read, not a write. + !is_in_assignment_position(self.cx, expr), + ], { + span_note_and_lint( + self.cx, + EVAL_ORDER_DEPENDENCE, + 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 // if) the closure will be evaluated, any reads in it might not diff --git a/clippy_lints/src/format.rs b/clippy_lints/src/format.rs index 2577e2908..f1a450e58 100644 --- a/clippy_lints/src/format.rs +++ b/clippy_lints/src/format.rs @@ -5,7 +5,7 @@ use rustc::ty; use syntax::ast::LitKind; use syntax::symbol::InternedString; 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 /// argument")` and `format!("{}", foo)` where `foo` is a string. @@ -47,7 +47,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { if_let_chain!{[ let ExprPath(ref qpath) = fun.node, 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 check_static_str(cx, &args[0]), // 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, args.len() == 2, 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])); diff --git a/clippy_lints/src/functions.rs b/clippy_lints/src/functions.rs index 869e621ea..def357c55 100644 --- a/clippy_lints/src/functions.rs +++ b/clippy_lints/src/functions.rs @@ -2,6 +2,7 @@ use rustc::hir::intravisit; use rustc::hir; use rustc::lint::*; use rustc::ty; +use rustc::hir::def::Def; use std::collections::HashSet; use syntax::ast; use syntax::abi::Abi; @@ -166,9 +167,9 @@ impl<'a, 'tcx> Functions { } } -fn raw_ptr_arg(arg: &hir::Arg, ty: &hir::Ty) -> Option { - if let (&hir::PatKind::Binding(_, def_id, _, _), &hir::TyPtr(_)) = (&arg.pat.node, &ty.node) { - Some(def_id) +fn raw_ptr_arg(arg: &hir::Arg, ty: &hir::Ty) -> Option { + if let (&hir::PatKind::Binding(_, id, _, _), &hir::TyPtr(_)) = (&arg.pat.node, &ty.node) { + Some(id) } else { None } @@ -176,7 +177,7 @@ fn raw_ptr_arg(arg: &hir::Arg, ty: &hir::Ty) -> Option { struct DerefVisitor<'a, 'tcx: 'a> { cx: &'a LateContext<'a, 'tcx>, - ptrs: HashSet, + ptrs: HashSet, 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> { fn check_arg(&self, ptr: &hir::Expr) { if let hir::ExprPath(ref qpath) = ptr.node { - let def = self.cx.tables.qpath_def(qpath, ptr.hir_id); - if self.ptrs.contains(&def.def_id()) { - span_lint( - self.cx, - NOT_UNSAFE_PTR_ARG_DEREF, - ptr.span, - "this public function dereferences a raw pointer but is not marked `unsafe`", - ); + if let Def::Local(id) = self.cx.tables.qpath_def(qpath, ptr.hir_id) { + if self.ptrs.contains(&id) { + span_lint( + self.cx, + NOT_UNSAFE_PTR_ARG_DEREF, + ptr.span, + "this public function dereferences a raw pointer but is not marked `unsafe`", + ); + } } } } diff --git a/clippy_lints/src/let_if_seq.rs b/clippy_lints/src/let_if_seq.rs index 9812c7591..789dee6b0 100644 --- a/clippy_lints/src/let_if_seq.rs +++ b/clippy_lints/src/let_if_seq.rs @@ -1,6 +1,8 @@ use rustc::lint::*; use rustc::hir; use rustc::hir::BindingAnnotation; +use rustc::hir::def::Def; +use syntax::ast; use utils::{snippet, span_lint_and_then}; /// **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 hir::StmtDecl(ref decl, _) = stmt.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::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 Some(value) = check_assign(cx, def_id, &*then), - !used_in_expr(cx, def_id, value), + let Some(value) = check_assign(cx, canonical_id, &*then), + !used_in_expr(cx, canonical_id, value), ], { let span = stmt.span.to(if_.span); let (default_multi_stmts, default) = if let Some(ref else_) = *else_ { 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 if let Some(ref default) = decl.init { (true, &**default) @@ -130,7 +132,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LetIfSeq { struct UsedVisitor<'a, 'tcx: 'a> { cx: &'a LateContext<'a, 'tcx>, - id: hir::def_id::DefId, + id: ast::NodeId, 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) { if_let_chain! {[ 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; return; @@ -152,7 +155,7 @@ impl<'a, 'tcx> hir::intravisit::Visitor<'tcx> for UsedVisitor<'a, 'tcx> { fn check_assign<'a, 'tcx>( cx: &LateContext<'a, 'tcx>, - decl: hir::def_id::DefId, + decl: ast::NodeId, block: &'tcx hir::Block, ) -> Option<&'tcx hir::Expr> { if_let_chain! {[ @@ -161,7 +164,8 @@ fn check_assign<'a, 'tcx>( let hir::StmtSemi(ref expr, _) = expr.node, let hir::ExprAssign(ref var, ref value) = expr.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 { cx: cx, @@ -183,7 +187,7 @@ fn check_assign<'a, 'tcx>( 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 { cx: cx, id: id, diff --git a/clippy_lints/src/loops.rs b/clippy_lints/src/loops.rs index 4452cee86..f8ed04222 100644 --- a/clippy_lints/src/loops.rs +++ b/clippy_lints/src/loops.rs @@ -2,7 +2,6 @@ use itertools::Itertools; use reexport::*; use rustc::hir::*; 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::map::Node::{NodeBlock, NodeExpr, NodeStmt}; use rustc::lint::*; @@ -594,13 +593,14 @@ fn check_for_loop<'a, 'tcx>( 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! {[ let ExprPath(ref qpath) = expr.node, let QPath::Resolved(None, ref path) = *qpath, path.segments.len() == 1, + let Def::Local(local_id) = cx.tables.qpath_def(qpath, expr.hir_id), // our variable! - cx.tables.qpath_def(qpath, expr.hir_id).def_id() == var + local_id == var ], { 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) } -fn get_fixed_offset_var<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &Expr, var: DefId) -> Option { - fn extract_offset<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, e: &Expr, var: DefId) -> Option { +fn get_fixed_offset_var<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &Expr, var: ast::NodeId) -> Option { + fn extract_offset<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, e: &Expr, var: ast::NodeId) -> Option { match e.node { ExprLit(ref l) => match l.node { 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>( cx: &LateContext<'a, 'tcx>, body: &Expr, - var: DefId, + var: ast::NodeId, ) -> Vec<(FixedOffsetVar, FixedOffsetVar)> { fn get_assignment<'a, 'tcx>( cx: &LateContext<'a, 'tcx>, e: &Expr, - var: DefId, + var: ast::NodeId, ) -> Option<(FixedOffsetVar, FixedOffsetVar)> { 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)) { @@ -759,7 +759,7 @@ fn detect_manual_memcpy<'a, 'tcx>( }) = higher::range(arg) { // 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 { match (&arg1.value[..], arg1.negate, &arg2.value[..], arg2.negate) { ("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 // 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 .into_iter() @@ -852,10 +852,10 @@ fn check_for_loop_range<'a, 'tcx>( }) = higher::range(arg) { // 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 { cx: cx, - var: def_id, + var: canonical_id, indexed: HashMap::new(), referenced: HashSet::new(), 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>, - def_id: DefId, + local: ast::NodeId, 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) { - if same_var(self.cx, expr, self.def_id) { + if same_var(self.cx, expr, self.local) { self.used = true; } else { walk_expr(self, expr); @@ -1322,7 +1322,7 @@ struct VarVisitor<'a, 'tcx: 'a> { /// context reference cx: &'a LateContext<'a, 'tcx>, /// var name to look for as index - var: DefId, + var: ast::NodeId, /// indexed variables, the extend is `None` for global indexed: HashMap>, /// 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, ], { let index_used = same_var(self.cx, idx, self.var) || { - let mut used_visitor = DefIdUsedVisitor { + let mut used_visitor = LocalUsedVisitor { cx: self.cx, - def_id: self.var, + local: self.var, used: false, }; walk_expr(&mut used_visitor, idx); @@ -1356,9 +1356,7 @@ impl<'a, 'tcx> Visitor<'tcx> for VarVisitor<'a, 'tcx> { if index_used { let def = self.cx.tables.qpath_def(seqpath, seqexpr.hir_id); match def { - Def::Local(..) | Def::Upvar(..) => { - 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"); + Def::Local(node_id) | Def::Upvar(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); @@ -1381,8 +1379,9 @@ impl<'a, 'tcx> Visitor<'tcx> for VarVisitor<'a, 'tcx> { let ExprPath(ref qpath) = expr.node, let QPath::Resolved(None, ref path) = *qpath, 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 self.nonindex = true; } else { @@ -1672,11 +1671,7 @@ impl<'a, 'tcx> Visitor<'tcx> for InitializeVisitor<'a, 'tcx> { fn var_def_id(cx: &LateContext, expr: &Expr) -> Option { if let ExprPath(ref qpath) = expr.node { let path_res = cx.tables.qpath_def(qpath, expr.hir_id); - if let Def::Local(def_id) = path_res { - let node_id = cx.tcx - .hir - .as_local_node_id(def_id) - .expect("That DefId should be valid"); + if let Def::Local(node_id) = path_res { return Some(node_id); } } diff --git a/clippy_lints/src/mem_forget.rs b/clippy_lints/src/mem_forget.rs index 9058d0d10..43409eaea 100644 --- a/clippy_lints/src/mem_forget.rs +++ b/clippy_lints/src/mem_forget.rs @@ -1,6 +1,6 @@ use rustc::lint::*; 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 /// `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) { if let ExprCall(ref path_expr, ref args) = e.node { if let ExprPath(ref qpath) = path_expr.node { - let def_id = cx.tables.qpath_def(qpath, path_expr.hir_id).def_id(); - if match_def_path(cx.tcx, def_id, &paths::MEM_FORGET) { - let forgot_ty = cx.tables.expr_ty(&args[0]); + 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) { + let forgot_ty = cx.tables.expr_ty(&args[0]); - if match forgot_ty.ty_adt_def() { - Some(def) => def.has_dtor(cx.tcx), - _ => false, - } { - span_lint(cx, MEM_FORGET, e.span, "usage of mem::forget on Drop type"); + if match forgot_ty.ty_adt_def() { + Some(def) => def.has_dtor(cx.tcx), + _ => false, + } { + span_lint(cx, MEM_FORGET, e.span, "usage of mem::forget on Drop type"); + } } } } diff --git a/clippy_lints/src/minmax.rs b/clippy_lints/src/minmax.rs index aea923117..bcdbd738e 100644 --- a/clippy_lints/src/minmax.rs +++ b/clippy_lints/src/minmax.rs @@ -2,7 +2,7 @@ use consts::{constant_simple, Constant}; use rustc::lint::*; use rustc::hir::*; 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 /// 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)> { if let ExprCall(ref path, ref args) = expr.node { if let ExprPath(ref qpath) = path.node { - let def_id = cx.tables.qpath_def(qpath, path.hir_id).def_id(); - - if match_def_path(cx.tcx, def_id, &paths::CMP_MIN) { - fetch_const(cx, args, MinMax::Min) - } else if match_def_path(cx.tcx, def_id, &paths::CMP_MAX) { - fetch_const(cx, args, MinMax::Max) - } else { - None - } + 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) { + fetch_const(cx, args, MinMax::Min) + } else if match_def_path(cx.tcx, def_id, &paths::CMP_MAX) { + fetch_const(cx, args, MinMax::Max) + } else { + None + } + }) } else { None } diff --git a/clippy_lints/src/misc.rs b/clippy_lints/src/misc.rs index fcb29439a..2c764109e 100644 --- a/clippy_lints/src/misc.rs +++ b/clippy_lints/src/misc.rs @@ -574,11 +574,7 @@ fn in_attributes_expansion(expr: &Expr) -> bool { /// Test whether `def` is a variable defined outside a macro. fn non_macro_local(cx: &LateContext, def: &def::Def) -> bool { match *def { - def::Def::Local(def_id) | def::Def::Upvar(def_id, _, _) => { - let id = cx.tcx - .hir - .as_local_node_id(def_id) - .expect("local variables should be found in the same crate"); + def::Def::Local(id) | def::Def::Upvar(id, _, _) => { !in_macro(cx.tcx.hir.span(id)) }, _ => false, diff --git a/clippy_lints/src/needless_pass_by_value.rs b/clippy_lints/src/needless_pass_by_value.rs index da3bfc759..4a7a04292 100644 --- a/clippy_lints/src/needless_pass_by_value.rs +++ b/clippy_lints/src/needless_pass_by_value.rs @@ -1,6 +1,5 @@ use rustc::hir::*; use rustc::hir::intravisit::FnKind; -use rustc::hir::def_id::DefId; use rustc::lint::*; use rustc::ty::{self, TypeFoldable}; use rustc::traits; @@ -129,8 +128,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessPassByValue { !implements_trait(cx, ty, asref_trait, &[]), !implements_borrow_trait, - let PatKind::Binding(mode, defid, ..) = arg.pat.node, - !moved_vars.contains(&defid), + let PatKind::Binding(mode, canonical_id, ..) = arg.pat.node, + !moved_vars.contains(&canonical_id), ], { // Note: `toplevel_ref_arg` warns if `BindByRef` if mode == BindingAnnotation::Mutable || mode == BindingAnnotation::RefMut { @@ -139,7 +138,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessPassByValue { // Suggestion logic 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! {[ match_type(cx, ty, &paths::VEC), 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> { cx: &'a LateContext<'a, 'tcx>, - moved_vars: HashSet, + moved_vars: HashSet, /// Spans which need to be prefixed with `*` for dereferencing the /// suggested additional /// reference. - spans_need_deref: HashMap>, + spans_need_deref: HashMap>, } 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>) { let cmt = unwrap_downcast_or_interior(cmt); - if_let_chain! {[ - let mc::Categorization::Local(vid) = cmt.cat, - let Some(def_id) = self.cx.tcx.hir.opt_local_def_id(vid), - ], { - self.moved_vars.insert(def_id); - }} + if let mc::Categorization::Local(vid) = cmt.cat { + self.moved_vars.insert(vid); + } } 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! {[ 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; loop { @@ -235,7 +230,7 @@ impl<'a, 'tcx> MovedVariablesCtxt<'a, 'tcx> { // `match` and `if let` if let ExprMatch(ref c, ..) = e.node { self.spans_need_deref - .entry(def_id) + .entry(vid) .or_insert_with(HashSet::new) .insert(c.span); } @@ -248,7 +243,7 @@ impl<'a, 'tcx> MovedVariablesCtxt<'a, 'tcx> { let DeclLocal(ref local) = decl.node, ], { self.spans_need_deref - .entry(def_id) + .entry(vid) .or_insert_with(HashSet::new) .insert(local.init .as_ref() diff --git a/clippy_lints/src/panic.rs b/clippy_lints/src/panic.rs index a05087318..f04285344 100644 --- a/clippy_lints/src/panic.rs +++ b/clippy_lints/src/panic.rs @@ -1,7 +1,7 @@ use rustc::hir::*; use rustc::lint::*; 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!`. /// @@ -40,7 +40,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { let ExprCall(ref fun, ref params) = ex.node, params.len() == 2, 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, is_direct_expn_of(expr.span, "panic").is_some(), let LitKind::Str(ref string, _) = lit.node, diff --git a/clippy_lints/src/print.rs b/clippy_lints/src/print.rs index 9aca75433..1f24a7af0 100644 --- a/clippy_lints/src/print.rs +++ b/clippy_lints/src/print.rs @@ -1,7 +1,7 @@ use rustc::hir::*; use rustc::hir::map::Node::{NodeImplItem, NodeItem}; 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 format::get_argument_fmtstr_parts; @@ -72,9 +72,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { if_let_chain! {[ let ExprCall(ref fun, ref args) = expr.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 // `print!` expansion. @@ -96,9 +95,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { args.len() == 1, let ExprCall(ref args_fun, ref args_args) = args[0].node, let ExprPath(ref qpath) = args_fun.node, - match_def_path(cx.tcx, - resolve_node(cx, qpath, args_fun.hir_id).def_id(), - &paths::FMT_ARGUMENTS_NEWV1), + let Some(const_def_id) = opt_def_id(resolve_node(cx, qpath, args_fun.hir_id)), + match_def_path(cx.tcx, const_def_id, &paths::FMT_ARGUMENTS_NEWV1), args_args.len() == 2, let ExprAddrOf(_, ref match_expr) = args_args[1].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)` else if args.len() == 2 && match_def_path(cx.tcx, fun_id, &paths::FMT_ARGUMENTV1_NEW) { if let ExprPath(ref qpath) = args[1].node { - let def_id = cx.tables.qpath_def(qpath, args[1].hir_id).def_id(); - 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() { - span_lint(cx, USE_DEBUG, args[0].span, "use of `Debug`-based formatting"); + 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) && is_expn_of(expr.span, "panic").is_none() { + span_lint(cx, USE_DEBUG, args[0].span, "use of `Debug`-based formatting"); + } } } } diff --git a/clippy_lints/src/regex.rs b/clippy_lints/src/regex.rs index 8b5dedfcc..a18bf6286 100644 --- a/clippy_lints/src/regex.rs +++ b/clippy_lints/src/regex.rs @@ -9,7 +9,7 @@ use std::error::Error; use syntax::ast::{LitKind, NodeId}; use syntax::codemap::{BytePos, Span}; 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 /// (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 ExprPath(ref qpath) = fun.node, 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) || match_def_path(cx.tcx, def_id, &paths::REGEX_BUILDER_NEW) { check_regex(cx, &args[0], true); diff --git a/clippy_lints/src/transmute.rs b/clippy_lints/src/transmute.rs index a590bf744..18b80c768 100644 --- a/clippy_lints/src/transmute.rs +++ b/clippy_lints/src/transmute.rs @@ -2,7 +2,7 @@ use rustc::lint::*; use rustc::ty::{self, Ty}; use rustc::hir::*; 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 /// 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) { if let ExprCall(ref path_expr, ref args) = e.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) { - let from_ty = cx.tables.expr_ty(&args[0]); - let to_ty = cx.tables.expr_ty(e); + if match_def_path(cx.tcx, def_id, &paths::TRANSMUTE) { + let from_ty = cx.tables.expr_ty(&args[0]); + let to_ty = cx.tables.expr_ty(e); - match (&from_ty.sty, &to_ty.sty) { - _ if from_ty == to_ty => span_lint( - cx, - USELESS_TRANSMUTE, - e.span, - &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 + match (&from_ty.sty, &to_ty.sty) { + _ if from_ty == to_ty => span_lint( + cx, + USELESS_TRANSMUTE, + e.span, + &format!("transmute from a type (`{}`) to itself", from_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 + (&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()); + }, ), - |db| { - let arg = sugg::Sugg::hir(cx, &args[0], ".."); - let (deref, cast) = if to_rty.mutbl == Mutability::MutMutable { - ("&mut *", "*mut") - } else { - ("&*", "*const") - }; + (&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::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 { - arg - } else { - arg.as_ty(&format!("{} {}", cast, get_type_snippet(cx, qpath, to_rty.ty))) - }; + let arg = if from_pty.ty == to_rty.ty { + arg + } else { + 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()); - }, - ), - _ => return, - }; + db.span_suggestion(e.span, "try", sugg::make_unop(deref, arg).to_string()); + }, + ), + _ => return, + }; + } } } } diff --git a/clippy_lints/src/utils/higher.rs b/clippy_lints/src/utils/higher.rs index 09e40aea8..550ecedea 100644 --- a/clippy_lints/src/utils/higher.rs +++ b/clippy_lints/src/utils/higher.rs @@ -6,7 +6,7 @@ use rustc::hir; use rustc::lint::LateContext; 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. pub fn binop(op: hir::BinOp_) -> ast::BinOpKind { @@ -181,13 +181,13 @@ pub fn vec_macro<'e>(cx: &LateContext, expr: &'e hir::Expr) -> Option { - 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); if let Some(ref src) = source.dylib { println!("extern crate dylib source: {:?}", src.0); diff --git a/clippy_lints/src/utils/mod.rs b/clippy_lints/src/utils/mod.rs index 8e816ffbf..5157d416b 100644 --- a/clippy_lints/src/utils/mod.rs +++ b/clippy_lints/src/utils/mod.rs @@ -950,12 +950,10 @@ pub fn opt_def_id(def: Def) -> Option { Def::Method(id) | Def::Const(id) | Def::AssociatedConst(id) | - Def::Local(id) | - Def::Upvar(id, ..) | Def::Macro(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..]), let PatKind::Binding(_, defid, _, None) = pat[0].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; }}