]> git.lizzy.rs Git - rust.git/commitdiff
Merge pull request #1506 from bood/master
authorMartin Carton <cartonmartin+github@gmail.com>
Tue, 7 Feb 2017 17:56:38 +0000 (18:56 +0100)
committerGitHub <noreply@github.com>
Tue, 7 Feb 2017 17:56:38 +0000 (18:56 +0100)
Lint for possible missing comma in an array #1177

43 files changed:
CHANGELOG.md
Cargo.toml
README.md
clippy_lints/Cargo.toml
clippy_lints/src/assign_ops.rs
clippy_lints/src/attrs.rs
clippy_lints/src/block_in_if_condition.rs
clippy_lints/src/consts.rs
clippy_lints/src/cyclomatic_complexity.rs
clippy_lints/src/derive.rs
clippy_lints/src/empty_enum.rs [new file with mode: 0644]
clippy_lints/src/entry.rs
clippy_lints/src/enum_clike.rs
clippy_lints/src/escape.rs
clippy_lints/src/eta_reduction.rs
clippy_lints/src/eval_order_dependence.rs
clippy_lints/src/format.rs
clippy_lints/src/functions.rs
clippy_lints/src/large_enum_variant.rs
clippy_lints/src/len_zero.rs
clippy_lints/src/let_if_seq.rs
clippy_lints/src/lib.rs
clippy_lints/src/lifetimes.rs
clippy_lints/src/loops.rs
clippy_lints/src/map_clone.rs
clippy_lints/src/methods.rs
clippy_lints/src/misc.rs
clippy_lints/src/missing_doc.rs
clippy_lints/src/mut_mut.rs
clippy_lints/src/new_without_default.rs
clippy_lints/src/print.rs
clippy_lints/src/ptr.rs
clippy_lints/src/shadow.rs
clippy_lints/src/types.rs
clippy_lints/src/unused_label.rs
clippy_lints/src/utils/hir.rs
clippy_lints/src/utils/inspector.rs
clippy_lints/src/utils/internal_lints.rs
clippy_lints/src/utils/mod.rs
clippy_lints/src/vec.rs
tests/compile-fail/empty_enum.rs [new file with mode: 0644]
tests/compile-fail/enum_glob_use.rs
tests/compile-fail/methods.rs

index 4b378a487fa8dab456cb1ccae8e4177a55784ef4..42df561a6e12c9c56984fc994444592693506f81 100644 (file)
@@ -1,6 +1,11 @@
 # Change Log
 All notable changes to this project will be documented in this file.
 
+## 0.0.113 — 2017-02-04
+* Rustup to *rustc 1.16.0-nightly (eedaa94e3 2017-02-02)*
+* New lint: [`large_enum_variant`]
+* `explicit_into_iter_loop` provides suggestions
+
 ## 0.0.112 — 2017-01-27
 * Rustup to *rustc 1.16.0-nightly (df8debf6d 2017-01-25)*
 
@@ -301,6 +306,7 @@ All notable changes to this project will be documented in this file.
 [`double_parens`]: https://github.com/Manishearth/rust-clippy/wiki#double_parens
 [`drop_ref`]: https://github.com/Manishearth/rust-clippy/wiki#drop_ref
 [`duplicate_underscore_argument`]: https://github.com/Manishearth/rust-clippy/wiki#duplicate_underscore_argument
+[`empty_enum`]: https://github.com/Manishearth/rust-clippy/wiki#empty_enum
 [`empty_loop`]: https://github.com/Manishearth/rust-clippy/wiki#empty_loop
 [`enum_clike_unportable_variant`]: https://github.com/Manishearth/rust-clippy/wiki#enum_clike_unportable_variant
 [`enum_glob_use`]: https://github.com/Manishearth/rust-clippy/wiki#enum_glob_use
index 23c559d345b72aff06a840796b19e1779e6014a2..e46d3363a0d15db1b7aaf17d86de0410d47dbfc8 100644 (file)
@@ -1,6 +1,6 @@
 [package]
 name = "clippy"
