enum glob use and copies left

This commit is contained in:
Oliver Schneider
2016-12-02 17:38:31 +01:00
parent 59b0077565
commit 16aab71688
15 changed files with 117 additions and 109 deletions

View File

@@ -48,6 +48,8 @@ impl EnumGlobUse {
return; // re-exports are fine return; // re-exports are fine
} }
if let ItemUse(ref path, UseKind::Glob) = item.node { 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 let Def::Enum(_) = path.def {
span_lint(cx, ENUM_GLOB_USE, item.span, "don't use glob imports for enum variants"); span_lint(cx, ENUM_GLOB_USE, item.span, "don't use glob imports for enum variants");
} }

View File

@@ -5,7 +5,7 @@ use rustc::hir::*;
use rustc::hir::intravisit::{Visitor, walk_ty, walk_ty_param_bound, walk_fn_decl, walk_generics}; use rustc::hir::intravisit::{Visitor, walk_ty, walk_ty_param_bound, walk_fn_decl, walk_generics};
use std::collections::{HashSet, HashMap}; use std::collections::{HashSet, HashMap};
use syntax::codemap::Span; use syntax::codemap::Span;
use utils::{in_external_macro, span_lint}; use utils::{in_external_macro, span_lint, last_path_segment};
/// **What it does:** Checks for lifetime annotations which can be removed by /// **What it does:** Checks for lifetime annotations which can be removed by
/// relying on lifetime elision. /// relying on lifetime elision.
@@ -240,26 +240,24 @@ impl<'v, 't> RefVisitor<'v, 't> {
} }
fn collect_anonymous_lifetimes(&mut self, qpath: &QPath, ty: &Ty) { fn collect_anonymous_lifetimes(&mut self, qpath: &QPath, ty: &Ty) {
if let QPath::Resolved(_, ref path) = *qpath { let last_path_segment = &last_path_segment(qpath).parameters;
let last_path_segment = path.segments.last().map(|s| &s.parameters); if let &AngleBracketedParameters(ref params) = last_path_segment {
if let Some(&AngleBracketedParameters(ref params)) = last_path_segment { if params.lifetimes.is_empty() {
if params.lifetimes.is_empty() { match self.cx.tcx.tables().qpath_def(qpath, ty.id) {
match self.cx.tcx.tables().qpath_def(qpath, ty.id) { Def::TyAlias(def_id) |
Def::TyAlias(def_id) | Def::Struct(def_id) => {
Def::Struct(def_id) => { let generics = self.cx.tcx.item_generics(def_id);
let generics = self.cx.tcx.item_generics(def_id); for _ in generics.regions.as_slice() {
for _ in generics.regions.as_slice() { self.record(&None);
self.record(&None);
}
} }
Def::Trait(def_id) => {
let trait_def = self.cx.tcx.trait_defs.borrow()[&def_id];
for _ in &trait_def.generics.regions {
self.record(&None);
}
}
_ => (),
} }
Def::Trait(def_id) => {
let trait_def = self.cx.tcx.trait_defs.borrow()[&def_id];
for _ in &trait_def.generics.regions {
self.record(&None);
}
}
_ => (),
} }
} }
} }

View File

@@ -16,7 +16,7 @@ use utils::sugg;
use utils::{snippet, span_lint, get_parent_expr, match_trait_method, match_type, multispan_sugg, use utils::{snippet, span_lint, get_parent_expr, match_trait_method, match_type, multispan_sugg,
in_external_macro, is_refutable, span_help_and_lint, is_integer_literal, in_external_macro, is_refutable, span_help_and_lint, is_integer_literal,
get_enclosing_block, span_lint_and_then, higher, walk_ptrs_ty}; get_enclosing_block, span_lint_and_then, higher, walk_ptrs_ty, last_path_segment};
use utils::paths; use utils::paths;
/// **What it does:** Checks for looping over the range of `0..len` of some /// **What it does:** Checks for looping over the range of `0..len` of some
@@ -369,26 +369,23 @@ impl LateLintPass for Pass {
if let (&PatKind::TupleStruct(ref qpath, ref pat_args, _), if let (&PatKind::TupleStruct(ref qpath, ref pat_args, _),
&ExprMethodCall(method_name, _, ref method_args)) = (pat, &match_expr.node) { &ExprMethodCall(method_name, _, ref method_args)) = (pat, &match_expr.node) {
let iter_expr = &method_args[0]; let iter_expr = &method_args[0];
if let QPath::Resolved(_, ref path) = *qpath { let lhs_constructor = last_path_segment(qpath);
if let Some(lhs_constructor) = path.segments.last() { if &*method_name.node.as_str() == "next" &&
if &*method_name.node.as_str() == "next" && match_trait_method(cx, match_expr, &paths::ITERATOR) &&
match_trait_method(cx, match_expr, &paths::ITERATOR) && &*lhs_constructor.name.as_str() == "Some" &&
&*lhs_constructor.name.as_str() == "Some" && !is_refutable(cx, &pat_args[0]) &&
!is_refutable(cx, &pat_args[0]) && !is_iterator_used_after_while_let(cx, iter_expr) {
!is_iterator_used_after_while_let(cx, iter_expr) { let iterator = snippet(cx, method_args[0].span, "_");
let iterator = snippet(cx, method_args[0].span, "_"); let loop_var = snippet(cx, pat_args[0].span, "_");
let loop_var = snippet(cx, pat_args[0].span, "_"); span_lint_and_then(cx,
span_lint_and_then(cx, WHILE_LET_ON_ITERATOR,
WHILE_LET_ON_ITERATOR, expr.span,
expr.span, "this loop could be written as a `for` loop",
"this loop could be written as a `for` loop", |db| {
|db| { db.span_suggestion(expr.span,
db.span_suggestion(expr.span, "try",
"try", format!("for {} in {} {{ .. }}", loop_var, iterator));
format!("for {} in {} {{ .. }}", loop_var, iterator)); });
});
}
}
} }
} }
} }

View File

@@ -3,6 +3,7 @@ use rustc::lint::*;
use rustc::middle::const_val::ConstVal; use rustc::middle::const_val::ConstVal;
use rustc::middle::const_qualif::ConstQualif; use rustc::middle::const_qualif::ConstQualif;
use rustc::ty; use rustc::ty;
use rustc::hir::def::Def;
use rustc_const_eval::EvalHint::ExprTypeChecked; use rustc_const_eval::EvalHint::ExprTypeChecked;
use rustc_const_eval::eval_const_expr_partial; use rustc_const_eval::eval_const_expr_partial;
use std::borrow::Cow; use std::borrow::Cow;
@@ -10,7 +11,8 @@ use std::fmt;
use syntax::codemap::Span; use syntax::codemap::Span;
use utils::{get_trait_def_id, implements_trait, in_external_macro, in_macro, is_copy, match_path, use utils::{get_trait_def_id, implements_trait, in_external_macro, in_macro, is_copy, match_path,
match_trait_method, match_type, method_chain_args, return_ty, same_tys, snippet, match_trait_method, match_type, method_chain_args, return_ty, same_tys, snippet,
span_lint, span_lint_and_then, span_note_and_lint, walk_ptrs_ty, walk_ptrs_ty_depth}; span_lint, span_lint_and_then, span_note_and_lint, walk_ptrs_ty, walk_ptrs_ty_depth,
last_path_segment, single_segment_path, match_def_path};
use utils::paths; use utils::paths;
use utils::sugg; use utils::sugg;
@@ -701,12 +703,8 @@ fn lint_or_fun_call(cx: &LateContext, expr: &hir::Expr, name: &str, args: &[hir:
} }
if name == "unwrap_or" { if name == "unwrap_or" {
if let hir::ExprPath(hir::QPath::Resolved(_, ref path)) = fun.node { if let hir::ExprPath(ref qpath) = fun.node {
let path: &str = &path.segments let path: &str = &*last_path_segment(qpath).name.as_str();
.last()
.expect("A path must have at least one segment")
.name
.as_str();
if ["default", "new"].contains(&path) { if ["default", "new"].contains(&path) {
let arg_ty = cx.tcx.tables().expr_ty(arg); let arg_ty = cx.tcx.tables().expr_ty(arg);
@@ -878,7 +876,8 @@ fn lint_cstring_as_ptr(cx: &LateContext, expr: &hir::Expr, new: &hir::Expr, unwr
let hir::ExprCall(ref fun, ref args) = new.node, let hir::ExprCall(ref fun, ref args) = new.node,
args.len() == 1, args.len() == 1,
let hir::ExprPath(ref path) = fun.node, let hir::ExprPath(ref path) = fun.node,
match_path(path, &paths::CSTRING_NEW), let Def::Method(did) = cx.tcx.tables().qpath_def(path, fun.id),
match_def_path(cx, did, &paths::CSTRING_NEW)
], { ], {
span_lint_and_then(cx, TEMPORARY_CSTRING_AS_PTR, expr.span, span_lint_and_then(cx, TEMPORARY_CSTRING_AS_PTR, expr.span,
"you are getting the inner pointer of a temporary `CString`", "you are getting the inner pointer of a temporary `CString`",
@@ -1188,8 +1187,9 @@ fn lint_chars_next(cx: &LateContext, expr: &hir::Expr, chain: &hir::Expr, other:
let Some(args) = method_chain_args(chain, &["chars", "next"]), let Some(args) = method_chain_args(chain, &["chars", "next"]),
let hir::ExprCall(ref fun, ref arg_char) = other.node, let hir::ExprCall(ref fun, ref arg_char) = other.node,
arg_char.len() == 1, arg_char.len() == 1,
let hir::ExprPath(hir::QPath::Resolved(None, ref path)) = fun.node, let hir::ExprPath(ref qpath) = fun.node,
path.segments.len() == 1 && &*path.segments[0].name.as_str() == "Some" let Some(segment) = single_segment_path(qpath),
&*segment.name.as_str() == "Some"
], { ], {
let self_ty = walk_ptrs_ty(cx.tcx.tables().expr_ty_adjusted(&args[0][0])); let self_ty = walk_ptrs_ty(cx.tcx.tables().expr_ty_adjusted(&args[0][0]));

View File

@@ -10,7 +10,7 @@ use rustc_const_math::ConstFloat;
use syntax::codemap::{Span, Spanned, ExpnFormat}; use syntax::codemap::{Span, Spanned, ExpnFormat};
use utils::{ use utils::{
get_item_name, get_parent_expr, implements_trait, in_macro, is_integer_literal, match_path, get_item_name, get_parent_expr, implements_trait, in_macro, is_integer_literal, match_path,
snippet, span_lint, span_lint_and_then, walk_ptrs_ty snippet, span_lint, span_lint_and_then, walk_ptrs_ty, last_path_segment
}; };
use utils::sugg::Sugg; use utils::sugg::Sugg;
@@ -263,22 +263,14 @@ impl LateLintPass for Pass {
} }
let binding = match expr.node { let binding = match expr.node {
ExprPath(ref qpath) => { ExprPath(ref qpath) => {
if let QPath::Resolved(_, ref path) = *qpath { let binding = last_path_segment(qpath).name.as_str();
let binding = path.segments if binding.starts_with('_') &&
.last() !binding.starts_with("__") &&
.expect("path should always have at least one segment") &*binding != "_result" && // FIXME: #944
.name is_used(cx, expr) &&
.as_str(); // don't lint if the declaration is in a macro
if binding.starts_with('_') && non_macro_local(cx, &cx.tcx.tables().qpath_def(qpath, expr.id)) {
!binding.starts_with("__") && Some(binding)
&*binding != "_result" && // FIXME: #944
is_used(cx, expr) &&
// don't lint if the declaration is in a macro
non_macro_local(cx, &cx.tcx.tables().qpath_def(qpath, expr.id)) {
Some(binding)
} else {
None
}
} else { } else {
None None
} }

View File

@@ -75,17 +75,13 @@ impl LateLintPass for StepByZero {
// .iter() and .len() called on same Path // .iter() and .len() called on same Path
let ExprPath(QPath::Resolved(_, ref iter_path)) = iter_args[0].node, let ExprPath(QPath::Resolved(_, ref iter_path)) = iter_args[0].node,
let ExprPath(QPath::Resolved(_, ref len_path)) = len_args[0].node, let ExprPath(QPath::Resolved(_, ref len_path)) = len_args[0].node,
iter_path == len_path iter_path.segments == len_path.segments
], { ], {
let Path { segments: ref iter_path, .. } = **iter_path; span_lint(cx,
let Path { segments: ref len_path, .. } = **len_path; RANGE_ZIP_WITH_LEN,
if iter_path == len_path { expr.span,
span_lint(cx, &format!("It is more idiomatic to use {}.iter().enumerate()",
RANGE_ZIP_WITH_LEN, snippet(cx, iter_args[0].span, "_")));
expr.span,
&format!("It is more idiomatic to use {}.iter().enumerate()",
snippet(cx, iter_args[0].span, "_")));
}
}} }}
} }
} }

View File

@@ -2,7 +2,7 @@ use rustc::lint::*;
use rustc::ty::TypeVariants::{TyRawPtr, TyRef}; use rustc::ty::TypeVariants::{TyRawPtr, TyRef};
use rustc::ty; use rustc::ty;
use rustc::hir::*; use rustc::hir::*;
use utils::{match_def_path, paths, span_lint, span_lint_and_then, snippet}; use utils::{match_def_path, paths, span_lint, span_lint_and_then, snippet, last_path_segment};
use utils::sugg; use utils::sugg;
/// **What it does:** Checks for transmutes that can't ever be correct on any /// **What it does:** Checks for transmutes that can't ever be correct on any
@@ -191,9 +191,8 @@ impl LateLintPass for Transmute {
/// the type's `ToString` implementation. In weird cases it could lead to types with invalid `'_` /// the type's `ToString` implementation. In weird cases it could lead to types with invalid `'_`
/// lifetime, but it should be rare. /// lifetime, but it should be rare.
fn get_type_snippet(cx: &LateContext, path: &QPath, to_rty: ty::Ty) -> String { fn get_type_snippet(cx: &LateContext, path: &QPath, to_rty: ty::Ty) -> String {
let seg = last_path_segment(path);
if_let_chain!{[ if_let_chain!{[
let QPath::Resolved(_, ref path) = *path,
let Some(seg) = path.segments.last(),
let PathParameters::AngleBracketedParameters(ref ang) = seg.parameters, let PathParameters::AngleBracketedParameters(ref ang) = seg.parameters,
let Some(to_ty) = ang.types.get(1), let Some(to_ty) = ang.types.get(1),
let TyRptr(_, ref to_ty) = to_ty.node, let TyRptr(_, ref to_ty) = to_ty.node,

View File

@@ -7,7 +7,7 @@ use std::cmp::Ordering;
use syntax::ast::{IntTy, UintTy, FloatTy}; use syntax::ast::{IntTy, UintTy, FloatTy};
use syntax::codemap::Span; use syntax::codemap::Span;
use utils::{comparisons, higher, in_external_macro, in_macro, match_def_path, snippet, use utils::{comparisons, higher, in_external_macro, in_macro, match_def_path, snippet,
span_help_and_lint, span_lint, opt_def_id}; span_help_and_lint, span_lint, opt_def_id, last_path_segment};
use utils::paths; use utils::paths;
/// Handles all the linting of funky types /// Handles all the linting of funky types
@@ -78,9 +78,8 @@ impl LateLintPass for TypePass {
let def = cx.tcx.tables().qpath_def(qpath, ast_ty.id); let def = cx.tcx.tables().qpath_def(qpath, ast_ty.id);
if let Some(def_id) = opt_def_id(def) { if let Some(def_id) = opt_def_id(def) {
if def_id == cx.tcx.lang_items.owned_box().unwrap() { if def_id == cx.tcx.lang_items.owned_box().unwrap() {
let last = last_path_segment(qpath);
if_let_chain! {[ if_let_chain! {[
let QPath::Resolved(_, ref path) = *qpath,
let Some(ref last) = path.segments.last(),
let PathParameters::AngleBracketedParameters(ref ag) = last.parameters, let PathParameters::AngleBracketedParameters(ref ag) = last.parameters,
let Some(ref vec) = ag.types.get(0), let Some(ref vec) = ag.types.get(0),
let TyPath(ref qpath) = vec.node, let TyPath(ref qpath) = vec.node,

View File

@@ -163,7 +163,7 @@ pub fn vec_macro<'e>(cx: &LateContext, expr: &'e hir::Expr) -> Option<VecArgs<'e
// `vec![elem; size]` case // `vec![elem; size]` case
Some(VecArgs::Repeat(&args[0], &args[1])) Some(VecArgs::Repeat(&args[0], &args[1]))
} }
else if match_path(path, &["into_vec"]) && args.len() == 1 { else if match_def_path(cx, fun_def.def_id(), &paths::SLICE_INTO_VEC) && args.len() == 1 {
// `vec![a, b, c]` case // `vec![a, b, c]` case
if_let_chain!{[ if_let_chain!{[
let hir::ExprBox(ref boxed) = args[0].node, let hir::ExprBox(ref boxed) = args[0].node,

View File

@@ -3,7 +3,7 @@ use rustc::lint::*;
use rustc::hir::*; use rustc::hir::*;
use std::hash::{Hash, Hasher}; use std::hash::{Hash, Hasher};
use std::collections::hash_map::DefaultHasher; use std::collections::hash_map::DefaultHasher;
use syntax::ast::Name; use syntax::ast::{Name, NodeId};
use syntax::ptr::P; use syntax::ptr::P;
use utils::differing_macro_contexts; use utils::differing_macro_contexts;
@@ -457,13 +457,13 @@ impl<'a, 'tcx: 'a> SpanlessHash<'a, 'tcx> {
ExprPath(ref qpath) => { ExprPath(ref qpath) => {
let c: fn(_) -> _ = ExprPath; let c: fn(_) -> _ = ExprPath;
c.hash(&mut self.s); c.hash(&mut self.s);
self.hash_qpath(qpath); self.hash_qpath(qpath, e.id);
} }
ExprStruct(ref path, ref fields, ref expr) => { ExprStruct(ref path, ref fields, ref expr) => {
let c: fn(_, _, _) -> _ = ExprStruct; let c: fn(_, _, _) -> _ = ExprStruct;
c.hash(&mut self.s); c.hash(&mut self.s);
self.hash_qpath(path); self.hash_qpath(path, e.id);
for f in fields { for f in fields {
self.hash_name(&f.name.node); self.hash_name(&f.name.node);
@@ -528,21 +528,8 @@ impl<'a, 'tcx: 'a> SpanlessHash<'a, 'tcx> {
n.as_str().hash(&mut self.s); n.as_str().hash(&mut self.s);
} }
pub fn hash_qpath(&mut self, p: &QPath) { pub fn hash_qpath(&mut self, p: &QPath, id: NodeId) {
match *p { self.cx.tcx.tables().qpath_def(p, id).hash(&mut self.s);
QPath::Resolved(ref _ty, ref path) => {
let c: fn(_, _) -> _ = QPath::Resolved;
c.hash(&mut self.s);
// self.hash_ty(ty); FIXME
self.hash_path(path);
},
QPath::TypeRelative(ref _ty, ref seg) => {
let c: fn(_, _) -> _ = QPath::TypeRelative;
c.hash(&mut self.s);
// self.hash_ty(ty); FIXME
self.hash_name(&seg.name);
},
}
} }
pub fn hash_path(&mut self, p: &Path) { pub fn hash_path(&mut self, p: &Path) {

View File

@@ -95,7 +95,16 @@ pub fn differing_macro_contexts(lhs: Span, rhs: Span) -> bool {
} }
/// Returns true if this `expn_info` was expanded by any macro. /// Returns true if this `expn_info` was expanded by any macro.
pub fn in_macro<T: LintContext>(cx: &T, span: Span) -> bool { pub fn in_macro<T: LintContext>(cx: &T, span: Span) -> bool {
cx.sess().codemap().with_expn_info(span.expn_id, |info| info.is_some()) cx.sess().codemap().with_expn_info(span.expn_id, |info| match info {
Some(info) => {
match info.callee.format {
// don't treat range expressions desugared to structs as "in_macro"
ExpnFormat::CompilerDesugaring(name) => name != "...",
_ => true,
}
},
None => false,
})
} }
/// Returns true if the macro that expanded the crate was outside of the current crate or was a /// Returns true if the macro that expanded the crate was outside of the current crate or was a
@@ -150,6 +159,9 @@ pub fn match_def_path(cx: &LateContext, def_id: DefId, path: &[&str]) -> bool {
let mut apb = AbsolutePathBuffer { names: vec![] }; let mut apb = AbsolutePathBuffer { names: vec![] };
cx.tcx.push_item_path(&mut apb, def_id); cx.tcx.push_item_path(&mut apb, def_id);
if path == paths::VEC_FROM_ELEM {
println!("{:#?} == {:#?}", apb.names, path);
}
apb.names.len() == path.len() && apb.names.len() == path.len() &&
apb.names.iter().zip(path.iter()).all(|(a, &b)| &**a == b) apb.names.iter().zip(path.iter()).all(|(a, &b)| &**a == b)
@@ -197,6 +209,23 @@ pub fn match_trait_method(cx: &LateContext, expr: &Expr, path: &[&str]) -> bool
} }
} }
pub fn last_path_segment(path: &QPath) -> &PathSegment {
match *path {
QPath::Resolved(_, ref path) => path.segments
.last()
.expect("A path must have at least one segment"),
QPath::TypeRelative(_, ref seg) => &seg,
}
}
pub fn single_segment_path(path: &QPath) -> Option<&PathSegment> {
match *path {
QPath::Resolved(_, ref path) if path.segments.len() == 1 => Some(&path.segments[0]),
QPath::Resolved(..) => None,
QPath::TypeRelative(_, ref seg) => Some(&seg),
}
}
/// Match a `Path` against a slice of segment string literals. /// Match a `Path` against a slice of segment string literals.
/// ///
/// # Examples /// # Examples
@@ -204,10 +233,16 @@ pub fn match_trait_method(cx: &LateContext, expr: &Expr, path: &[&str]) -> bool
/// match_path(path, &["std", "rt", "begin_unwind"]) /// match_path(path, &["std", "rt", "begin_unwind"])
/// ``` /// ```
pub fn match_path(path: &QPath, segments: &[&str]) -> bool { pub fn match_path(path: &QPath, segments: &[&str]) -> bool {
if let QPath::Resolved(_, ref path) = *path { match *path {
match_path_old(path, segments) QPath::Resolved(_, ref path) => match_path_old(path, segments),
} else { QPath::TypeRelative(ref ty, ref segment) => match ty.node {
false TyPath(ref inner_path) => {
segments.len() > 0 &&
match_path(inner_path, &segments[..(segments.len() - 1)]) &&
segment.name == segments[segments.len() - 1]
},
_ => false,
},
} }
} }

View File

@@ -12,7 +12,7 @@ pub const CLONE_TRAIT: [&'static str; 3] = ["core", "clone", "Clone"];
pub const CMP_MAX: [&'static str; 3] = ["core", "cmp", "max"]; pub const CMP_MAX: [&'static str; 3] = ["core", "cmp", "max"];
pub const CMP_MIN: [&'static str; 3] = ["core", "cmp", "min"]; pub const CMP_MIN: [&'static str; 3] = ["core", "cmp", "min"];
pub const COW: [&'static str; 3] = ["collections", "borrow", "Cow"]; pub const COW: [&'static str; 3] = ["collections", "borrow", "Cow"];
pub const CSTRING_NEW: [&'static str; 4] = ["std", "ffi", "CString", "new"]; pub const CSTRING_NEW: [&'static str; 5] = ["std", "ffi", "c_str", "CString", "new"];
pub const DEBUG_FMT_METHOD: [&'static str; 4] = ["core", "fmt", "Debug", "fmt"]; pub const DEBUG_FMT_METHOD: [&'static str; 4] = ["core", "fmt", "Debug", "fmt"];
pub const DEFAULT_TRAIT: [&'static str; 3] = ["core", "default", "Default"]; pub const DEFAULT_TRAIT: [&'static str; 3] = ["core", "default", "Default"];
pub const DISPLAY_FMT_METHOD: [&'static str; 4] = ["core", "fmt", "Display", "fmt"]; pub const DISPLAY_FMT_METHOD: [&'static str; 4] = ["core", "fmt", "Display", "fmt"];
@@ -64,6 +64,7 @@ pub const RESULT: [&'static str; 3] = ["core", "result", "Result"];
pub const RESULT_ERR: [&'static str; 4] = ["core", "result", "Result", "Err"]; pub const RESULT_ERR: [&'static str; 4] = ["core", "result", "Result", "Err"];
pub const RESULT_OK: [&'static str; 4] = ["core", "result", "Result", "Ok"]; pub const RESULT_OK: [&'static str; 4] = ["core", "result", "Result", "Ok"];
pub const SERDE_DE_VISITOR: [&'static str; 3] = ["serde", "de", "Visitor"]; pub const SERDE_DE_VISITOR: [&'static str; 3] = ["serde", "de", "Visitor"];
pub const SLICE_INTO_VEC: [&'static str; 4] = ["collections", "slice", "<impl [T]>", "into_vec"];
pub const STRING: [&'static str; 3] = ["collections", "string", "String"]; pub const STRING: [&'static str; 3] = ["collections", "string", "String"];
pub const TRANSMUTE: [&'static str; 4] = ["core", "intrinsics", "", "transmute"]; pub const TRANSMUTE: [&'static str; 4] = ["core", "intrinsics", "", "transmute"];
pub const VEC: [&'static str; 3] = ["collections", "vec", "Vec"]; pub const VEC: [&'static str; 3] = ["collections", "vec", "Vec"];

View File

@@ -9,6 +9,7 @@
#![allow(blacklisted_name)] #![allow(blacklisted_name)]
#![allow(collapsible_if)] #![allow(collapsible_if)]
#![allow(zero_divided_by_zero, eq_op)] #![allow(zero_divided_by_zero, eq_op)]
#![allow(path_statements)]
fn bar<T>(_: T) {} fn bar<T>(_: T) {}
fn foo() -> bool { unimplemented!() } fn foo() -> bool { unimplemented!() }

View File

@@ -10,5 +10,5 @@ pub fn test(_: LinkedList<u8>) { //~ ERROR I see you're using a LinkedList!
} }
fn main(){ fn main(){
test(LinkedList::new()); test(LinkedList::new()); //~ ERROR I see you're using a LinkedList!
} }

View File

@@ -21,6 +21,7 @@ fn run_mode(dir: &'static str, mode: &'static str) {
fn prepare_env() { fn prepare_env() {
set_var("CLIPPY_DISABLE_WIKI_LINKS", "true"); set_var("CLIPPY_DISABLE_WIKI_LINKS", "true");
set_var("RUST_BACKTRACE", "0"); // these are riddicously slow right now
} }
#[test] #[test]