Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# Change Log
All notable changes to this project will be documented in this file.

## 0.0.104 — 2016-12-01
* Update to *rustc 1.15.0-nightly (1c448574b 2016-11-28)*

## 0.0.103 — 2016-11-25
* Update to *rustc 1.15.0-nightly (d5814b03e 2016-11-23)*

Expand Down
8 changes: 4 additions & 4 deletions clippy_lints/src/attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,15 +105,15 @@ impl LateLintPass for AttrPass {
}
match item.node {
ItemExternCrate(_) |
ItemUse(_) => {
ItemUse(_, _) => {
for attr in &item.attrs {
if let MetaItemKind::List(ref lint_list) = attr.value.node {
match &*attr.name().as_str() {
"allow" | "warn" | "deny" | "forbid" => {
// whitelist `unused_imports`
for lint in lint_list {
if is_word(lint, "unused_imports") {
if let ItemUse(_) = item.node {
if let ItemUse(_, _) = item.node {
return;
}
}
Expand Down Expand Up @@ -193,8 +193,8 @@ fn is_relevant_expr(cx: &LateContext, expr: &Expr) -> bool {
ExprRet(Some(ref e)) => is_relevant_expr(cx, e),
ExprRet(None) | ExprBreak(_, None) => false,
ExprCall(ref path_expr, _) => {
if let ExprPath(..) = path_expr.node {
let fun_id = resolve_node(cx, path_expr.id).expect("function should be resolved").def_id();
if let ExprPath(ref qpath) = path_expr.node {
let fun_id = resolve_node(cx, qpath, path_expr.id).def_id();
!match_def_path(cx, fun_id, &paths::BEGIN_PANIC)
} else {
true
Expand Down
19 changes: 7 additions & 12 deletions clippy_lints/src/bit_mask.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use rustc::hir::*;
use rustc::hir::def::{Def, PathResolution};
use rustc::hir::def::Def;
use rustc::lint::*;
use rustc_const_eval::lookup_const_by_id;
use syntax::ast::LitKind;
Expand Down Expand Up @@ -245,18 +245,13 @@ fn fetch_int_literal(cx: &LateContext, lit: &Expr) -> Option<u64> {
None
}
}
ExprPath(_, _) => {
{
// Important to let the borrow expire before the const lookup to avoid double
// borrowing.
let def_map = cx.tcx.def_map.borrow();
match def_map.get(&lit.id) {
Some(&PathResolution { base_def: Def::Const(def_id), .. }) => Some(def_id),
_ => None,
}
ExprPath(ref qpath) => {
let def = cx.tcx.tables().qpath_def(qpath, lit.id);
if let Def::Const(def_id) = def {
lookup_const_by_id(cx.tcx, def_id, None).and_then(|(l, _ty)| fetch_int_literal(cx, l))
} else {
None
}
.and_then(|def_id| lookup_const_by_id(cx.tcx, def_id, None))
.and_then(|(l, _ty)| fetch_int_literal(cx, l))
}
_ => None,
}
Expand Down
2 changes: 1 addition & 1 deletion clippy_lints/src/blacklisted_name.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ impl LintPass for BlackListedName {

impl LateLintPass for BlackListedName {
fn check_pat(&mut self, cx: &LateContext, pat: &Pat) {
if let PatKind::Binding(_, ref ident, _) = pat.node {
if let PatKind::Binding(_, _, ref ident, _) = pat.node {
if self.blacklist.iter().any(|s| s == &*ident.node.as_str()) {
span_lint(cx,
BLACKLISTED_NAME,
Expand Down
33 changes: 17 additions & 16 deletions clippy_lints/src/consts.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#![allow(cast_possible_truncation)]

use rustc::lint::LateContext;
use rustc::hir::def::{Def, PathResolution};
use rustc::hir::def::Def;
use rustc_const_eval::lookup_const_by_id;
use rustc_const_math::{ConstInt, ConstUsize, ConstIsize};
use rustc::hir::*;
Expand All @@ -10,7 +10,7 @@ use std::cmp::PartialOrd;
use std::hash::{Hash, Hasher};
use std::mem;
use std::rc::Rc;
use syntax::ast::{FloatTy, LitIntType, LitKind, StrStyle, UintTy, IntTy};
use syntax::ast::{FloatTy, LitIntType, LitKind, StrStyle, UintTy, IntTy, NodeId};
use syntax::ptr::P;

#[derive(Debug, Copy, Clone)]
Expand Down Expand Up @@ -252,7 +252,7 @@ impl<'c, 'cc> ConstEvalLateContext<'c, 'cc> {
/// simple constant folding: Insert an expression, get a constant or none.
fn expr(&mut self, e: &Expr) -> Option<Constant> {
match e.node {
ExprPath(_, _) => self.fetch_path(e),
ExprPath(ref qpath) => self.fetch_path(qpath, e.id),
ExprBlock(ref block) => self.block(block),
ExprIf(ref cond, ref then, ref otherwise) => self.ifthenelse(cond, then, otherwise),
ExprLit(ref lit) => Some(lit_to_constant(&lit.node)),
Expand Down Expand Up @@ -285,21 +285,22 @@ impl<'c, 'cc> ConstEvalLateContext<'c, 'cc> {
}

/// lookup a possibly constant expression from a ExprPath
fn fetch_path(&mut self, e: &Expr) -> Option<Constant> {
fn fetch_path(&mut self, qpath: &QPath, id: NodeId) -> Option<Constant> {
if let Some(lcx) = self.lcx {
let mut maybe_id = None;
if let Some(&PathResolution { base_def: Def::Const(id), .. }) = lcx.tcx.def_map.borrow().get(&e.id) {
maybe_id = Some(id);
}
// separate if lets to avoid double borrowing the def_map
if let Some(id) = maybe_id {
if let Some((const_expr, _ty)) = lookup_const_by_id(lcx.tcx, id, None) {
let ret = self.expr(const_expr);
if ret.is_some() {
self.needed_resolution = true;
let def = lcx.tcx.tables().qpath_def(qpath, id);
match def {
Def::Const(def_id) | Def::AssociatedConst(def_id) => {
let substs = Some(lcx.tcx.tables().node_id_item_substs(id)
.unwrap_or_else(|| lcx.tcx.intern_substs(&[])));
if let Some((const_expr, _ty)) = lookup_const_by_id(lcx.tcx, def_id, substs) {
let ret = self.expr(const_expr);
if ret.is_some() {
self.needed_resolution = true;
}
return ret;
}
return ret;
}
},
_ => {},
}
}
None
Expand Down
2 changes: 1 addition & 1 deletion clippy_lints/src/copies.rs
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ fn bindings<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, pat: &Pat) -> HashMap<Interned
bindings_impl(cx, pat, map);
}
}
PatKind::Binding(_, ref ident, ref as_pat) => {
PatKind::Binding(_, _, ref ident, ref as_pat) => {
if let Entry::Vacant(v) = map.entry(ident.node.as_str()) {
v.insert(cx.tcx.tables().pat_ty(pat));
}
Expand Down
6 changes: 3 additions & 3 deletions clippy_lints/src/derive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use rustc::ty;
use rustc::hir::*;
use syntax::codemap::Span;
use utils::paths;
use utils::{is_automatically_derived, match_path, span_lint_and_then};
use utils::{is_automatically_derived, span_lint_and_then, match_path_old};

/// **What it does:** Checks for deriving `Hash` but implementing `PartialEq`
/// explicitly.
Expand Down Expand Up @@ -89,7 +89,7 @@ impl LateLintPass for Derive {
fn check_hash_peq<'a, 'tcx: 'a>(cx: &LateContext<'a, 'tcx>, span: Span, trait_ref: &TraitRef, ty: ty::Ty<'tcx>,
hash_is_automatically_derived: bool) {
if_let_chain! {[
match_path(&trait_ref.path, &paths::HASH),
match_path_old(&trait_ref.path, &paths::HASH),
let Some(peq_trait_def_id) = cx.tcx.lang_items.eq_trait()
], {
let peq_trait_def = cx.tcx.lookup_trait_def(peq_trait_def_id);
Expand Down Expand Up @@ -131,7 +131,7 @@ fn check_hash_peq<'a, 'tcx: 'a>(cx: &LateContext<'a, 'tcx>, span: Span, trait_re

/// Implementation of the `EXPL_IMPL_CLONE_ON_COPY` lint.
fn check_copy_clone<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, item: &Item, trait_ref: &TraitRef, ty: ty::Ty<'tcx>) {
if match_path(&trait_ref.path, &paths::CLONE_TRAIT) {
if match_path_old(&trait_ref.path, &paths::CLONE_TRAIT) {
let parameter_environment = ty::ParameterEnvironment::for_item(cx.tcx, item.id);
let subst_ty = ty.subst(cx.tcx, parameter_environment.free_substs);

Expand Down
4 changes: 2 additions & 2 deletions clippy_lints/src/drop_ref.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ impl LintPass for Pass {
impl LateLintPass for Pass {
fn check_expr(&mut self, cx: &LateContext, expr: &Expr) {
if let ExprCall(ref path, ref args) = expr.node {
if let ExprPath(None, _) = path.node {
let def_id = cx.tcx.expect_def(path.id).def_id();
if let ExprPath(ref qpath) = path.node {
let def_id = cx.tcx.tables().qpath_def(qpath, path.id).def_id();
if match_def_path(cx, def_id, &paths::DROP) {
if args.len() != 1 {
return;
Expand Down
28 changes: 7 additions & 21 deletions clippy_lints/src/enum_glob_use.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
//! lint on `use`ing all variants of an enum

use rustc::hir::*;
use rustc::hir::def::Def;
use rustc::hir::map::Node::NodeItem;
use rustc::lint::{LateLintPass, LintPass, LateContext, LintArray, LintContext};
use rustc::lint::{LateLintPass, LintPass, LateContext, LintArray};
use syntax::ast::NodeId;
use syntax::codemap::Span;
use utils::span_lint;
Expand Down Expand Up @@ -48,24 +46,12 @@ impl EnumGlobUse {
if item.vis == Visibility::Public {
return; // re-exports are fine
}
if let ItemUse(ref item_use) = item.node {
if let ViewPath_::ViewPathGlob(_) = item_use.node {
if let Some(def) = cx.tcx.def_map.borrow().get(&item.id) {
if let Some(node_id) = cx.tcx.map.as_local_node_id(def.full_def().def_id()) {
if let Some(NodeItem(it)) = cx.tcx.map.find(node_id) {
if let ItemEnum(..) = it.node {
span_lint(cx, ENUM_GLOB_USE, item.span, "don't use glob imports for enum variants");
}
}
} else {
let child = cx.sess().cstore.item_children(def.full_def().def_id());
if let Some(child) = child.first() {
if let Def::Variant(..) = child.def {
span_lint(cx, ENUM_GLOB_USE, item.span, "don't use glob imports for enum variants");
}
}
}
}
if let ItemUse(ref path, UseKind::Glob) = item.node {
// FIXME: ask jseyfried why the qpath.def for `use std::cmp::Ordering::*;`
// extracted through `ItemUse(ref qpath, UseKind::Glob)` is a `Mod` and not an `Enum`
//if let Def::Enum(_) = path.def {
if path.segments.last().and_then(|seg| seg.name.as_str().chars().next()).map_or(false, char::is_uppercase) {
Copy link
Contributor

@mcarton mcarton Dec 2, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you had an answer for that?

span_lint(cx, ENUM_GLOB_USE, item.span, "don't use glob imports for enum variants");
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions clippy_lints/src/eta_reduction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,9 @@ fn check_closure(cx: &LateContext, expr: &Expr) {
_ => (),
}
for (a1, a2) in decl.inputs.iter().zip(args) {
if let PatKind::Binding(_, ident, _) = a1.pat.node {
if let PatKind::Binding(_, _, ident, _) = a1.pat.node {
// XXXManishearth Should I be checking the binding mode here?
if let ExprPath(None, ref p) = a2.node {
if let ExprPath(QPath::Resolved(None, ref p)) = a2.node {
if p.segments.len() != 1 {
// If it's a proper path, it can't be a local variable
return;
Expand Down
50 changes: 27 additions & 23 deletions clippy_lints/src/eval_order_dependence.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,16 +61,18 @@ impl LateLintPass for EvalOrderDependence {
// Find a write to a local variable.
match expr.node {
ExprAssign(ref lhs, _) | ExprAssignOp(_, ref lhs, _) => {
if let ExprPath(None, ref path) = lhs.node {
if path.segments.len() == 1 {
let var = cx.tcx.expect_def(lhs.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 ExprPath(ref qpath) = lhs.node {
if let QPath::Resolved(_, ref path) = *qpath {
if path.segments.len() == 1 {
let var = cx.tcx.tables().qpath_def(qpath, lhs.id).def_id();
let mut visitor = ReadVisitor {
cx: cx,
var: var,
write_expr: expr,
last_expr: expr,
};
check_for_unsequenced_reads(&mut visitor);
}
}
}
}
Expand Down Expand Up @@ -293,19 +295,21 @@ impl<'v, 't> Visitor<'v> for ReadVisitor<'v, 't> {
}

match expr.node {
ExprPath(None, ref path) => {
if path.segments.len() == 1 && self.cx.tcx.expect_def(expr.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"
);
ExprPath(ref qpath) => {
if let QPath::Resolved(None, ref path) = *qpath {
if path.segments.len() == 1 && self.cx.tcx.tables().qpath_def(qpath, expr.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"
);
}
}
}
}
Expand Down
10 changes: 4 additions & 6 deletions clippy_lints/src/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,9 @@ impl LateLintPass for Pass {
// `format!("{}", foo)` expansion
ExprCall(ref fun, ref args) => {
if_let_chain!{[
let ExprPath(..) = fun.node,
let ExprPath(ref qpath) = fun.node,
args.len() == 2,
let Some(fun) = resolve_node(cx, fun.id),
match_def_path(cx, fun.def_id(), &paths::FMT_ARGUMENTS_NEWV1),
match_def_path(cx, resolve_node(cx, qpath, fun.id).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
Expand Down Expand Up @@ -129,9 +128,8 @@ fn check_arg_is_display(cx: &LateContext, expr: &Expr) -> bool {
exprs.len() == 1,
let ExprCall(_, ref args) = exprs[0].node,
args.len() == 2,
let ExprPath(None, _) = args[1].node,
let Some(fun) = resolve_node(cx, args[1].id),
match_def_path(cx, fun.def_id(), &paths::DISPLAY_FMT_METHOD),
let ExprPath(ref qpath) = args[1].node,
match_def_path(cx, resolve_node(cx, qpath, args[1].id).def_id(), &paths::DISPLAY_FMT_METHOD),
], {
let ty = walk_ptrs_ty(cx.tcx.tables().pat_ty(&pat[0]));

Expand Down
11 changes: 6 additions & 5 deletions clippy_lints/src/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,9 +138,9 @@ impl Functions {
}
}

fn raw_ptr_arg(cx: &LateContext, arg: &hir::Arg) -> Option<hir::def_id::DefId> {
if let (&hir::PatKind::Binding(_, _, _), &hir::TyPtr(_)) = (&arg.pat.node, &arg.ty.node) {
cx.tcx.def_map.borrow().get(&arg.pat.id).map(|pr| pr.full_def().def_id())
fn raw_ptr_arg(_cx: &LateContext, arg: &hir::Arg) -> Option<hir::def_id::DefId> {
if let (&hir::PatKind::Binding(_, def_id, _, _), &hir::TyPtr(_)) = (&arg.pat.node, &arg.ty.node) {
Some(def_id)
} else {
None
}
Expand Down Expand Up @@ -183,8 +183,9 @@ impl<'a, 'tcx, 'v> hir::intravisit::Visitor<'v> for DerefVisitor<'a, 'tcx> {

impl<'a, 'tcx: 'a> DerefVisitor<'a, 'tcx> {
fn check_arg(&self, ptr: &hir::Expr) {
if let Some(def) = self.cx.tcx.def_map.borrow().get(&ptr.id) {
if self.ptrs.contains(&def.full_def().def_id()) {
if let hir::ExprPath(ref qpath) = ptr.node {
let def = self.cx.tcx.tables().qpath_def(qpath, ptr.id);
if self.ptrs.contains(&def.def_id()) {
span_lint(self.cx,
NOT_UNSAFE_PTR_ARG_DEREF,
ptr.span,
Expand Down
2 changes: 1 addition & 1 deletion clippy_lints/src/if_let_redundant_pattern_matching.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ impl LateLintPass for Pass {
}
}

PatKind::Path(_, ref path) if match_path(path, &paths::OPTION_NONE) => {
PatKind::Path(ref path) if match_path(path, &paths::OPTION_NONE) => {
"is_none()"
}

Expand Down
Loading