-version = "0.0.112"
+version = "0.0.113"
 authors = [
        "Manish Goregaokar <manishsmail@gmail.com>",
        "Andre Bogus <bogusandre@gmail.com>",
@@ -30,7 +30,7 @@ test = false
 
 [dependencies]
 # begin automatic update
-clippy_lints = { version = "0.0.112", path = "clippy_lints" }
+clippy_lints = { version = "0.0.113", path = "clippy_lints" }
 # end automatic update
 cargo_metadata = "0.1.1"
 
index 1e959b981f29c7d416f626c3f8b65f5d61b8f8ce..bb4b596a049ebce685adbfa967d97436734f8f63 100644 (file)
--- a/README.md
+++ b/README.md
@@ -220,6 +220,7 @@ name
 [double_parens](https://github.com/Manishearth/rust-clippy/wiki#double_parens)                                         | warn    | Warn on unnecessary double parentheses
 [drop_ref](https://github.com/Manishearth/rust-clippy/wiki#drop_ref)                                                   | warn    | calls to `std::mem::drop` with a reference instead of an owned value
 [duplicate_underscore_argument](https://github.com/Manishearth/rust-clippy/wiki#duplicate_underscore_argument)         | warn    | function arguments having names which only differ by an underscore
+[empty_enum](https://github.com/Manishearth/rust-clippy/wiki#empty_enum)                                               | allow   | enum with no variants
 [empty_loop](https://github.com/Manishearth/rust-clippy/wiki#empty_loop)                                               | warn    | empty `loop {}`, which should block or sleep
 [enum_clike_unportable_variant](https://github.com/Manishearth/rust-clippy/wiki#enum_clike_unportable_variant)         | warn    | C-like enums that are `repr(isize/usize)` and have values that don't fit into an `i32`
 [enum_glob_use](https://github.com/Manishearth/rust-clippy/wiki#enum_glob_use)                                         | allow   | use items that import all variants of an enum
index c324cabe1c730affb922f9b8e496718d04ac2fdc..8a81dc75e97863c65868e21aeb576093e8f21f68 100644 (file)
@@ -1,7 +1,7 @@
 [package]
 name = "clippy_lints"
 # begin automatic update
-version = "0.0.112"
+version = "0.0.113"
 # end automatic update
 authors = [
        "Manish Goregaokar <manishsmail@gmail.com>",
index 7e6b8cf98c2c3847f37c3eec5aac6a787ccdfa85..71ebb996fc579e86c68f3f91312cda6a66135083 100644 (file)
@@ -143,12 +143,12 @@ macro_rules! ops {
                                             return; // useless if the trait doesn't exist
                                         };
                                         // check that we are not inside an `impl AssignOp` of this exact operation
-                                        let parent_fn = cx.tcx.map.get_parent(e.id);
-                                        let parent_impl = cx.tcx.map.get_parent(parent_fn);
+                                        let parent_fn = cx.tcx.hir.get_parent(e.id);
+                                        let parent_impl = cx.tcx.hir.get_parent(parent_fn);
                                         // the crate node is the only one that is not in the map
                                         if_let_chain!{[
                                             parent_impl != ast::CRATE_NODE_ID,
-                                            let hir::map::Node::NodeItem(item) = cx.tcx.map.get(parent_impl),
+                                            let hir::map::Node::NodeItem(item) = cx.tcx.hir.get(parent_impl),
                                             let hir::Item_::ItemImpl(_, _, _, Some(ref trait_ref), _, _) = item.node,
                                             trait_ref.path.def.def_id() == trait_id
                                         ], { return; }}
index e908aa02c40d506b361353080c2422ab08dcb9c7..30115c60572a08c63a903dbb939ee4ac6464f2f7 100644 (file)
@@ -158,7 +158,7 @@ fn check_trait_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx TraitItem
 
 fn is_relevant_item(tcx: ty::TyCtxt, item: &Item) -> bool {
     if let ItemFn(_, _, _, _, _, eid) = item.node {
-        is_relevant_expr(tcx, tcx.body_tables(eid), &tcx.map.body(eid).value)
+        is_relevant_expr(tcx, tcx.body_tables(eid), &tcx.hir.body(eid).value)
     } else {
         false
     }
@@ -166,7 +166,7 @@ fn is_relevant_item(tcx: ty::TyCtxt, item: &Item) -> bool {
 
 fn is_relevant_impl(tcx: ty::TyCtxt, item: &ImplItem) -> bool {
     match item.node {
-        ImplItemKind::Method(_, eid) => is_relevant_expr(tcx, tcx.body_tables(eid), &tcx.map.body(eid).value),
+        ImplItemKind::Method(_, eid) => is_relevant_expr(tcx, tcx.body_tables(eid), &tcx.hir.body(eid).value),
         _ => false,
     }
 }
@@ -175,13 +175,13 @@ fn is_relevant_trait(tcx: ty::TyCtxt, item: &TraitItem) -> bool {
     match item.node {
         TraitItemKind::Method(_, TraitMethod::Required(_)) => true,
         TraitItemKind::Method(_, TraitMethod::Provided(eid)) => {
-            is_relevant_expr(tcx, tcx.body_tables(eid), &tcx.map.body(eid).value)
+            is_relevant_expr(tcx, tcx.body_tables(eid), &tcx.hir.body(eid).value)
         },
         _ => false,
     }
 }
 
-fn is_relevant_block(tcx: ty::TyCtxt, tables: &ty::Tables, block: &Block) -> bool {
+fn is_relevant_block(tcx: ty::TyCtxt, tables: &ty::TypeckTables, block: &Block) -> bool {
     for stmt in &block.stmts {
         match stmt.node {
             StmtDecl(_, _) => return true,
@@ -194,7 +194,7 @@ fn is_relevant_block(tcx: ty::TyCtxt, tables: &ty::Tables, block: &Block) -> boo
     block.expr.as_ref().map_or(false, |e| is_relevant_expr(tcx, tables, e))
 }
 
-fn is_relevant_expr(tcx: ty::TyCtxt, tables: &ty::Tables, expr: &Expr) -> bool {
+fn is_relevant_expr(tcx: ty::TyCtxt, tables: &ty::TypeckTables, expr: &Expr) -> bool {
     match expr.node {
         ExprBlock(ref block) => is_relevant_block(tcx, tables, block),
         ExprRet(Some(ref e)) => is_relevant_expr(tcx, tables, e),
index 6a02e69a8818d01d5fad7bf96d5e7012105b62d0..5fd8020e1a8805ec4938962c0f11f0e147f57d23 100644 (file)
@@ -57,7 +57,7 @@ struct ExVisitor<'a, 'tcx: 'a> {
 impl<'a, 'tcx: 'a> Visitor<'tcx> for ExVisitor<'a, 'tcx> {
     fn visit_expr(&mut self, expr: &'tcx Expr) {
         if let ExprClosure(_, _, eid, _) = expr.node {
-            let body = self.cx.tcx.map.body(eid);
+            let body = self.cx.tcx.hir.body(eid);
             let ex = &body.value;
             if matches!(ex.node, ExprBlock(_)) {
                 self.found_block = Some(ex);
@@ -67,7 +67,7 @@ fn visit_expr(&mut self, expr: &'tcx Expr) {
         walk_expr(self, expr);
     }
     fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
-        NestedVisitorMap::All(&self.cx.tcx.map)
+        NestedVisitorMap::All(&self.cx.tcx.hir)
     }
 }
 
index 7ea6c7e4b21b6b537e1e0ecc98d0675fbfdb5b9d..f6c9619dcf0a92c1b796175d2fb43f5908cabaf2 100644 (file)
@@ -263,7 +263,7 @@ fn expr(&mut self, e: &Expr) -> Option<Constant> {
             ExprRepeat(ref value, number_id) => {
                 if let Some(lcx) = self.lcx {
                     self.binop_apply(value,
-                                     &lcx.tcx.map.body(number_id).value,
+                                     &lcx.tcx.hir.body(number_id).value,
                                      |v, n| Some(Constant::Repeat(Box::new(v), n.as_u64() as usize)))
                 } else {
                     None
index 0a452f8ae130341541376a837ff74970adb21fef..9d6056de3434712f181ce751762c19cf151fb826 100644 (file)
@@ -99,7 +99,7 @@ fn check_fn(
         span: Span,
         node_id: NodeId
     ) {
-        let def_id = cx.tcx.map.local_def_id(node_id);
+        let def_id = cx.tcx.hir.local_def_id(node_id);
         if !cx.tcx.has_attr(def_id, "test") {
             self.check(cx, &body.value, span);
         }
index cf5b0208426e7dc1d64f132257747be44f88a130..b2a8d26000d14f2abe87f887a1bfb1de8072bc5a 100644 (file)
@@ -73,7 +73,7 @@ fn get_lints(&self) -> LintArray {
 impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Derive {
     fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx Item) {
         if let ItemImpl(_, _, _, Some(ref trait_ref), _, _) = item.node {
-            let ty = cx.tcx.item_type(cx.tcx.map.local_def_id(item.id));
+            let ty = cx.tcx.item_type(cx.tcx.hir.local_def_id(item.id));
             let is_automatically_derived = is_automatically_derived(&*item.attrs);
 
             check_hash_peq(cx, item.span, trait_ref, ty, is_automatically_derived);
@@ -122,9 +122,9 @@ fn check_hash_peq<'a, 'tcx>(
                     cx, DERIVE_HASH_XOR_EQ, span,
                     mess,
                     |db| {
-                    if let Some(node_id) = cx.tcx.map.as_local_node_id(impl_id) {
+                    if let Some(node_id) = cx.tcx.hir.as_local_node_id(impl_id) {
                         db.span_note(
-                            cx.tcx.map.span(node_id),
+                            cx.tcx.hir.span(node_id),
                             "`PartialEq` implemented here"
                         );
                     }
diff --git a/clippy_lints/src/empty_enum.rs b/clippy_lints/src/empty_enum.rs
new file mode 100644 (file)
index 0000000..631ac8b
--- /dev/null
@@ -0,0 +1,46 @@
+//! lint when there is an enum with no variants
+
+use rustc::lint::*;
+use rustc::hir::*;
+use utils::span_lint_and_then;
+
+/// **What it does:** Checks for `enum`s with no variants.
+///
+/// **Why is this bad?** Enum's with no variants should be replaced with `!`, the uninhabited type,
+/// or a wrapper around it.
+///
+/// **Known problems:** None.
+///
+/// **Example:**
+/// ```rust
+/// enum Test {}
+/// ```
+declare_lint! {
+    pub EMPTY_ENUM,
+    Allow,
+    "enum with no variants"
+}
+
+#[derive(Copy,Clone)]
+pub struct EmptyEnum;
+
+impl LintPass for EmptyEnum {
+    fn get_lints(&self) -> LintArray {
+        lint_array!(EMPTY_ENUM)
+    }
+}
+
+impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EmptyEnum {
+    fn check_item(&mut self, cx: &LateContext, item: &Item) {
+        let did = cx.tcx.hir.local_def_id(item.id);
+        if let ItemEnum(..) = item.node {
+            let ty = cx.tcx.item_type(did);
+            let adt = ty.ty_adt_def().expect("already checked whether this is an enum");
+            if adt.variants.is_empty() {
+                span_lint_and_then(cx, EMPTY_ENUM, item.span, "enum with no variants", |db| {
+                    db.span_help(item.span, "consider using the uninhabited type `!` or a wrapper around it");
+                });
+            }
+        }
+    }
+}
index 50bd62a855abf88ef4556cc802b0b1eb5265606c..8c8165592b52239785d6225759ca6e1fc9008a66 100644 (file)
@@ -148,6 +148,6 @@ fn visit_expr(&mut self, expr: &'tcx Expr) {
         }
     }
     fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
-        NestedVisitorMap::All(&self.cx.tcx.map)
+        NestedVisitorMap::All(&self.cx.tcx.hir)
     }
 }
index a73f68fcb58e9ab1296787b97bf608522c26f1e1..e924ae79df9fe66cd163bfb8bec5f50eb80a76a3 100644 (file)
@@ -45,7 +45,7 @@ fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx Item) {
                 if let Some(body_id) = variant.disr_expr {
                     use rustc_const_eval::*;
                     let constcx = ConstContext::new(cx.tcx, body_id);
-                    let bad = match constcx.eval(&cx.tcx.map.body(body_id).value, EvalHint::ExprTypeChecked) {
+                    let bad = match constcx.eval(&cx.tcx.hir.body(body_id).value, EvalHint::ExprTypeChecked) {
                         Ok(ConstVal::Integral(Usize(Us64(i)))) => i as u32 as u64 != i,
                         Ok(ConstVal::Integral(Isize(Is64(i)))) => i as i32 as i64 != i,
                         _ => false,
index 2e9f6af5bd819ee1e77aeb24046e8a468a779212..0db45efeb386b42773e114353a443dcc1188fd6b 100644 (file)
@@ -40,16 +40,13 @@ pub struct Pass {
 }
 
 fn is_non_trait_box(ty: ty::Ty) -> bool {
-    match ty.sty {
-        ty::TyBox(inner) => !inner.is_trait(),
-        _ => false,
-    }
+    ty.is_box() && !ty.boxed_ty().is_trait()
 }
 
 struct EscapeDelegate<'a, 'tcx: 'a> {
     set: NodeSet,
     tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,
-    tables: &'a ty::Tables<'tcx>,
+    tables: &'a ty::TypeckTables<'tcx>,
     target: TargetDataLayout,
     too_large_for_stack: u64,
 }
@@ -89,7 +86,7 @@ fn check_fn(
         for node in v.set {
             span_lint(cx,
                       BOXED_LOCAL,
-                      cx.tcx.map.span(node),
+                      cx.tcx.hir.span(node),
                       "local variable doesn't need to be boxed here");
         }
     }
@@ -108,7 +105,7 @@ fn consume(&mut self, _: NodeId, _: Span, cmt: cmt<'tcx>, mode: ConsumeMode) {
     }
     fn matched_pat(&mut self, _: &Pat, _: cmt<'tcx>, _: MatchMode) {}
     fn consume_pat(&mut self, consume_pat: &Pat, cmt: cmt<'tcx>, _: ConsumeMode) {
-        let map = &self.tcx.map;
+        let map = &self.tcx.hir;
         if map.is_argument(consume_pat.id) {
             // Skip closure arguments
             if let Some(NodeExpr(..)) = map.find(map.get_parent_node(consume_pat.id)) {
@@ -180,7 +177,7 @@ fn borrow(
                         self.tables
                             .adjustments
                             .get(&self.tcx
-                                .map
+                                .hir
                                 .get_parent_node(borrow_id))
                             .map(|a| &a.kind) {
                         if autoderefs <= 1 {
@@ -204,16 +201,16 @@ impl<'a, 'tcx: 'a> EscapeDelegate<'a, 'tcx> {
     fn is_large_box(&self, ty: ty::Ty<'tcx>) -> bool {
         // Large types need to be boxed to avoid stack
         // overflows.
-        match ty.sty {
-            ty::TyBox(inner) => {
-                self.tcx.infer_ctxt((), Reveal::All).enter(|infcx| if let Ok(layout) = inner.layout(&infcx) {
-                    let size = layout.size(&self.target);
-                    size.bytes() > self.too_large_for_stack
-                } else {
-                    false
-                })
-            },
-            _ => false,
+        if ty.is_box() {
+            let inner = ty.boxed_ty();
+            self.tcx.infer_ctxt((), Reveal::All).enter(|infcx| if let Ok(layout) = inner.layout(&infcx) {
+                let size = layout.size(&self.target);
+                size.bytes() > self.too_large_for_stack
+            } else {
+                false
+            })
+        } else {
+            false
         }
     }
 }
index 769ff99d550d9859f65acadc8ac3dd8c6eefe883..40678e324b0a3d26229876237c7d99b6cc56abc7 100644 (file)
@@ -49,7 +49,7 @@ fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
 
 fn check_closure(cx: &LateContext, expr: &Expr) {
     if let ExprClosure(_, ref decl, eid, _) = expr.node {
-        let body = cx.tcx.map.body(eid);
+        let body = cx.tcx.hir.body(eid);
         let ex = &body.value;
         if let ExprCall(ref caller, ref args) = ex.node {
             if args.len() != decl.inputs.len() {
index c54b77a037c41c288ef17892cc88a8e9a3e355ac..798bd6cf1f7e245ea900a78e3c85378c79dfe490 100644 (file)
@@ -156,7 +156,7 @@ fn visit_block(&mut self, _: &'tcx Block) {
         // don't continue over blocks, LateLintPass already does that
     }
     fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
-        NestedVisitorMap::All(&self.cx.tcx.map)
+        NestedVisitorMap::All(&self.cx.tcx.hir)
     }
 }
 
@@ -176,7 +176,7 @@ fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
 ///
 /// When such a read is found, the lint is triggered.
 fn check_for_unsequenced_reads(vis: &mut ReadVisitor) {
-    let map = &vis.cx.tcx.map;
+    let map = &vis.cx.tcx.hir;
     let mut cur_id = vis.write_expr.id;
     loop {
         let parent_id = map.get_parent_node(cur_id);
@@ -342,7 +342,7 @@ fn visit_expr(&mut self, expr: &'tcx Expr) {
         walk_expr(self, expr);
     }
     fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
-        NestedVisitorMap::All(&self.cx.tcx.map)
+        NestedVisitorMap::All(&self.cx.tcx.hir)
     }
 }
 
index 6281d34dd939d21a97cbdfdb7f4260fcbe00d1bf..69ef78a305641d05aec322b1c7b128bf1942d76c 100644 (file)
@@ -78,10 +78,10 @@ pub fn get_argument_fmtstr_parts<'a, 'b>(cx: &LateContext<'a, 'b>, expr: &'a Exp
         block.stmts.len() == 1,
         let StmtDecl(ref decl, _) = block.stmts[0].node,
         let DeclItem(ref decl) = decl.node,
-        let Some(NodeItem(decl)) = cx.tcx.map.find(decl.id),
+        let Some(NodeItem(decl)) = cx.tcx.hir.find(decl.id),
         &*decl.name.as_str() == "__STATIC_FMTSTR",
         let ItemStatic(_, _, ref expr) = decl.node,
-        let ExprAddrOf(_, ref expr) = cx.tcx.map.body(*expr).value.node, // &["…", "…", …]
+        let ExprAddrOf(_, ref expr) = cx.tcx.hir.body(*expr).value.node, // &["…", "…", …]
         let ExprArray(ref exprs) = expr.node,
     ], {
         let mut result = Vec::new();
index 86548854272936e5ebe2d2bca0ac8d5a21444170..6d630c7cc8891fd0daf1a3b01b52bc7b9865fce2 100644 (file)
@@ -80,7 +80,7 @@ fn check_fn(
     ) {
         use rustc::hir::map::Node::*;
 
-        let is_impl = if let Some(NodeItem(item)) = cx.tcx.map.find(cx.tcx.map.get_parent_node(nodeid)) {
+        let is_impl = if let Some(NodeItem(item)) = cx.tcx.hir.find(cx.tcx.hir.get_parent_node(nodeid)) {
             matches!(item.node, hir::ItemImpl(_, _, _, Some(_), _, _) | hir::ItemDefaultImpl(..))
         } else {
             false
@@ -113,7 +113,7 @@ fn check_trait_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx hir::Trai
             }
 
             if let hir::TraitMethod::Provided(eid) = *eid {
-                let body = cx.tcx.map.body(eid);
+                let body = cx.tcx.hir.body(eid);
                 self.check_raw_ptr(cx, sig.unsafety, &sig.decl, body, item.id);
             }
         }
@@ -200,7 +200,7 @@ fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
         hir::intravisit::walk_expr(self, expr);
     }
     fn nested_visit_map<'this>(&'this mut self) -> intravisit::NestedVisitorMap<'this, 'tcx> {
-        intravisit::NestedVisitorMap::All(&self.cx.tcx.map)
+        intravisit::NestedVisitorMap::All(&self.cx.tcx.hir)
     }
 }
 
index ca812067878be2a91575f1ad264b0bf802d4a019..36c5e7a288aed6b30503e2c617ef541169e799e5 100644 (file)
@@ -46,7 +46,7 @@ fn get_lints(&self) -> LintArray {
 
 impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LargeEnumVariant {
     fn check_item(&mut self, cx: &LateContext, item: &Item) {
-        let did = cx.tcx.map.local_def_id(item.id);
+        let did = cx.tcx.hir.local_def_id(item.id);
         if let ItemEnum(ref def, _) = item.node {
             let ty = cx.tcx.item_type(did);
             let adt = ty.ty_adt_def().expect("already checked whether this is an enum");
index 6f4d69cbd5a2f8aa779750d355f16f8efac26608..8a2f37e5aa1fa07fbd4979de9aa4c4694bfc9a7e 100644 (file)
@@ -93,7 +93,7 @@ fn is_named_self(cx: &LateContext, item: &TraitItemRef, name: &str) -> bool {
         if let AssociatedItemKind::Method { has_self } = item.kind {
             has_self &&
             {
-                let did = cx.tcx.map.local_def_id(item.id.node_id);
+                let did = cx.tcx.hir.local_def_id(item.id.node_id);
                 let impl_ty = cx.tcx.item_type(did);
                 impl_ty.fn_args().skip_binder().len() == 1
             }
@@ -120,7 +120,7 @@ fn is_named_self(cx: &LateContext, item: &ImplItemRef, name: &str) -> bool {
         if let AssociatedItemKind::Method { has_self } = item.kind {
             has_self &&
             {
-                let did = cx.tcx.map.local_def_id(item.id.node_id);
+                let did = cx.tcx.hir.local_def_id(item.id.node_id);
                 let impl_ty = cx.tcx.item_type(did);
                 impl_ty.fn_args().skip_binder().len() == 1
             }
@@ -141,7 +141,7 @@ fn is_named_self(cx: &LateContext, item: &ImplItemRef, name: &str) -> bool {
 
     if let Some(i) = impl_items.iter().find(|i| is_named_self(cx, i, "len")) {
         if cx.access_levels.is_exported(i.id.node_id) {
-            let def_id = cx.tcx.map.local_def_id(item.id);
+            let def_id = cx.tcx.hir.local_def_id(item.id);
             let ty = cx.tcx.item_type(def_id);
 
             span_lint(cx,
index 618869021ee60e2e0620b4772b3e78600f33b575..cfc8d4bbd68985f736e3d1ec8fee37aab608f14b 100644 (file)
@@ -145,7 +145,7 @@ fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
         hir::intravisit::walk_expr(self, expr);
     }
     fn nested_visit_map<'this>(&'this mut self) -> hir::intravisit::NestedVisitorMap<'this, 'tcx> {
-        hir::intravisit::NestedVisitorMap::All(&self.cx.tcx.map)
+        hir::intravisit::NestedVisitorMap::All(&self.cx.tcx.hir)
     }
 }
 
index 447c5c9e2cf74d6ebd2dc4d229eb911035ea23b1..1099738d7995077129ad4bfbc1ea08e895bfafa8 100644 (file)
@@ -8,7 +8,6 @@
 #![feature(rustc_private)]
 #![feature(slice_patterns)]
 #![feature(stmt_expr_attributes)]
-#![feature(repeat_str)]
 #![feature(conservative_impl_trait)]
 #![feature(collections_bound)]
 
@@ -73,6 +72,7 @@ macro_rules! declare_restriction_lint {
 pub mod doc;
 pub mod double_parens;
 pub mod drop_forget_ref;
+pub mod empty_enum;
 pub mod entry;
 pub mod enum_clike;
 pub mod enum_glob_use;
@@ -266,6 +266,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) {
         max_single_char_names: conf.max_single_char_names,
     });
     reg.register_late_lint_pass(box drop_forget_ref::Pass);
+    reg.register_late_lint_pass(box empty_enum::EmptyEnum);
     reg.register_late_lint_pass(box types::AbsurdExtremeComparisons);
     reg.register_late_lint_pass(box types::InvalidUpcastComparisons);
     reg.register_late_lint_pass(box regex::Pass::default());
@@ -305,6 +306,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) {
 
     reg.register_lint_group("clippy_pedantic", vec![
         booleans::NONMINIMAL_BOOL,
+        empty_enum::EMPTY_ENUM,
         enum_glob_use::ENUM_GLOB_USE,
         enum_variants::PUB_ENUM_VARIANT_NAMES,
         enum_variants::STUTTER,
index 720cf29247c2e28396fce8152f055deea2faee4e..2051c883670506d3df9a1b78939f81a7de7aaf5e 100644 (file)
@@ -230,6 +230,8 @@ fn record(&mut self, lifetime: &Option<Lifetime>) {
         if let Some(ref lt) = *lifetime {
             if &*lt.name.as_str() == "'static" {
                 self.lts.push(RefLt::Static);
+            } else if lt.is_elided() {
+                self.lts.push(RefLt::Unnamed);
             } else {
                 self.lts.push(RefLt::Named(lt.name));
             }
@@ -275,7 +277,7 @@ fn visit_lifetime(&mut self, lifetime: &'tcx Lifetime) {
 
     fn visit_ty(&mut self, ty: &'tcx Ty) {
         match ty.node {
-            TyRptr(None, _) => {
+            TyRptr(ref lt, _) if lt.is_elided() => {
                 self.record(&None);
             },
             TyPath(ref path) => {
@@ -288,6 +290,15 @@ fn visit_ty(&mut self, ty: &'tcx Ty) {
                     }
                 }
             },
+            TyTraitObject(ref bounds, ref lt) => {
+                if !lt.is_elided() {
+                    self.record(&Some(*lt));
+                }
+                for bound in bounds {
+                    self.visit_poly_trait_ref(bound, TraitBoundModifier::None);
+                }
+                return;
+            },
             _ => (),
         }
         walk_ty(self, ty);
index f3dd2d4b8e3c4007c9fdf15fe24cd593a3eba817..c863b11e0b89b6583b65112cb6ea8af0a499373e 100644 (file)
@@ -677,7 +677,7 @@ fn check_for_loop_explicit_counter<'a, 'tcx>(
 
     // For each candidate, check the parent block to see if
     // it's initialized to zero at the start of the loop.
-    let map = &cx.tcx.map;
+    let map = &cx.tcx.hir;
     let parent_scope = map.get_enclosing_scope(expr.id).and_then(|id| map.get_enclosing_scope(id));
     if let Some(parent_id) = parent_scope {
         if let NodeBlock(block) = map.get(parent_id) {
@@ -794,7 +794,7 @@ fn visit_expr(&mut self, expr: &'tcx Expr) {
         walk_expr(self, expr);
     }
     fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
-        NestedVisitorMap::All(&self.cx.tcx.map)
+        NestedVisitorMap::All(&self.cx.tcx.hir)
     }
 }
 
@@ -822,7 +822,7 @@ fn visit_expr(&mut self, expr: &'tcx Expr) {
                         match def {
                             Def::Local(..) | Def::Upvar(..) => {
                                 let def_id = def.def_id();
-                                let node_id = self.cx.tcx.map.as_local_node_id(def_id).unwrap();
+                                let node_id = self.cx.tcx.hir.as_local_node_id(def_id).unwrap();
 
                                 let extent = self.cx.tcx.region_maps.var_scope(node_id);
                                 self.indexed.insert(seqvar.segments[0].name, Some(extent));
@@ -844,7 +844,7 @@ fn visit_expr(&mut self, expr: &'tcx Expr) {
         walk_expr(self, expr);
     }
     fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
-        NestedVisitorMap::All(&self.cx.tcx.map)
+        NestedVisitorMap::All(&self.cx.tcx.hir)
     }
 }
 
@@ -886,7 +886,7 @@ fn visit_expr(&mut self, expr: &'tcx Expr) {
         walk_expr(self, expr);
     }
     fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
-        NestedVisitorMap::All(&self.cx.tcx.map)
+        NestedVisitorMap::All(&self.cx.tcx.hir)
     }
 }
 
@@ -1029,7 +1029,7 @@ fn visit_expr(&mut self, expr: &'tcx Expr) {
         walk_expr(self, expr);
     }
     fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
-        NestedVisitorMap::All(&self.cx.tcx.map)
+        NestedVisitorMap::All(&self.cx.tcx.hir)
     }
 }
 
@@ -1116,7 +1116,7 @@ fn visit_expr(&mut self, expr: &'tcx Expr) {
         walk_expr(self, expr);
     }
     fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
-        NestedVisitorMap::All(&self.cx.tcx.map)
+        NestedVisitorMap::All(&self.cx.tcx.hir)
     }
 }
 
@@ -1124,7 +1124,7 @@ fn var_def_id(cx: &LateContext, expr: &Expr) -> Option<NodeId> {
     if let ExprPath(ref qpath) = expr.node {
         let path_res = cx.tables.qpath_def(qpath, expr.id);
         if let Def::Local(def_id) = path_res {
-            let node_id = cx.tcx.map.as_local_node_id(def_id).expect("That DefId should be valid");
+            let node_id = cx.tcx.hir.as_local_node_id(def_id).expect("That DefId should be valid");
             return Some(node_id);
         }
     }
index 9dff7e8c8ff54b3525053a31f7a329e41b8823ee..087ae8c31b926efc53ef3308d87866b1e9ec64a6 100644 (file)
@@ -31,7 +31,7 @@ fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
             if &*name.node.as_str() == "map" && args.len() == 2 {
                 match args[1].node {
                     ExprClosure(_, ref decl, closure_eid, _) => {
-                        let body = cx.tcx.map.body(closure_eid);
+                        let body = cx.tcx.hir.body(closure_eid);
                         let closure_expr = remove_blocks(&body.value);
                         if_let_chain! {[
                             // nothing special in the argument, besides reference bindings
index 8c77a21e88ca7eb415c7ea0d51327f04a5874aac..30ffcc9f6e3a66960ef6ba83b9ec12b4975f5439 100644 (file)
@@ -614,12 +614,12 @@ fn check_impl_item(&mut self, cx: &LateContext<'a, 'tcx>, implitem: &'tcx hir::I
             return;
         }
         let name = implitem.name;
-        let parent = cx.tcx.map.get_parent(implitem.id);
-        let item = cx.tcx.map.expect_item(parent);
+        let parent = cx.tcx.hir.get_parent(implitem.id);
+        let item = cx.tcx.hir.expect_item(parent);
         if_let_chain! {[
             let hir::ImplItemKind::Method(ref sig, id) = implitem.node,
             let Some(first_arg_ty) = sig.decl.inputs.get(0),
-            let Some(first_arg) = iter_input_pats(&sig.decl, cx.tcx.map.body(id)).next(),
+            let Some(first_arg) = iter_input_pats(&sig.decl, cx.tcx.hir.body(id)).next(),
             let hir::ItemImpl(_, _, _, None, ref self_ty, _) = item.node,
         ], {
             // check missing trait implementations
@@ -635,7 +635,7 @@ fn check_impl_item(&mut self, cx: &LateContext<'a, 'tcx>, implitem: &'tcx hir::I
             }
 
             // check conventions w.r.t. conversion method names and predicates
-            let ty = cx.tcx.item_type(cx.tcx.map.local_def_id(item.id));
+            let ty = cx.tcx.item_type(cx.tcx.hir.local_def_id(item.id));
             let is_copy = is_copy(cx, ty, item.id);
             for &(ref conv, self_kinds) in &CONVENTIONS {
                 if_let_chain! {[
@@ -798,7 +798,7 @@ fn check_general_case(
 /// Checks for the `CLONE_ON_COPY` lint.
 fn lint_clone_on_copy(cx: &LateContext, expr: &hir::Expr, arg: &hir::Expr, arg_ty: ty::Ty) {
     let ty = cx.tables.expr_ty(expr);
-    let parent = cx.tcx.map.get_parent(expr.id);
+    let parent = cx.tcx.hir.get_parent(expr.id);
     let parameter_environment = ty::ParameterEnvironment::for_item(cx.tcx, parent);
     if let ty::TyRef(_, ty::TypeAndMut { ty: inner, .. }) = arg_ty.sty {
         if let ty::TyRef(..) = inner.sty {
@@ -949,10 +949,10 @@ fn derefs_to_slice(cx: &LateContext, expr: &hir::Expr, ty: ty::Ty) -> Option<sug
     fn may_slice(cx: &LateContext, ty: ty::Ty) -> bool {
         match ty.sty {
             ty::TySlice(_) => true,
+            ty::TyAdt(def, _) if def.is_box() => may_slice(cx, ty.boxed_ty()),
             ty::TyAdt(..) => match_type(cx, ty, &paths::VEC),
             ty::TyArray(_, size) => size < 32,
-            ty::TyRef(_, ty::TypeAndMut { ty: inner, .. }) |
-            ty::TyBox(inner) => may_slice(cx, inner),
+            ty::TyRef(_, ty::TypeAndMut { ty: inner, .. }) => may_slice(cx, inner),
             _ => false,
         }
     }
@@ -966,8 +966,8 @@ fn may_slice(cx: &LateContext, ty: ty::Ty) -> bool {
     } else {
         match ty.sty {
             ty::TySlice(_) => sugg::Sugg::hir_opt(cx, expr),
-            ty::TyRef(_, ty::TypeAndMut { ty: inner, .. }) |
-            ty::TyBox(inner) => {
+            ty::TyAdt(def, _) if def.is_box() && may_slice(cx, ty.boxed_ty()) => sugg::Sugg::hir_opt(cx, expr),
+            ty::TyRef(_, ty::TypeAndMut { ty: inner, .. }) => {
                 if may_slice(cx, inner) {
                     sugg::Sugg::hir_opt(cx, expr)
                 } else {
index 777ded8c2da89d48eff12e5532194dc3524d31e0..d397d4251117661ae062ddde754f2ce55c3bf72d 100644 (file)
@@ -477,7 +477,7 @@ fn non_macro_local(cx: &LateContext, def: &def::Def) -> bool {
     match *def {
         def::Def::Local(id) |
         def::Def::Upvar(id, _, _) => {
-            if let Some(span) = cx.tcx.map.span_if_local(id) {
+            if let Some(span) = cx.tcx.hir.span_if_local(id) {
                 !in_macro(cx, span)
             } else {
                 true
index d5be44e8c2b93ec01dc3b9a8e06bc2ede9f330d7..348e66a679e86cf551e26333ad7cb1a525b10d14 100644 (file)
@@ -146,7 +146,7 @@ fn check_trait_item(&mut self, cx: &LateContext<'a, 'tcx>, trait_item: &'tcx hir
 
     fn check_impl_item(&mut self, cx: &LateContext<'a, 'tcx>, impl_item: &'tcx hir::ImplItem) {
         // If the method is an impl for a trait, don't doc.
-        let def_id = cx.tcx.map.local_def_id(impl_item.id);
+        let def_id = cx.tcx.hir.local_def_id(impl_item.id);
         match cx.tcx.associated_item(def_id).container {
             ty::TraitContainer(_) => return,
             ty::ImplContainer(cid) => {
index 4c217e19725066cd27ae9d60ba0889767a8920cb..d5e4a0fdb26c93295e9610a537bae3428833b0c1 100644 (file)
@@ -91,6 +91,6 @@ fn visit_ty(&mut self, ty: &'tcx hir::Ty) {
         intravisit::walk_ty(self, ty);
     }
     fn nested_visit_map<'this>(&'this mut self) -> intravisit::NestedVisitorMap<'this, 'tcx> {
-        intravisit::NestedVisitorMap::All(&self.cx.tcx.map)
+        intravisit::NestedVisitorMap::All(&self.cx.tcx.hir)
     }
 }
index 5477204b79c12777a472c146455ad1a25faf7a32..e4e98c260388736e90c9387205cacf6b84929f39 100644 (file)
@@ -110,7 +110,7 @@ fn check_fn(
             }
             if decl.inputs.is_empty() && &*name.as_str() == "new" && cx.access_levels.is_reachable(id) {
                 let self_ty = cx.tcx
-                    .item_type(cx.tcx.map.local_def_id(cx.tcx.map.get_parent(id)));
+                    .item_type(cx.tcx.hir.local_def_id(cx.tcx.hir.get_parent(id)));
                 if_let_chain!{[
                     self_ty.walk_shallow().next().is_none(), // implements_trait does not work with generics
                     same_tys(cx, self_ty, return_ty(cx, id), id),
@@ -160,7 +160,7 @@ fn can_derive_default<'t, 'c>(ty: ty::Ty<'t>, cx: &LateContext<'c, 't>, default_
                     return None;
                 }
             }
-            cx.tcx.map.span_if_local(adt_def.did)
+            cx.tcx.hir.span_if_local(adt_def.did)
         },
         _ => None,
     }
index ad7d720fc51bcf3bcba2c967e2eba000796da062..0776b660b41794aee6b02db516e4f2aa39e97294 100644 (file)
@@ -135,7 +135,7 @@ fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
 }
 
 fn is_in_debug_impl(cx: &LateContext, expr: &Expr) -> bool {
-    let map = &cx.tcx.map;
+    let map = &cx.tcx.hir;
 
     // `fmt` method
     if let Some(NodeImplItem(item)) = map.find(map.get_parent(expr.id)) {
index 78fdc06708a9b942400ed75bd25020911554bd57..590e3d587d4ebb1fc04fb78f9ac24085f60268ca 100644 (file)
@@ -63,7 +63,7 @@ fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx Item) {
 
     fn check_impl_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx ImplItem) {
         if let ImplItemKind::Method(ref sig, _) = item.node {
-            if let Some(NodeItem(it)) = cx.tcx.map.find(cx.tcx.map.get_parent(item.id)) {
+            if let Some(NodeItem(it)) = cx.tcx.hir.find(cx.tcx.hir.get_parent(item.id)) {
                 if let ItemImpl(_, _, _, Some(_), _, _) = it.node {
                     return; // ignore trait impls
                 }
@@ -91,7 +91,7 @@ fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
 }
 
 fn check_fn(cx: &LateContext, decl: &FnDecl, fn_id: NodeId) {
-    let fn_def_id = cx.tcx.map.local_def_id(fn_id);
+    let fn_def_id = cx.tcx.hir.local_def_id(fn_id);
     let fn_ty = cx.tcx.item_type(fn_def_id).fn_sig().skip_binder();
 
     for (arg, ty) in decl.inputs.iter().zip(fn_ty.inputs()) {
index 9fc089bef43eeccef85421b4117c70b0f25babb6..62ef155c3211cbaa2aa9cb9ac014861f77147c14 100644 (file)
@@ -338,7 +338,7 @@ fn check_ty<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ty: &'tcx Ty, bindings: &mut V
         TySlice(ref sty) => check_ty(cx, sty, bindings),
         TyArray(ref fty, body_id) => {
             check_ty(cx, fty, bindings);
-            check_expr(cx, &cx.tcx.map.body(body_id).value, bindings);
+            check_expr(cx, &cx.tcx.hir.body(body_id).value, bindings);
         },
         TyPtr(MutTy { ty: ref mty, .. }) |
         TyRptr(_, MutTy { ty: ref mty, .. }) => check_ty(cx, mty, bindings),
@@ -347,7 +347,7 @@ fn check_ty<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ty: &'tcx Ty, bindings: &mut V
                 check_ty(cx, t, bindings)
             }
         },
-        TyTypeof(body_id) => check_expr(cx, &cx.tcx.map.body(body_id).value, bindings),
+        TyTypeof(body_id) => check_expr(cx, &cx.tcx.hir.body(body_id).value, bindings),
         _ => (),
     }
 }
@@ -382,7 +382,7 @@ fn visit_name(&mut self, _: Span, name: Name) {
         }
     }
     fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
-        NestedVisitorMap::All(&self.cx.tcx.map)
+        NestedVisitorMap::All(&self.cx.tcx.hir)
     }
 }
 
index bae4363659a6d5b06ad1969a249d8dfa4eaef767..ccdcb94d212cdcbc03f508bffda6caadb9cf3241 100644 (file)
@@ -72,7 +72,7 @@ fn get_lints(&self) -> LintArray {
 impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypePass {
     fn check_fn(&mut self, cx: &LateContext, _: FnKind, decl: &FnDecl, _: &Body, _: Span, id: NodeId) {
         // skip trait implementations, see #605
-        if let Some(map::NodeItem(item)) = cx.tcx.map.find(cx.tcx.map.get_parent(id)) {
+        if let Some(map::NodeItem(item)) = cx.tcx.hir.find(cx.tcx.hir.get_parent(id)) {
             if let ItemImpl(_, _, _, Some(..), _, _) = item.node {
                 return;
             }
@@ -702,13 +702,10 @@ fn visit_ty(&mut self, ty: &'tcx Ty) {
             // function types bring a lot of overhead
             TyBareFn(..) => (50 * self.nest, 1),
 
-            TyTraitObject(ref bounds) => {
-                let has_lifetimes = bounds.iter()
-                    .any(|bound| match *bound {
-                        TraitTyParamBound(ref poly_trait, ..) => !poly_trait.bound_lifetimes.is_empty(),
-                        RegionTyParamBound(..) => true,
-                    });
-                if has_lifetimes {
+            TyTraitObject(ref param_bounds, _) => {
+                let has_lifetime_parameters = param_bounds.iter()
+                    .any(|bound| !bound.bound_lifetimes.is_empty());
+                if has_lifetime_parameters {
                     // complex trait bounds like A<'a, 'b>
                     (50 * self.nest, 1)
                 } else {
@@ -725,7 +722,7 @@ fn visit_ty(&mut self, ty: &'tcx Ty) {
         self.nest -= sub_nest;
     }
     fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
-        NestedVisitorMap::All(&self.cx.tcx.map)
+        NestedVisitorMap::All(&self.cx.tcx.hir)
     }
 }
 
index 5136a821c546f549fb854375f9b1a88b4ee8ac2f..c74554d5083b4f0de1175f4b48a44fe3fd90a6a2 100644 (file)
@@ -83,6 +83,6 @@ fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
         walk_expr(self, expr);
     }
     fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
-        NestedVisitorMap::All(&self.cx.tcx.map)
+        NestedVisitorMap::All(&self.cx.tcx.hir)
     }
 }
index 3bce1b3d7e576b1d9e68d32aa45c4335c0f41770..2c5c19b2185d4e081bd2f637398f44f909ebdafd 100644 (file)
@@ -114,7 +114,7 @@ pub fn eq_expr(&self, left: &Expr, right: &Expr) -> bool {
             },
             (&ExprRepeat(ref le, ll_id), &ExprRepeat(ref re, rl_id)) => {
                 self.eq_expr(le, re) &&
-                self.eq_expr(&self.cx.tcx.map.body(ll_id).value, &self.cx.tcx.map.body(rl_id).value)
+                self.eq_expr(&self.cx.tcx.hir.body(ll_id).value, &self.cx.tcx.hir.body(rl_id).value)
             },
             (&ExprRet(ref l), &ExprRet(ref r)) => both(l, r, |l, r| self.eq_expr(l, r)),
             (&ExprPath(ref l), &ExprPath(ref r)) => self.eq_qpath(l, r),
@@ -217,7 +217,7 @@ fn eq_ty(&self, left: &Ty, right: &Ty) -> bool {
             (&TySlice(ref l_vec), &TySlice(ref r_vec)) => self.eq_ty(l_vec, r_vec),
             (&TyArray(ref lt, ll_id), &TyArray(ref rt, rl_id)) => {
                 self.eq_ty(lt, rt) &&
-                self.eq_expr(&self.cx.tcx.map.body(ll_id).value, &self.cx.tcx.map.body(rl_id).value)
+                self.eq_expr(&self.cx.tcx.hir.body(ll_id).value, &self.cx.tcx.hir.body(rl_id).value)
             },
             (&TyPtr(ref l_mut), &TyPtr(ref r_mut)) => l_mut.mutbl == r_mut.mutbl && self.eq_ty(&*l_mut.ty, &*r_mut.ty),
             (&TyRptr(_, ref l_rmut), &TyRptr(_, ref r_rmut)) => {
@@ -370,7 +370,7 @@ pub fn hash_expr(&mut self, e: &Expr) {
                 let c: fn(_, _, _, _) -> _ = ExprClosure;
                 c.hash(&mut self.s);
                 cap.hash(&mut self.s);
-                self.hash_expr(&self.cx.tcx.map.body(eid).value);
+                self.hash_expr(&self.cx.tcx.hir.body(eid).value);
             },
             ExprField(ref e, ref f) => {
                 let c: fn(_, _) -> _ = ExprField;
@@ -435,7 +435,7 @@ pub fn hash_expr(&mut self, e: &Expr) {
                 let c: fn(_, _) -> _ = ExprRepeat;
                 c.hash(&mut self.s);
                 self.hash_expr(e);
-                self.hash_expr(&self.cx.tcx.map.body(l_id).value);
+                self.hash_expr(&self.cx.tcx.hir.body(l_id).value);
             },
             ExprRet(ref e) => {
                 let c: fn(_) -> _ = ExprRet;
index e08a7d3bfdb7d54a35b78bbbc28d925d066a798d..66c1ba89353e09e03b87e290e8e7d7b24d9a31b3 100644 (file)
@@ -65,7 +65,7 @@ fn check_impl_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx hir::ImplI
         match item.node {
             hir::ImplItemKind::Const(_, body_id) => {
                 println!("associated constant");
-                print_expr(cx, &cx.tcx.map.body(body_id).value, 1);
+                print_expr(cx, &cx.tcx.hir.body(body_id).value, 1);
             },
             hir::ImplItemKind::Method(..) => println!("method"),
             hir::ImplItemKind::Type(_) => println!("associated type"),
@@ -332,13 +332,13 @@ fn print_expr(cx: &LateContext, expr: &hir::Expr, indent: usize) {
             println!("{}value:", ind);
             print_expr(cx, val, indent + 1);
             println!("{}repeat count:", ind);
-            print_expr(cx, &cx.tcx.map.body(body_id).value, indent + 1);
+            print_expr(cx, &cx.tcx.hir.body(body_id).value, indent + 1);
         },
     }
 }
 
 fn print_item(cx: &LateContext, item: &hir::Item) {
-    let did = cx.tcx.map.local_def_id(item.id);
+    let did = cx.tcx.hir.local_def_id(item.id);
     println!("item `{}`", item.name);
     match item.vis {
         hir::Visibility::Public => println!("public"),
index ea7a654ed1f7d0eb7b4c72290699b7359e8e3b21..41e9d7773639c64bb66add01f312158e5107b5c8 100644 (file)
@@ -114,7 +114,7 @@ fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx Item) {
                     output: &mut self.registered_lints,
                     cx: cx,
                 };
-                collector.visit_expr(&cx.tcx.map.body(body_id).value);
+                collector.visit_expr(&cx.tcx.hir.body(body_id).value);
             }
         }
     }
@@ -142,7 +142,10 @@ fn check_crate_post(&mut self, cx: &LateContext<'a, 'tcx>, _: &'tcx Crate) {
 
 
 fn is_lint_ref_type(ty: &Ty) -> bool {
-    if let TyRptr(Some(_), MutTy { ty: ref inner, mutbl: MutImmutable }) = ty.node {
+    if let TyRptr(ref lt, MutTy { ty: ref inner, mutbl: MutImmutable }) = ty.node {
+        if lt.is_elided() {
+            return false;
+        }
         if let TyPath(ref path) = inner.node {
             return match_path(path, &paths::LINT);
         }
@@ -175,6 +178,6 @@ fn visit_path(&mut self, path: &'tcx Path, _: NodeId) {
         }
     }
     fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
-        NestedVisitorMap::All(&self.cx.tcx.map)
+        NestedVisitorMap::All(&self.cx.tcx.hir)
     }
 }
index ef9c6b9c38a21ddeab56394a7aee5f0c66b4a3b4..1211b77ddb87c0a0a4964a14953d0e37f197ded5 100644 (file)
@@ -362,8 +362,8 @@ pub fn method_chain_args<'a>(expr: &'a Expr, methods: &[&str]) -> Option<Vec<&'a
 
 /// Get the name of the item the expression is in, if available.
 pub fn get_item_name(cx: &LateContext, expr: &Expr) -> Option<Name> {
-    let parent_id = cx.tcx.map.get_parent(expr.id);
-    match cx.tcx.map.find(parent_id) {
+    let parent_id = cx.tcx.hir.get_parent(expr.id);
+    match cx.tcx.hir.find(parent_id) {
         Some(Node::NodeItem(&Item { ref name, .. })) |
         Some(Node::NodeTraitItem(&TraitItem { ref name, .. })) |
         Some(Node::NodeImplItem(&ImplItem { ref name, .. })) => Some(*name),
@@ -458,7 +458,7 @@ fn trim_multiline_inner(s: Cow<str>, ignore_first: bool, ch: char) -> Cow<str> {
 
 /// Get a parent expressions if any – this is useful to constrain a lint.
 pub fn get_parent_expr<'c>(cx: &'c LateContext, e: &Expr) -> Option<&'c Expr> {
-    let map = &cx.tcx.map;
+    let map = &cx.tcx.hir;
     let node_id: NodeId = e.id;
     let parent_id: NodeId = map.get_parent_node(node_id);
     if node_id == parent_id {
@@ -472,14 +472,14 @@ pub fn get_parent_expr<'c>(cx: &'c LateContext, e: &Expr) -> Option<&'c Expr> {
 }
 
 pub fn get_enclosing_block<'a, 'tcx: 'a>(cx: &LateContext<'a, 'tcx>, node: NodeId) -> Option<&'tcx Block> {
-    let map = &cx.tcx.map;
+    let map = &cx.tcx.hir;
     let enclosing_node = map.get_enclosing_scope(node)
         .and_then(|enclosing_id| map.find(enclosing_id));
     if let Some(node) = enclosing_node {
         match node {
             Node::NodeBlock(block) => Some(block),
             Node::NodeItem(&Item { node: ItemFn(_, _, _, _, _, eid), .. }) => {
-                match cx.tcx.map.body(eid).value.node {
+                match cx.tcx.hir.body(eid).value.node {
                     ExprBlock(ref block) => Some(block),
                     _ => None,
                 }
@@ -762,7 +762,7 @@ pub fn camel_case_from(s: &str) -> usize {
 /// Convenience function to get the return type of a function
 pub fn return_ty<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, fn_item: NodeId) -> ty::Ty<'tcx> {
     let parameter_env = ty::ParameterEnvironment::for_item(cx.tcx, fn_item);
-    let fn_def_id = cx.tcx.map.local_def_id(fn_item);
+    let fn_def_id = cx.tcx.hir.local_def_id(fn_item);
     let fn_sig = cx.tcx.item_type(fn_def_id).fn_sig();
     let fn_sig = cx.tcx.liberate_late_bound_regions(parameter_env.free_id_outlive, fn_sig);
     fn_sig.output()
index d518921b743bb93a9dc2d61e3dd6ea39c5aa0524..a8d2701ccfa829f44ad69737ff2d96840da44e2b 100644 (file)
@@ -48,7 +48,7 @@ fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
         if_let_chain!{[
             let Some((_, arg, _)) = higher::for_loop(expr),
             let Some(vec_args) = higher::vec_macro(cx, arg),
-            is_copy(cx, vec_type(cx.tables.expr_ty_adjusted(arg)), cx.tcx.map.get_parent(expr.id)),
+            is_copy(cx, vec_type(cx.tables.expr_ty_adjusted(arg)), cx.tcx.hir.get_parent(expr.id)),
         ], {
             // report the error around the `vec!` not inside `<std macros>:`
             let span = cx.sess().codemap().source_callsite(arg.span);
diff --git a/tests/compile-fail/empty_enum.rs b/tests/compile-fail/empty_enum.rs
new file mode 100644 (file)
index 0000000..ac9b314
--- /dev/null
@@ -0,0 +1,11 @@
+#![feature(plugin)]
+#![plugin(clippy)]
+
+#![allow(dead_code)]
+#![deny(empty_enum)]
+
+enum Empty {} //~ ERROR enum with no variants
+    //~^ HELP consider using the uninhabited type `!` or a wrapper around it
+
+fn main() {
+}
index 12fd104312a9f9bea3fa4c06f80e2b02432c5af6..86539c2b13efe48a4348a011a21a6a3fb3dad0a1 100644 (file)
@@ -5,7 +5,9 @@
 
 use std::cmp::Ordering::*; //~ ERROR: don't use glob imports for enum variants
 
-enum Enum {}
+enum Enum {
+    _Foo,
+}
 
 use self::Enum::*; //~ ERROR: don't use glob imports for enum variants
 
index cd04a3b6b973dff2b23ba044317da38d632f79e3..43a4386886d9f8b0353694aee1d8216aa5f7a57c 100644 (file)
@@ -350,6 +350,7 @@ const fn make_const(i: i32) -> i32 { i }
 /// Checks implementation of `ITER_NTH` lint
 fn iter_nth() {
     let mut some_vec = vec![0, 1, 2, 3];
+    let mut boxed_slice: Box<[u8]> = Box::new([0, 1, 2, 3]);
     let mut some_vec_deque: VecDeque<_> = some_vec.iter().cloned().collect();
 
     {
@@ -358,6 +359,8 @@ fn iter_nth() {
         //~^ERROR called `.iter().nth()` on a Vec. Calling `.get()` is both faster and more readable
         let bad_slice = &some_vec[..].iter().nth(3);
         //~^ERROR called `.iter().nth()` on a slice. Calling `.get()` is both faster and more readable
+        let bad_boxed_slice = boxed_slice.iter().nth(3);
+        //~^ERROR called `.iter().nth()` on a slice. Calling `.get()` is both faster and more readable
         let bad_vec_deque = some_vec_deque.iter().nth(3);
         //~^ERROR called `.iter().nth()` on a VecDeque. Calling `.get()` is both faster and more readable
     }
@@ -414,6 +417,7 @@ fn get_mut(&mut self, pos: usize) -> Option<&mut u32> { self.arr.get_mut(pos) }
 
 /// Checks implementation of `GET_UNWRAP` lint
 fn get_unwrap() {
+    let mut boxed_slice: Box<[u8]> = Box::new([0, 1, 2, 3]);
     let mut some_slice = &mut [0, 1, 2, 3];
     let mut some_vec = vec![0, 1, 2, 3];
     let mut some_vecdeque: VecDeque<_> = some_vec.iter().cloned().collect();
@@ -422,6 +426,10 @@ fn get_unwrap() {
     let mut false_positive = GetFalsePositive { arr: [0, 1, 2] };
 
     { // Test `get().unwrap()`
+        let _ = boxed_slice.get(1).unwrap();
+        //~^ERROR called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise
+        //~|HELP try this
+        //~|SUGGESTION boxed_slice[1]
         let _ = some_slice.get(0).unwrap();
         //~^ERROR called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise
         //~|HELP try this
@@ -447,6 +455,10 @@ fn get_unwrap() {
     }
 
     { // Test `get_mut().unwrap()`
+        *boxed_slice.get_mut(0).unwrap() = 1;
+        //~^ERROR called `.get_mut().unwrap()` on a slice. Using `[]` is more clear and more concise
+        //~|HELP try this
+        //~|SUGGESTION &mut boxed_slice[0]
         *some_slice.get_mut(0).unwrap() = 1;
         //~^ERROR called `.get_mut().unwrap()` on a slice. Using `[]` is more clear and more concise
         //~|HELP try this