From eef2e8948b4f0de21669231933739ef0d0f0017a Mon Sep 17 00:00:00 2001 From: Devon Hollowood Date: Mon, 8 Oct 2018 21:40:21 -0700 Subject: [PATCH 1/3] Fix cast_possible_truncation warnings --- clippy_lints/src/consts.rs | 27 ++++++++++++++++++++------- clippy_lints/src/lib.rs | 1 + clippy_lints/src/regex.rs | 19 +++++++++++++++++-- clippy_lints/src/utils/sugg.rs | 3 ++- src/driver.rs | 4 +++- 5 files changed, 43 insertions(+), 11 deletions(-) diff --git a/clippy_lints/src/consts.rs b/clippy_lints/src/consts.rs index 2422e8e8a..b84430e68 100644 --- a/clippy_lints/src/consts.rs +++ b/clippy_lints/src/consts.rs @@ -18,6 +18,7 @@ use crate::rustc::ty::{self, Ty, TyCtxt, Instance}; use crate::rustc::ty::subst::{Subst, Substs}; use std::cmp::Ordering::{self, Equal}; use std::cmp::PartialOrd; +use std::convert::TryInto; use std::hash::{Hash, Hasher}; use std::mem; use std::rc::Rc; @@ -341,8 +342,12 @@ impl<'c, 'cc> ConstEvalLateContext<'c, 'cc> { BinOpKind::Mul => l.checked_mul(r).map(zext), BinOpKind::Div if r != 0 => l.checked_div(r).map(zext), BinOpKind::Rem if r != 0 => l.checked_rem(r).map(zext), - BinOpKind::Shr => l.checked_shr(r as u128 as u32).map(zext), - BinOpKind::Shl => l.checked_shl(r as u128 as u32).map(zext), + BinOpKind::Shr => l.checked_shr( + (r as u128).try_into().expect("shift too large") + ).map(zext), + BinOpKind::Shl => l.checked_shl( + (r as u128).try_into().expect("shift too large") + ).map(zext), BinOpKind::BitXor => Some(zext(l ^ r)), BinOpKind::BitOr => Some(zext(l | r)), BinOpKind::BitAnd => Some(zext(l & r)), @@ -362,8 +367,12 @@ impl<'c, 'cc> ConstEvalLateContext<'c, 'cc> { BinOpKind::Mul => l.checked_mul(r).map(Constant::Int), BinOpKind::Div => l.checked_div(r).map(Constant::Int), BinOpKind::Rem => l.checked_rem(r).map(Constant::Int), - BinOpKind::Shr => l.checked_shr(r as u32).map(Constant::Int), - BinOpKind::Shl => l.checked_shl(r as u32).map(Constant::Int), + BinOpKind::Shr => l.checked_shr( + r.try_into().expect("shift too large") + ).map(Constant::Int), + BinOpKind::Shl => l.checked_shl( + r.try_into().expect("shift too large") + ).map(Constant::Int), BinOpKind::BitXor => Some(Constant::Int(l ^ r)), BinOpKind::BitOr => Some(Constant::Int(l | r)), BinOpKind::BitAnd => Some(Constant::Int(l & r)), @@ -426,8 +435,12 @@ pub fn miri_to_const<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, result: &ty::Const<' ConstValue::Scalar(Scalar::Bits{ bits: b, ..}) => match result.ty.sty { ty::Bool => Some(Constant::Bool(b == 1)), ty::Uint(_) | ty::Int(_) => Some(Constant::Int(b)), - ty::Float(FloatTy::F32) => Some(Constant::F32(f32::from_bits(b as u32))), - ty::Float(FloatTy::F64) => Some(Constant::F64(f64::from_bits(b as u64))), + ty::Float(FloatTy::F32) => Some(Constant::F32(f32::from_bits( + b.try_into().expect("invalid f32 bit representation") + ))), + ty::Float(FloatTy::F64) => Some(Constant::F64(f64::from_bits( + b.try_into().expect("invalid f64 bit representation") + ))), // FIXME: implement other conversion _ => None, }, @@ -439,7 +452,7 @@ pub fn miri_to_const<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, result: &ty::Const<' .alloc_map .lock() .unwrap_memory(ptr.alloc_id); - let offset = ptr.offset.bytes() as usize; + let offset = ptr.offset.bytes().try_into().expect("too-large pointer offset"); let n = n as usize; String::from_utf8(alloc.bytes[offset..(offset + n)].to_owned()).ok().map(Constant::Str) }, diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index e4ad9fe9c..af69a6284 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -21,6 +21,7 @@ #![feature(tool_lints)] #![warn(rust_2018_idioms, trivial_casts, trivial_numeric_casts)] #![feature(crate_visibility_modifier)] +#![feature(try_from)] // FIXME: switch to something more ergonomic here, once available. // (currently there is no way to opt into sysroot crates w/o `extern crate`) diff --git a/clippy_lints/src/regex.rs b/clippy_lints/src/regex.rs index 7a818c41f..deb32e49a 100644 --- a/clippy_lints/src/regex.rs +++ b/clippy_lints/src/regex.rs @@ -18,6 +18,7 @@ use crate::syntax::ast::{LitKind, NodeId, StrStyle}; use crate::syntax::source_map::{BytePos, Span}; use crate::utils::{is_expn_of, match_def_path, match_type, opt_def_id, paths, span_help_and_lint, span_lint}; use crate::consts::{constant, Constant}; +use std::convert::TryInto; /// **What it does:** Checks [regex](https://crates.io/crates/regex) creation /// (with `Regex::new`,`RegexBuilder::new` or `RegexSet::new`) for correct @@ -143,8 +144,22 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { fn str_span(base: Span, c: regex_syntax::ast::Span, offset: u16) -> Span { let offset = u32::from(offset); - let end = base.lo() + BytePos(c.end.offset as u32 + offset); - let start = base.lo() + BytePos(c.start.offset as u32 + offset); + let end = base.lo() + BytePos( + c.end + .offset + .try_into() + .ok() + .and_then(|o: u32| o.checked_add(offset)) + .expect("offset too large"), + ); + let start = base.lo() + BytePos( + c.start + .offset + .try_into() + .ok() + .and_then(|o: u32| o.checked_add(offset)) + .expect("offset too large"), + ); assert!(start <= end); Span::new(start, end, base.ctxt()) } diff --git a/clippy_lints/src/utils/sugg.rs b/clippy_lints/src/utils/sugg.rs index fecfc0c07..eb67838f1 100644 --- a/clippy_lints/src/utils/sugg.rs +++ b/clippy_lints/src/utils/sugg.rs @@ -16,6 +16,7 @@ use crate::rustc::hir; use crate::rustc::lint::{EarlyContext, LateContext, LintContext}; use crate::rustc_errors; use std::borrow::Cow; +use std::convert::TryInto; use std::fmt::Display; use std; use crate::syntax::source_map::{CharPos, Span}; @@ -551,7 +552,7 @@ impl<'a, 'b, 'c, T: LintContext<'c>> DiagnosticBuilderExt<'c, T> for rustc_error let non_whitespace_offset = src[fmpos.pos.to_usize()..].find(|c| c != ' ' && c != '\t' && c != '\n'); if let Some(non_whitespace_offset) = non_whitespace_offset { - remove_span = remove_span.with_hi(remove_span.hi() + BytePos(non_whitespace_offset as u32)) + remove_span = remove_span.with_hi(remove_span.hi() + BytePos(non_whitespace_offset.try_into().expect("offset too large"))) } } diff --git a/src/driver.rs b/src/driver.rs index d2ed3cb1c..0619b3ae0 100644 --- a/src/driver.rs +++ b/src/driver.rs @@ -12,6 +12,7 @@ #![feature(box_syntax)] #![feature(rustc_private)] #![feature(tool_lints)] +#![feature(try_from)] #![allow(unknown_lints, clippy::missing_docs_in_private_items)] // FIXME: switch to something more ergonomic here, once available. @@ -22,6 +23,7 @@ extern crate rustc_driver; extern crate rustc_plugin; use self::rustc_driver::{driver::CompileController, Compilation}; +use std::convert::TryInto; use std::path::Path; use std::process::{exit, Command}; @@ -153,5 +155,5 @@ pub fn main() { let args = args; rustc_driver::run_compiler(&args, Box::new(controller), None, None) - }) as i32) + }).try_into().expect("exit code too large")) } From 2b9abc5daa67120e9b8b711885b71a4c63399921 Mon Sep 17 00:00:00 2001 From: Devon Hollowood Date: Mon, 8 Oct 2018 22:34:10 -0700 Subject: [PATCH 2/3] Fix cast_possible_wrap and cast_sign_loss warnings --- clippy_lints/src/consts.rs | 5 +++-- clippy_lints/src/enum_clike.rs | 2 +- clippy_lints/src/utils/mod.rs | 2 ++ 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/clippy_lints/src/consts.rs b/clippy_lints/src/consts.rs index b84430e68..5d509ef76 100644 --- a/clippy_lints/src/consts.rs +++ b/clippy_lints/src/consts.rs @@ -230,6 +230,7 @@ impl<'c, 'cc> ConstEvalLateContext<'c, 'cc> { } } + #[allow(clippy::cast_possible_wrap)] fn constant_not(&self, o: &Constant, ty: ty::Ty<'_>) -> Option { use self::Constant::*; match *o { @@ -343,10 +344,10 @@ impl<'c, 'cc> ConstEvalLateContext<'c, 'cc> { BinOpKind::Div if r != 0 => l.checked_div(r).map(zext), BinOpKind::Rem if r != 0 => l.checked_rem(r).map(zext), BinOpKind::Shr => l.checked_shr( - (r as u128).try_into().expect("shift too large") + r.try_into().expect("invalid shift") ).map(zext), BinOpKind::Shl => l.checked_shl( - (r as u128).try_into().expect("shift too large") + r.try_into().expect("invalid shift") ).map(zext), BinOpKind::BitXor => Some(zext(l ^ r)), BinOpKind::BitOr => Some(zext(l | r)), diff --git a/clippy_lints/src/enum_clike.rs b/clippy_lints/src/enum_clike.rs index 8fba45de8..313175aee 100644 --- a/clippy_lints/src/enum_clike.rs +++ b/clippy_lints/src/enum_clike.rs @@ -53,7 +53,7 @@ impl LintPass for UnportableVariant { } impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnportableVariant { - #[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)] + #[allow(clippy::cast_possible_truncation, clippy::cast_possible_wrap, clippy::cast_sign_loss)] fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx Item) { if cx.tcx.data_layout.pointer_size.bits() != 64 { return; diff --git a/clippy_lints/src/utils/mod.rs b/clippy_lints/src/utils/mod.rs index 7282e5064..2a9b1cb0a 100644 --- a/clippy_lints/src/utils/mod.rs +++ b/clippy_lints/src/utils/mod.rs @@ -971,12 +971,14 @@ pub fn int_bits(tcx: TyCtxt<'_, '_, '_>, ity: ast::IntTy) -> u64 { layout::Integer::from_attr(tcx, attr::IntType::SignedInt(ity)).size().bits() } +#[allow(clippy::cast_possible_wrap)] /// Turn a constant int byte representation into an i128 pub fn sext(tcx: TyCtxt<'_, '_, '_>, u: u128, ity: ast::IntTy) -> i128 { let amt = 128 - int_bits(tcx, ity); ((u as i128) << amt) >> amt } +#[allow(clippy::cast_sign_loss)] /// clip unused bytes pub fn unsext(tcx: TyCtxt<'_, '_, '_>, u: i128, ity: ast::IntTy) -> u128 { let amt = 128 - int_bits(tcx, ity); From 289c642d1a58c6173a1c3adbc26dbb89a7fde4ca Mon Sep 17 00:00:00 2001 From: Devon Hollowood Date: Tue, 9 Oct 2018 23:35:10 -0700 Subject: [PATCH 3/3] Clarify code Take advantage of the fact that very large regexes are unlikely --- clippy_lints/src/regex.rs | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/clippy_lints/src/regex.rs b/clippy_lints/src/regex.rs index deb32e49a..e68468d4d 100644 --- a/clippy_lints/src/regex.rs +++ b/clippy_lints/src/regex.rs @@ -18,7 +18,7 @@ use crate::syntax::ast::{LitKind, NodeId, StrStyle}; use crate::syntax::source_map::{BytePos, Span}; use crate::utils::{is_expn_of, match_def_path, match_type, opt_def_id, paths, span_help_and_lint, span_lint}; use crate::consts::{constant, Constant}; -use std::convert::TryInto; +use std::convert::TryFrom; /// **What it does:** Checks [regex](https://crates.io/crates/regex) creation /// (with `Regex::new`,`RegexBuilder::new` or `RegexSet::new`) for correct @@ -142,24 +142,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { } } +#[allow(clippy::cast_possible_truncation)] // truncation very unlikely here fn str_span(base: Span, c: regex_syntax::ast::Span, offset: u16) -> Span { let offset = u32::from(offset); - let end = base.lo() + BytePos( - c.end - .offset - .try_into() - .ok() - .and_then(|o: u32| o.checked_add(offset)) - .expect("offset too large"), - ); - let start = base.lo() + BytePos( - c.start - .offset - .try_into() - .ok() - .and_then(|o: u32| o.checked_add(offset)) - .expect("offset too large"), - ); + let end = base.lo() + BytePos(u32::try_from(c.end.offset).expect("offset too large") + offset); + let start = base.lo() + BytePos(u32::try_from(c.start.offset).expect("offset too large") + offset); assert!(start <= end); Span::new(start, end, base.ctxt()) }