This commit is contained in:
Oliver Schneider 2017-09-13 15:34:04 +02:00
parent b7222be917
commit 32a9394490
No known key found for this signature in database
GPG Key ID: A69F8D225B3AD7D9
19 changed files with 118 additions and 81 deletions

View File

@ -1,6 +1,9 @@
# Change Log
All notable changes to this project will be documented in this file.
## 0.0.160
* Update to *rustc 1.22.0-nightly (dd08c3070 2017-09-12)*
## 0.0.159
* Update to *rustc 1.22.0-nightly (eba374fb2 2017-09-11)*
* New lint: [`clone_on_ref_ptr`]

6
Cargo.lock generated
View File

@ -1,6 +1,6 @@
[root]
name = "clippy_lints"
version = "0.0.158"
version = "0.0.159"
dependencies = [
"itertools 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
@ -73,11 +73,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "clippy"
version = "0.0.158"
version = "0.0.159"
dependencies = [
"cargo_metadata 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"clippy-mini-macro-test 0.1.0",
"clippy_lints 0.0.158",
"clippy_lints 0.0.159",
"compiletest_rs 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
"duct 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",

View File

@ -1,6 +1,6 @@
[package]
name = "clippy"
version = "0.0.159"
version = "0.0.160"
authors = [
"Manish Goregaokar <manishsmail@gmail.com>",
"Andre Bogus <bogusandre@gmail.com>",
@ -31,7 +31,7 @@ path = "src/main.rs"
[dependencies]
# begin automatic update
clippy_lints = { version = "0.0.159", path = "clippy_lints" }
clippy_lints = { version = "0.0.160", path = "clippy_lints" }
# end automatic update
cargo_metadata = "0.2"

View File

@ -1,7 +1,7 @@
[package]
name = "clippy_lints"
# begin automatic update
version = "0.0.159"
version = "0.0.160"
# end automatic update
authors = [
"Manish Goregaokar <manishsmail@gmail.com>",

View File

@ -7,6 +7,7 @@ use rustc_const_math::{ConstInt, ConstIsize, ConstUsize};
use rustc::hir;
use syntax::ast::RangeLimits;
use utils::{self, higher};
use utils::const_to_u64;
/// **What it does:** Checks for out of bounds array indexing with a constant
/// index.
@ -63,7 +64,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ArrayIndexing {
let ty = cx.tables.expr_ty(array);
if let ty::TyArray(_, size) = ty.sty {
let size = ConstInt::Usize(
ConstUsize::new(size as u64, cx.sess().target.uint_type).expect("array size is invalid"),
ConstUsize::new(const_to_u64(size), cx.sess().target.usize_ty).expect("array size is invalid"),
);
let parent_item = cx.tcx.hir.get_parent(e.id);
let parent_def_id = cx.tcx.hir.local_def_id(parent_item);
@ -71,13 +72,14 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ArrayIndexing {
let constcx = ConstContext::new(cx.tcx, cx.param_env.and(substs), cx.tables);
// Index is a constant uint
let const_index = constcx.eval(index);
if let Ok(ConstVal::Integral(const_index)) = const_index {
if size <= const_index {
utils::span_lint(cx, OUT_OF_BOUNDS_INDEXING, e.span, "const index is out of bounds");
}
if let Ok(const_index) = constcx.eval(index) {
if let ConstVal::Integral(const_index) = const_index.val {
if size <= const_index {
utils::span_lint(cx, OUT_OF_BOUNDS_INDEXING, e.span, "const index is out of bounds");
}
return;
return;
}
}
// Index is a constant range
@ -112,19 +114,19 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ArrayIndexing {
/// Returns an option containing a tuple with the start and end (exclusive) of
/// the range.
fn to_const_range(
start: &Option<Option<ConstVal>>,
end: &Option<Option<ConstVal>>,
start: &Option<Option<&ty::Const>>,
end: &Option<Option<&ty::Const>>,
limits: RangeLimits,
array_size: ConstInt,
) -> Option<(ConstInt, ConstInt)> {
let start = match *start {
Some(Some(ConstVal::Integral(x))) => x,
Some(Some(&ty::Const { val: ConstVal::Integral(x), .. })) => x,
Some(_) => return None,
None => ConstInt::U8(0),
};
let end = match *end {
Some(Some(ConstVal::Integral(x))) => if limits == RangeLimits::Closed {
Some(Some(&ty::Const { val: ConstVal::Integral(x), .. })) => if limits == RangeLimits::Closed {
match x {
ConstInt::U8(_) => (x + ConstInt::U8(1)),
ConstInt::U16(_) => (x + ConstInt::U16(1)),

View File

@ -14,6 +14,7 @@ use std::mem;
use std::rc::Rc;
use syntax::ast::{FloatTy, LitKind, StrStyle};
use syntax::ptr::P;
use utils::const_to_u64;
#[derive(Debug, Copy, Clone)]
pub enum FloatWidth {
@ -49,7 +50,7 @@ pub enum Constant {
/// an array of constants
Vec(Vec<Constant>),
/// also an array, but with only one constant, repeated N times
Repeat(Box<Constant>, usize),
Repeat(Box<Constant>, u64),
/// a tuple of constants
Tuple(Vec<Constant>),
}
@ -175,10 +176,10 @@ pub fn lit_to_constant<'a, 'tcx>(lit: &LitKind, tcx: TyCtxt<'a, 'tcx, 'tcx>, mut
LitKind::Char(c) => Constant::Char(c),
LitKind::Int(n, hint) => match (&ty.sty, hint) {
(&ty::TyInt(ity), _) | (_, Signed(ity)) => {
Constant::Int(ConstInt::new_signed_truncating(n as i128, ity, tcx.sess.target.int_type))
Constant::Int(ConstInt::new_signed_truncating(n as i128, ity, tcx.sess.target.isize_ty))
},
(&ty::TyUint(uty), _) | (_, Unsigned(uty)) => {
Constant::Int(ConstInt::new_unsigned_truncating(n as u128, uty, tcx.sess.target.uint_type))
Constant::Int(ConstInt::new_unsigned_truncating(n as u128, uty, tcx.sess.target.usize_ty))
},
_ => bug!(),
},
@ -249,7 +250,7 @@ impl<'c, 'cc> ConstEvalLateContext<'c, 'cc> {
ExprTup(ref tup) => self.multi(tup).map(Constant::Tuple),
ExprRepeat(ref value, _) => {
let n = match self.tables.expr_ty(e).sty {
ty::TyArray(_, n) => n,
ty::TyArray(_, n) => const_to_u64(n),
_ => span_bug!(e.span, "typeck error"),
};
self.expr(value).map(|v| Constant::Repeat(Box::new(v), n))

View File

@ -143,17 +143,8 @@ fn check_copy_clone<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, item: &Item, trait_ref
// Some types are not Clone by default but could be cloned “by hand” if necessary
ty::TyAdt(def, substs) => for variant in &def.variants {
for field in &variant.fields {
match field.ty(cx.tcx, substs).sty {
ty::TyArray(_, size) if size > 32 => {
return;
},
ty::TyFnPtr(..) => {
return;
},
ty::TyTuple(tys, _) if tys.len() > 12 => {
return;
},
_ => (),
if let ty::TyFnDef(..) = field.ty(cx.tcx, substs).sty {
return;
}
}
},

View File

@ -55,8 +55,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnportableVariant {
.at(expr.span)
.const_eval(param_env.and((did, substs)))
{
Ok(ConstVal::Integral(Usize(Us64(i)))) => u64::from(i as u32) != i,
Ok(ConstVal::Integral(Isize(Is64(i)))) => i64::from(i as i32) != i,
Ok(&ty::Const { val: ConstVal::Integral(Usize(Us64(i))), .. }) => u64::from(i as u32) != i,
Ok(&ty::Const { val: ConstVal::Integral(Isize(Is64(i))), .. }) => i64::from(i as i32) != i,
_ => false,
};
if bad {

View File

@ -8,6 +8,7 @@
#![feature(slice_patterns)]
#![feature(stmt_expr_attributes)]
#![feature(conservative_impl_trait)]
#![feature(inclusive_range_syntax, range_contains)]
#![allow(unknown_lints, indexing_slicing, shadow_reuse, missing_docs_in_private_items)]
#[macro_use]

View File

@ -13,6 +13,7 @@ use rustc_const_eval::ConstContext;
use std::collections::{HashMap, HashSet};
use syntax::ast;
use utils::sugg;
use utils::const_to_u64;
use utils::{get_enclosing_block, get_parent_expr, higher, in_external_macro, is_integer_literal, is_refutable,
last_path_segment, match_trait_method, match_type, multispan_sugg, snippet, snippet_opt,
@ -969,7 +970,7 @@ fn is_len_call(expr: &Expr, var: &Name) -> bool {
false
}
fn check_for_loop_reverse_range(cx: &LateContext, arg: &Expr, expr: &Expr) {
fn check_for_loop_reverse_range<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, arg: &'tcx Expr, expr: &'tcx Expr) {
// if this for loop is iterating over a two-sided range...
if let Some(higher::Range {
start: Some(start),
@ -989,7 +990,7 @@ fn check_for_loop_reverse_range(cx: &LateContext, arg: &Expr, expr: &Expr) {
// who think that this will iterate from the larger value to the
// smaller value.
let (sup, eq) = match (start_idx, end_idx) {
(ConstVal::Integral(start_idx), ConstVal::Integral(end_idx)) => {
(&ty::Const{ val: ConstVal::Integral(start_idx), .. }, &ty::Const{ val: ConstVal::Integral(end_idx), .. }) => {
(start_idx > end_idx, start_idx == end_idx)
},
_ => (false, false),
@ -1461,7 +1462,7 @@ fn is_ref_iterable_type(cx: &LateContext, e: &Expr) -> bool {
fn is_iterable_array(ty: Ty) -> bool {
// IntoIterator is currently only implemented for array sizes <= 32 in rustc
match ty.sty {
ty::TyArray(_, 0...32) => true,
ty::TyArray(_, n) => (0...32).contains(const_to_u64(n)),
_ => false,
}
}

View File

@ -318,7 +318,7 @@ fn check_match_bool(cx: &LateContext, ex: &Expr, arms: &[Arm], expr: &Expr) {
}
}
fn check_overlapping_arms(cx: &LateContext, ex: &Expr, arms: &[Arm]) {
fn check_overlapping_arms<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ex: &'tcx Expr, arms: &'tcx [Arm]) {
if arms.len() >= 2 && cx.tables.expr_ty(ex).is_integral() {
let ranges = all_ranges(cx, arms, ex.id);
let type_ranges = type_ranges(&ranges);
@ -411,7 +411,7 @@ fn check_match_ref_pats(cx: &LateContext, ex: &Expr, arms: &[Arm], source: Match
}
/// Get all arms that are unbounded `PatRange`s.
fn all_ranges<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, arms: &[Arm], id: NodeId) -> Vec<SpannedRange<ConstVal<'tcx>>> {
fn all_ranges<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, arms: &'tcx [Arm], id: NodeId) -> Vec<SpannedRange<&'tcx ty::Const<'tcx>>> {
let parent_item = cx.tcx.hir.get_parent(id);
let parent_def_id = cx.tcx.hir.local_def_id(parent_item);
let substs = Substs::identity_for_item(cx.tcx, parent_def_id);
@ -444,7 +444,7 @@ fn all_ranges<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, arms: &[Arm], id: NodeId) ->
let PatKind::Lit(ref value) = pat.node,
let Ok(value) = constcx.eval(value)
], {
return Some(SpannedRange { span: pat.span, node: (value.clone(), Bound::Included(value)) });
return Some(SpannedRange { span: pat.span, node: (value, Bound::Included(value)) });
}}
None
@ -464,19 +464,19 @@ type TypedRanges = Vec<SpannedRange<ConstInt>>;
/// Get all `Int` ranges or all `Uint` ranges. Mixed types are an error anyway
/// and other types than
/// `Uint` and `Int` probably don't make sense.
fn type_ranges(ranges: &[SpannedRange<ConstVal>]) -> TypedRanges {
fn type_ranges(ranges: &[SpannedRange<&ty::Const>]) -> TypedRanges {
ranges
.iter()
.filter_map(|range| match range.node {
(ConstVal::Integral(start), Bound::Included(ConstVal::Integral(end))) => Some(SpannedRange {
(&ty::Const { val: ConstVal::Integral(start), .. }, Bound::Included(&ty::Const { val: ConstVal::Integral(end), .. })) => Some(SpannedRange {
span: range.span,
node: (start, Bound::Included(end)),
}),
(ConstVal::Integral(start), Bound::Excluded(ConstVal::Integral(end))) => Some(SpannedRange {
(&ty::Const { val: ConstVal::Integral(start), .. }, Bound::Excluded(&ty::Const { val: ConstVal::Integral(end), .. })) => Some(SpannedRange {
span: range.span,
node: (start, Bound::Excluded(end)),
}),
(ConstVal::Integral(start), Bound::Unbounded) => Some(SpannedRange {
(&ty::Const { val: ConstVal::Integral(start), .. }, Bound::Unbounded) => Some(SpannedRange {
span: range.span,
node: (start, Bound::Unbounded),
}),

View File

@ -14,6 +14,7 @@ use utils::{get_trait_def_id, implements_trait, in_external_macro, in_macro, is_
span_lint_and_sugg, span_lint_and_then, span_note_and_lint, walk_ptrs_ty, walk_ptrs_ty_depth};
use utils::paths;
use utils::sugg;
use utils::const_to_u64;
#[derive(Clone)]
pub struct Pass;
@ -1049,7 +1050,7 @@ fn derefs_to_slice(cx: &LateContext, expr: &hir::Expr, ty: Ty) -> Option<sugg::S
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::TyArray(_, size) => const_to_u64(size) < 32,
ty::TyRef(_, ty::TypeAndMut { ty: inner, .. }) => may_slice(cx, inner),
_ => false,
}
@ -1155,7 +1156,7 @@ fn lint_map_unwrap_or(cx: &LateContext, expr: &hir::Expr, map_args: &[hir::Expr]
}
/// lint use of `map().unwrap_or_else()` for `Option`s
fn lint_map_unwrap_or_else(cx: &LateContext, expr: &hir::Expr, map_args: &[hir::Expr], unwrap_args: &[hir::Expr]) {
fn lint_map_unwrap_or_else<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr, map_args: &'tcx [hir::Expr], unwrap_args: &'tcx [hir::Expr]) {
// lint if the caller of `map()` is an `Option`
if match_type(cx, cx.tables.expr_ty(&map_args[0]), &paths::OPTION) {
// lint message
@ -1188,7 +1189,7 @@ fn lint_map_unwrap_or_else(cx: &LateContext, expr: &hir::Expr, map_args: &[hir::
}
/// lint use of `filter().next()` for `Iterators`
fn lint_filter_next(cx: &LateContext, expr: &hir::Expr, filter_args: &[hir::Expr]) {
fn lint_filter_next<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr, filter_args: &'tcx [hir::Expr]) {
// lint if caller of `.filter().next()` is an Iterator
if match_trait_method(cx, expr, &paths::ITERATOR) {
let msg = "called `filter(p).next()` on an `Iterator`. This is more succinctly expressed by calling \
@ -1211,7 +1212,7 @@ fn lint_filter_next(cx: &LateContext, expr: &hir::Expr, filter_args: &[hir::Expr
}
/// lint use of `filter().map()` for `Iterators`
fn lint_filter_map(cx: &LateContext, expr: &hir::Expr, _filter_args: &[hir::Expr], _map_args: &[hir::Expr]) {
fn lint_filter_map<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr, _filter_args: &'tcx [hir::Expr], _map_args: &'tcx [hir::Expr]) {
// lint if caller of `.filter().map()` is an Iterator
if match_trait_method(cx, expr, &paths::ITERATOR) {
let msg = "called `filter(p).map(q)` on an `Iterator`. \
@ -1221,7 +1222,7 @@ fn lint_filter_map(cx: &LateContext, expr: &hir::Expr, _filter_args: &[hir::Expr
}
/// lint use of `filter().map()` for `Iterators`
fn lint_filter_map_map(cx: &LateContext, expr: &hir::Expr, _filter_args: &[hir::Expr], _map_args: &[hir::Expr]) {
fn lint_filter_map_map<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr, _filter_args: &'tcx [hir::Expr], _map_args: &'tcx [hir::Expr]) {
// lint if caller of `.filter().map()` is an Iterator
if match_trait_method(cx, expr, &paths::ITERATOR) {
let msg = "called `filter_map(p).map(q)` on an `Iterator`. \
@ -1231,7 +1232,7 @@ fn lint_filter_map_map(cx: &LateContext, expr: &hir::Expr, _filter_args: &[hir::
}
/// lint use of `filter().flat_map()` for `Iterators`
fn lint_filter_flat_map(cx: &LateContext, expr: &hir::Expr, _filter_args: &[hir::Expr], _map_args: &[hir::Expr]) {
fn lint_filter_flat_map<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr, _filter_args: &'tcx [hir::Expr], _map_args: &'tcx [hir::Expr]) {
// lint if caller of `.filter().flat_map()` is an Iterator
if match_trait_method(cx, expr, &paths::ITERATOR) {
let msg = "called `filter(p).flat_map(q)` on an `Iterator`. \
@ -1242,7 +1243,7 @@ fn lint_filter_flat_map(cx: &LateContext, expr: &hir::Expr, _filter_args: &[hir:
}
/// lint use of `filter_map().flat_map()` for `Iterators`
fn lint_filter_map_flat_map(cx: &LateContext, expr: &hir::Expr, _filter_args: &[hir::Expr], _map_args: &[hir::Expr]) {
fn lint_filter_map_flat_map<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr, _filter_args: &'tcx [hir::Expr], _map_args: &'tcx [hir::Expr]) {
// lint if caller of `.filter_map().flat_map()` is an Iterator
if match_trait_method(cx, expr, &paths::ITERATOR) {
let msg = "called `filter_map(p).flat_map(q)` on an `Iterator`. \
@ -1253,12 +1254,12 @@ fn lint_filter_map_flat_map(cx: &LateContext, expr: &hir::Expr, _filter_args: &[
}
/// lint searching an Iterator followed by `is_some()`
fn lint_search_is_some(
cx: &LateContext,
expr: &hir::Expr,
fn lint_search_is_some<'a, 'tcx>(
cx: &LateContext<'a, 'tcx>,
expr: &'tcx hir::Expr,
search_method: &str,
search_args: &[hir::Expr],
is_some_args: &[hir::Expr],
search_args: &'tcx [hir::Expr],
is_some_args: &'tcx [hir::Expr],
) {
// lint if caller of search is an Iterator
if match_trait_method(cx, &is_some_args[0], &paths::ITERATOR) {
@ -1285,7 +1286,7 @@ fn lint_search_is_some(
}
/// Checks for the `CHARS_NEXT_CMP` lint.
fn lint_chars_next(cx: &LateContext, expr: &hir::Expr, chain: &hir::Expr, other: &hir::Expr, eq: bool) -> bool {
fn lint_chars_next<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr, chain: &'tcx hir::Expr, other: &'tcx hir::Expr, eq: bool) -> bool {
if_let_chain! {[
let Some(args) = method_chain_args(chain, &["chars", "next"]),
let hir::ExprCall(ref fun, ref arg_char) = other.node,
@ -1317,11 +1318,11 @@ fn lint_chars_next(cx: &LateContext, expr: &hir::Expr, chain: &hir::Expr, other:
}
/// lint for length-1 `str`s for methods in `PATTERN_METHODS`
fn lint_single_char_pattern(cx: &LateContext, expr: &hir::Expr, arg: &hir::Expr) {
fn lint_single_char_pattern<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr, arg: &'tcx hir::Expr) {
let parent_item = cx.tcx.hir.get_parent(arg.id);
let parent_def_id = cx.tcx.hir.local_def_id(parent_item);
let substs = Substs::identity_for_item(cx.tcx, parent_def_id);
if let Ok(ConstVal::Str(r)) = ConstContext::new(cx.tcx, cx.param_env.and(substs), cx.tables).eval(arg) {
if let Ok(&ty::Const { val: ConstVal::Str(r), .. }) = ConstContext::new(cx.tcx, cx.param_env.and(substs), cx.tables).eval(arg) {
if r.len() == 1 {
let hint = snippet(cx, expr.span, "..").replace(&format!("\"{}\"", r), &format!("'{}'", r));
span_lint_and_then(

View File

@ -419,12 +419,12 @@ fn check_nan(cx: &LateContext, path: &Path, expr: &Expr) {
}
}
fn is_allowed(cx: &LateContext, expr: &Expr) -> bool {
fn is_allowed<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) -> bool {
let parent_item = cx.tcx.hir.get_parent(expr.id);
let parent_def_id = cx.tcx.hir.local_def_id(parent_item);
let substs = Substs::identity_for_item(cx.tcx, parent_def_id);
let res = ConstContext::new(cx.tcx, cx.param_env.and(substs), cx.tables).eval(expr);
if let Ok(ConstVal::Float(val)) = res {
if let Ok(&ty::Const { val: ConstVal::Float(val), .. }) = res {
use std::cmp::Ordering;
match val.ty {
FloatTy::F32 => {

View File

@ -57,7 +57,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for StepByZero {
use consts::{constant, Constant};
use rustc_const_math::ConstInt::Usize;
if let Some((Constant::Int(Usize(us)), _)) = constant(cx, &args[1]) {
if us.as_u64(cx.sess().target.uint_type) == 0 {
if us.as_u64() == 0 {
span_lint(
cx,
ITERATOR_STEP_BY_ZERO,

View File

@ -1,6 +1,7 @@
use regex_syntax;
use rustc::hir::*;
use rustc::lint::*;
use rustc::ty;
use rustc::middle::const_val::ConstVal;
use rustc_const_eval::ConstContext;
use rustc::ty::subst::Substs;
@ -145,12 +146,12 @@ fn str_span(base: Span, s: &str, c: usize) -> Span {
}
}
fn const_str(cx: &LateContext, e: &Expr) -> Option<InternedString> {
fn const_str<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) -> Option<InternedString> {
let parent_item = cx.tcx.hir.get_parent(e.id);
let parent_def_id = cx.tcx.hir.local_def_id(parent_item);
let substs = Substs::identity_for_item(cx.tcx, parent_def_id);
match ConstContext::new(cx.tcx, cx.param_env.and(substs), cx.tables).eval(e) {
Ok(ConstVal::Str(r)) => Some(r),
Ok(&ty::Const { val: ConstVal::Str(r), .. }) => Some(r),
_ => None,
}
}
@ -179,7 +180,7 @@ fn is_trivial_regex(s: &regex_syntax::Expr) -> Option<&'static str> {
}
}
fn check_set(cx: &LateContext, expr: &Expr, utf8: bool) {
fn check_set<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr, utf8: bool) {
if_let_chain! {[
let ExprAddrOf(_, ref expr) = expr.node,
let ExprArray(ref exprs) = expr.node,
@ -190,7 +191,7 @@ fn check_set(cx: &LateContext, expr: &Expr, utf8: bool) {
}}
}
fn check_regex(cx: &LateContext, expr: &Expr, utf8: bool) {
fn check_regex<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr, utf8: bool) {
let builder = regex_syntax::ExprBuilder::new().unicode(utf8);
if let ExprLit(ref lit) = expr.node {

View File

@ -1061,12 +1061,12 @@ enum AbsurdComparisonResult {
fn detect_absurd_comparison<'a>(
cx: &LateContext,
fn detect_absurd_comparison<'a, 'tcx>(
cx: &LateContext<'a, 'tcx>,
op: BinOp_,
lhs: &'a Expr,
rhs: &'a Expr,
) -> Option<(ExtremeExpr<'a>, AbsurdComparisonResult)> {
lhs: &'tcx Expr,
rhs: &'tcx Expr,
) -> Option<(ExtremeExpr<'tcx>, AbsurdComparisonResult)> {
use types::ExtremeType::*;
use types::AbsurdComparisonResult::*;
use utils::comparisons::*;
@ -1108,7 +1108,7 @@ fn detect_absurd_comparison<'a>(
})
}
fn detect_extreme_expr<'a>(cx: &LateContext, expr: &'a Expr) -> Option<ExtremeExpr<'a>> {
fn detect_extreme_expr<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) -> Option<ExtremeExpr<'tcx>> {
use rustc::middle::const_val::ConstVal::*;
use rustc_const_math::*;
use rustc_const_eval::*;
@ -1129,7 +1129,7 @@ fn detect_extreme_expr<'a>(cx: &LateContext, expr: &'a Expr) -> Option<ExtremeEx
Err(_) => return None,
};
let which = match (&ty.sty, cv) {
let which = match (&ty.sty, cv.val) {
(&ty::TyBool, Bool(false)) |
(&ty::TyInt(IntTy::Is), Integral(Isize(Is32(::std::i32::MIN)))) |
(&ty::TyInt(IntTy::Is), Integral(Isize(Is64(::std::i64::MIN)))) |
@ -1336,7 +1336,7 @@ fn numeric_cast_precast_bounds<'a>(cx: &LateContext, expr: &'a Expr) -> Option<(
}
#[allow(cast_possible_wrap)]
fn node_as_const_fullint(cx: &LateContext, expr: &Expr) -> Option<FullInt> {
fn node_as_const_fullint<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) -> Option<FullInt> {
use rustc::middle::const_val::ConstVal::*;
use rustc_const_eval::ConstContext;
@ -1344,7 +1344,7 @@ fn node_as_const_fullint(cx: &LateContext, expr: &Expr) -> Option<FullInt> {
let parent_def_id = cx.tcx.hir.local_def_id(parent_item);
let substs = Substs::identity_for_item(cx.tcx, parent_def_id);
match ConstContext::new(cx.tcx, cx.param_env.and(substs), cx.tables).eval(expr) {
Ok(val) => if let Integral(const_int) = val {
Ok(val) => if let Integral(const_int) = val.val {
match const_int.int_type() {
IntType::SignedInt(_) => Some(FullInt::S(const_int.to_u128_unchecked() as i128)),
IntType::UnsignedInt(_) => Some(FullInt::U(const_int.to_u128_unchecked())),
@ -1371,13 +1371,13 @@ fn err_upcast_comparison(cx: &LateContext, span: &Span, expr: &Expr, always: boo
}
}
fn upcast_comparison_bounds_err(
cx: &LateContext,
fn upcast_comparison_bounds_err<'a, 'tcx>(
cx: &LateContext<'a, 'tcx>,
span: &Span,
rel: comparisons::Rel,
lhs_bounds: Option<(FullInt, FullInt)>,
lhs: &Expr,
rhs: &Expr,
lhs: &'tcx Expr,
rhs: &'tcx Expr,
invert: bool,
) {
use utils::comparisons::*;

View File

@ -313,6 +313,10 @@ pub fn path_to_def(cx: &LateContext, path: &[&str]) -> Option<def::Def> {
}
}
pub fn const_to_u64(c: &ty::Const) -> u64 {
c.val.to_const_int().expect("eddyb says this works").to_u64().expect("see previous expect")
}
/// Convenience function to get the `DefId` of a trait by path.
pub fn get_trait_def_id(cx: &LateContext, path: &[&str]) -> Option<DefId> {
let def = match path_to_def(cx, path) {

View File

@ -57,7 +57,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
}
}
fn check_vec_macro(cx: &LateContext, vec_args: &higher::VecArgs, span: Span) {
fn check_vec_macro<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, vec_args: &higher::VecArgs<'tcx>, span: Span) {
let snippet = match *vec_args {
higher::VecArgs::Repeat(elem, len) => {
let parent_item = cx.tcx.hir.get_parent(len.id);

View File

@ -74,5 +74,37 @@ note: consider deriving `Clone` or removing `Copy`
67 | | }
| |_^
error: aborting due to 5 previous errors
error: you are implementing `Clone` explicitly on a `Copy` type
--> $DIR/derive.rs:75:1
|
75 | / impl Clone for BigArray {
76 | | fn clone(&self) -> Self { unimplemented!() }
77 | | }
| |_^
|
note: consider deriving `Clone` or removing `Copy`
--> $DIR/derive.rs:75:1
|
75 | / impl Clone for BigArray {
76 | | fn clone(&self) -> Self { unimplemented!() }
77 | | }
| |_^
error: you are implementing `Clone` explicitly on a `Copy` type
--> $DIR/derive.rs:85:1
|
85 | / impl Clone for FnPtr {
86 | | fn clone(&self) -> Self { unimplemented!() }
87 | | }
| |_^
|
note: consider deriving `Clone` or removing `Copy`
--> $DIR/derive.rs:85:1
|
85 | / impl Clone for FnPtr {
86 | | fn clone(&self) -> Self { unimplemented!() }
87 | | }
| |_^
error: aborting due to 7 previous errors