From 21f387d27810edd4ec135cc307dccc6d8e55d48b Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Tue, 13 Mar 2018 15:02:40 +0100 Subject: [PATCH] Update dependencies --- .gitignore | 1 + Cargo.toml | 3 +- clippy_lints/Cargo.toml | 10 ++-- clippy_lints/src/regex.rs | 107 +++++++++++++++++++++++++------------- src/main.rs | 8 +-- tests/compile-test.rs | 2 +- tests/ui/regex.stderr | 64 ++++++++++++----------- tests/versioncheck.rs | 4 +- 8 files changed, 122 insertions(+), 77 deletions(-) diff --git a/.gitignore b/.gitignore index 43552238725..6f472c418d2 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,7 @@ out Cargo.lock /target /clippy_lints/target +/clippy_workspace_tests/target # Generated by dogfood /target_recur/ diff --git a/Cargo.toml b/Cargo.toml index efaa00acd66..a256be6085b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,8 +39,9 @@ path = "src/driver.rs" # begin automatic update clippy_lints = { version = "0.0.187", path = "clippy_lints" } # end automatic update -cargo_metadata = "0.2" +cargo_metadata = "0.5" regex = "0.2" +semver = "0.9" [dev-dependencies] compiletest_rs = "0.3.7" diff --git a/clippy_lints/Cargo.toml b/clippy_lints/Cargo.toml index cee48c1514d..f8c93c9d7ed 100644 --- a/clippy_lints/Cargo.toml +++ b/clippy_lints/Cargo.toml @@ -16,18 +16,18 @@ license = "MPL-2.0" keywords = ["clippy", "lint", "plugin"] [dependencies] -itertools = "0.6.0" +itertools = "0.7" lazy_static = "1.0" matches = "0.1.2" quine-mc_cluskey = "0.2.2" -regex-syntax = "0.4.0" -semver = "0.6.0" +regex-syntax = "0.5.0" +semver = "0.9.0" serde = "1.0" serde_derive = "1.0" toml = "0.4" unicode-normalization = "0.1" -pulldown-cmark = "0.0.15" -url = "1.5.0" +pulldown-cmark = "0.1" +url = "1.7.0" if_chain = "0.1" [features] diff --git a/clippy_lints/src/regex.rs b/clippy_lints/src/regex.rs index bbb70e0cdea..f2c08944f50 100644 --- a/clippy_lints/src/regex.rs +++ b/clippy_lints/src/regex.rs @@ -6,7 +6,6 @@ use rustc::middle::const_val::ConstVal; use rustc_const_eval::ConstContext; use rustc::ty::subst::Substs; use std::collections::HashSet; -use std::error::Error; use syntax::ast::{LitKind, NodeId, StrStyle}; use syntax::codemap::{BytePos, Span}; use syntax::symbol::InternedString; @@ -134,16 +133,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { } } -#[allow(cast_possible_truncation)] -fn str_span(base: Span, s: &str, c: usize) -> Span { - let mut si = s.char_indices().skip(c); - - match (si.next(), si.next()) { - (Some((l, _)), Some((h, _))) => { - Span::new(base.lo() + BytePos(l as u32), base.lo() + BytePos(h as u32), base.ctxt()) - }, - _ => base, - } +fn str_span(base: Span, c: regex_syntax::ast::Span, offset: usize) -> Span { + let offset = offset as u32; + let end = base.lo() + BytePos(c.end.offset as u32 + offset); + let start = base.lo() + BytePos(c.start.offset as u32 + offset); + assert!(start <= end); + Span::new(start, end, base.ctxt()) } fn const_str<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) -> Option { @@ -159,24 +154,30 @@ fn const_str<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) -> Option Option<&'static str> { - use regex_syntax::Expr; +fn is_trivial_regex(s: ®ex_syntax::hir::Hir) -> Option<&'static str> { + use regex_syntax::hir::HirKind::*; + use regex_syntax::hir::Anchor::*; - match *s { - Expr::Empty | Expr::StartText | Expr::EndText => Some("the regex is unlikely to be useful as it is"), - Expr::Literal { .. } => Some("consider using `str::contains`"), - Expr::Concat(ref exprs) => match exprs.len() { - 2 => match (&exprs[0], &exprs[1]) { - (&Expr::StartText, &Expr::EndText) => Some("consider using `str::is_empty`"), - (&Expr::StartText, &Expr::Literal { .. }) => Some("consider using `str::starts_with`"), - (&Expr::Literal { .. }, &Expr::EndText) => Some("consider using `str::ends_with`"), - _ => None, - }, - 3 => if let (&Expr::StartText, &Expr::Literal { .. }, &Expr::EndText) = (&exprs[0], &exprs[1], &exprs[2]) { - Some("consider using `==` on `str`s") - } else { - None - }, + let is_literal = |e: &[regex_syntax::hir::Hir]| e.iter().all(|e| match *e.kind() { + Literal(_) => true, + _ => false, + }); + + match *s.kind() { + Empty | + Anchor(_) => Some("the regex is unlikely to be useful as it is"), + Literal(_) => Some("consider using `str::contains`"), + Alternation(ref exprs) => if exprs.iter().all(|e| e.kind().is_empty()) { + Some("the regex is unlikely to be useful as it is") + } else { + None + }, + Concat(ref exprs) => match (exprs[0].kind(), exprs[exprs.len() - 1].kind()) { + (&Anchor(StartText), &Anchor(EndText)) if exprs[1..(exprs.len() - 1)].is_empty() => Some("consider using `str::is_empty`"), + (&Anchor(StartText), &Anchor(EndText)) if is_literal(&exprs[1..(exprs.len() - 1)]) => Some("consider using `==` on `str`s"), + (&Anchor(StartText), &Literal(_)) if is_literal(&exprs[1..]) => Some("consider using `str::starts_with`"), + (&Literal(_), &Anchor(EndText)) if is_literal(&exprs[1..(exprs.len() - 1)]) => Some("consider using `str::ends_with`"), + _ if is_literal(exprs) => Some("consider using `str::contains`"), _ => None, }, _ => None, @@ -196,41 +197,73 @@ fn check_set<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx 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); + let mut parser = regex_syntax::ParserBuilder::new().unicode(utf8).build(); if let ExprLit(ref lit) = expr.node { if let LitKind::Str(ref r, style) = lit.node { let r = &r.as_str(); - let offset = if let StrStyle::Raw(n) = style { 1 + n } else { 0 }; - match builder.parse(r) { + let offset = if let StrStyle::Raw(n) = style { 2 + n } else { 1 }; + match parser.parse(r) { Ok(r) => if let Some(repl) = is_trivial_regex(&r) { span_help_and_lint( cx, TRIVIAL_REGEX, expr.span, "trivial regex", - &format!("consider using {}", repl), + repl, + ); + }, + Err(regex_syntax::Error::Parse(e)) => { + span_lint( + cx, + INVALID_REGEX, + str_span(expr.span, *e.span(), offset), + &format!("regex syntax error: {}", e.kind()), + ); + }, + Err(regex_syntax::Error::Translate(e)) => { + span_lint( + cx, + INVALID_REGEX, + str_span(expr.span, *e.span(), offset), + &format!("regex syntax error: {}", e.kind()), ); }, Err(e) => { span_lint( cx, INVALID_REGEX, - str_span(expr.span, r, e.position() + offset), - &format!("regex syntax error: {}", e.description()), + expr.span, + &format!("regex syntax error: {}", e), ); }, } } } else if let Some(r) = const_str(cx, expr) { - match builder.parse(&r) { + match parser.parse(&r) { Ok(r) => if let Some(repl) = is_trivial_regex(&r) { span_help_and_lint( cx, TRIVIAL_REGEX, expr.span, "trivial regex", - &format!("consider using {}", repl), + repl, + ); + }, + Err(regex_syntax::Error::Parse(e)) => { + span_lint( + cx, + INVALID_REGEX, + expr.span, + &format!("regex syntax error on position {}: {}", e.span().start.offset, e.kind()), + ); + }, + Err(regex_syntax::Error::Translate(e)) => { + span_lint( + cx, + INVALID_REGEX, + expr.span, + &format!("regex syntax error on position {}: {}", e.span().start.offset, e.kind()), ); }, Err(e) => { @@ -238,7 +271,7 @@ fn check_regex<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr, utf8: boo cx, INVALID_REGEX, expr.span, - &format!("regex syntax error on position {}: {}", e.position(), e.description()), + &format!("regex syntax error: {}", e), ); }, } diff --git a/src/main.rs b/src/main.rs index 8fd485b9efa..ab2b3b9a4a0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,7 +9,7 @@ use std::io::{self, Write}; extern crate cargo_metadata; -use std::path::Path; +use std::path::{Path, PathBuf}; const CARGO_CLIPPY_HELP: &str = r#"Checks a package to catch common mistakes and improve your Rust code. @@ -61,17 +61,19 @@ pub fn main() { let manifest_path_arg = std::env::args() .skip(2) - .find(|val| val.starts_with("--manifest-path=")); + .find(|val| val.starts_with("--manifest-path=")) + .map(|val| val["--manifest-path=".len()..].to_owned()); let mut metadata = if let Ok(metadata) = cargo_metadata::metadata(manifest_path_arg.as_ref().map(AsRef::as_ref)) { metadata } else { + println!("{:?}", cargo_metadata::metadata(manifest_path_arg.as_ref().map(AsRef::as_ref))); let _ = io::stderr().write_fmt(format_args!("error: Could not obtain cargo metadata.\n")); process::exit(101); }; let manifest_path = manifest_path_arg.map(|arg| { - Path::new(&arg["--manifest-path=".len()..]) + PathBuf::from(arg) .canonicalize() .expect("manifest path could not be canonicalized") }); diff --git a/tests/compile-test.rs b/tests/compile-test.rs index 5bf1bd5d13b..5e059084da8 100644 --- a/tests/compile-test.rs +++ b/tests/compile-test.rs @@ -68,7 +68,7 @@ fn run_mode(dir: &'static str, mode: &'static str) { fn prepare_env() { set_var("CLIPPY_DISABLE_DOCS_LINKS", "true"); set_var("CLIPPY_TESTS", "true"); - set_var("RUST_BACKTRACE", "0"); + //set_var("RUST_BACKTRACE", "0"); } #[test] diff --git a/tests/ui/regex.stderr b/tests/ui/regex.stderr index 58c6e47afb7..45b2b7a2280 100644 --- a/tests/ui/regex.stderr +++ b/tests/ui/regex.stderr @@ -1,60 +1,67 @@ -error: regex syntax error: empty alternate +error: trivial regex --> $DIR/regex.rs:16:45 | 16 | let pipe_in_wrong_position = Regex::new("|"); | ^^^ | - = note: `-D invalid-regex` implied by `-D warnings` + = note: `-D trivial-regex` implied by `-D warnings` + = help: the regex is unlikely to be useful as it is -error: regex syntax error: empty alternate +error: trivial regex --> $DIR/regex.rs:17:60 | 17 | let pipe_in_wrong_position_builder = RegexBuilder::new("|"); | ^^^ + | + = help: the regex is unlikely to be useful as it is -error: regex syntax error: invalid character class range - --> $DIR/regex.rs:18:40 +error: regex syntax error: invalid character class range, the start must be <= the end + --> $DIR/regex.rs:18:42 | 18 | let wrong_char_ranice = Regex::new("[z-a]"); - | ^^^^^^^ + | ^^^ + | + = note: `-D invalid-regex` implied by `-D warnings` -error: regex syntax error: invalid character class range - --> $DIR/regex.rs:19:35 +error: regex syntax error: invalid character class range, the start must be <= the end + --> $DIR/regex.rs:19:37 | 19 | let some_unicode = Regex::new("[é-è]"); - | ^^^^^^^ + | ^^^ -error: regex syntax error on position 0: unclosed parenthesis +error: regex syntax error on position 0: unclosed group --> $DIR/regex.rs:21:33 | 21 | let some_regex = Regex::new(OPENING_PAREN); | ^^^^^^^^^^^^^ -error: regex syntax error: empty alternate +error: trivial regex --> $DIR/regex.rs:23:53 | 23 | let binary_pipe_in_wrong_position = BRegex::new("|"); | ^^^ + | + = help: the regex is unlikely to be useful as it is -error: regex syntax error on position 0: unclosed parenthesis +error: regex syntax error on position 0: unclosed group --> $DIR/regex.rs:24:41 | 24 | let some_binary_regex = BRegex::new(OPENING_PAREN); | ^^^^^^^^^^^^^ -error: regex syntax error on position 0: unclosed parenthesis +error: regex syntax error on position 0: unclosed group --> $DIR/regex.rs:25:56 | 25 | let some_binary_regex_builder = BRegexBuilder::new(OPENING_PAREN); | ^^^^^^^^^^^^^ -error: regex syntax error on position 0: unclosed parenthesis +error: regex syntax error on position 0: unclosed group --> $DIR/regex.rs:40:9 | 40 | OPENING_PAREN, | ^^^^^^^^^^^^^ -error: regex syntax error on position 0: unclosed parenthesis +error: regex syntax error on position 0: unclosed group --> $DIR/regex.rs:44:9 | 44 | OPENING_PAREN, @@ -64,13 +71,13 @@ error: regex syntax error: unrecognized escape sequence --> $DIR/regex.rs:48:45 | 48 | let raw_string_error = Regex::new(r"[...//...]"); - | ^ + | ^^ error: regex syntax error: unrecognized escape sequence --> $DIR/regex.rs:49:46 | 49 | let raw_string_error = Regex::new(r#"[...//...]"#); - | ^ + | ^^ error: trivial regex --> $DIR/regex.rs:53:33 @@ -78,8 +85,7 @@ error: trivial regex 53 | let trivial_eq = Regex::new("^foobar$"); | ^^^^^^^^^^ | - = note: `-D trivial-regex` implied by `-D warnings` - = help: consider using consider using `==` on `str`s + = help: consider using `==` on `str`s error: trivial regex --> $DIR/regex.rs:55:48 @@ -87,7 +93,7 @@ error: trivial regex 55 | let trivial_eq_builder = RegexBuilder::new("^foobar$"); | ^^^^^^^^^^ | - = help: consider using consider using `==` on `str`s + = help: consider using `==` on `str`s error: trivial regex --> $DIR/regex.rs:57:42 @@ -95,7 +101,7 @@ error: trivial regex 57 | let trivial_starts_with = Regex::new("^foobar"); | ^^^^^^^^^ | - = help: consider using consider using `str::starts_with` + = help: consider using `str::starts_with` error: trivial regex --> $DIR/regex.rs:59:40 @@ -103,7 +109,7 @@ error: trivial regex 59 | let trivial_ends_with = Regex::new("foobar$"); | ^^^^^^^^^ | - = help: consider using consider using `str::ends_with` + = help: consider using `str::ends_with` error: trivial regex --> $DIR/regex.rs:61:39 @@ -111,7 +117,7 @@ error: trivial regex 61 | let trivial_contains = Regex::new("foobar"); | ^^^^^^^^ | - = help: consider using consider using `str::contains` + = help: consider using `str::contains` error: trivial regex --> $DIR/regex.rs:63:39 @@ -119,7 +125,7 @@ error: trivial regex 63 | let trivial_contains = Regex::new(NOT_A_REAL_REGEX); | ^^^^^^^^^^^^^^^^ | - = help: consider using consider using `str::contains` + = help: consider using `str::contains` error: trivial regex --> $DIR/regex.rs:65:40 @@ -127,7 +133,7 @@ error: trivial regex 65 | let trivial_backslash = Regex::new("a/.b"); | ^^^^^^^ | - = help: consider using consider using `str::contains` + = help: consider using `str::contains` error: trivial regex --> $DIR/regex.rs:68:36 @@ -135,7 +141,7 @@ error: trivial regex 68 | let trivial_empty = Regex::new(""); | ^^ | - = help: consider using the regex is unlikely to be useful as it is + = help: the regex is unlikely to be useful as it is error: trivial regex --> $DIR/regex.rs:70:36 @@ -143,7 +149,7 @@ error: trivial regex 70 | let trivial_empty = Regex::new("^"); | ^^^ | - = help: consider using the regex is unlikely to be useful as it is + = help: the regex is unlikely to be useful as it is error: trivial regex --> $DIR/regex.rs:72:36 @@ -151,7 +157,7 @@ error: trivial regex 72 | let trivial_empty = Regex::new("^$"); | ^^^^ | - = help: consider using consider using `str::is_empty` + = help: consider using `str::is_empty` error: trivial regex --> $DIR/regex.rs:74:44 @@ -159,7 +165,7 @@ error: trivial regex 74 | let binary_trivial_empty = BRegex::new("^$"); | ^^^^ | - = help: consider using consider using `str::is_empty` + = help: consider using `str::is_empty` error: aborting due to 23 previous errors diff --git a/tests/versioncheck.rs b/tests/versioncheck.rs index beea9ab7e64..6fe82ac792e 100644 --- a/tests/versioncheck.rs +++ b/tests/versioncheck.rs @@ -1,4 +1,6 @@ extern crate cargo_metadata; +extern crate semver; +use semver::VersionReq; #[test] fn check_that_clippy_lints_has_the_same_version_as_clippy() { @@ -8,7 +10,7 @@ fn check_that_clippy_lints_has_the_same_version_as_clippy() { assert_eq!(clippy_lints_meta.packages[0].version, clippy_meta.packages[0].version); for package in &clippy_meta.packages[0].dependencies { if package.name == "clippy_lints" { - assert_eq!(clippy_lints_meta.packages[0].version, package.req[1..]); + assert_eq!(VersionReq::parse(&clippy_lints_meta.packages[0].version).unwrap(), package.req); return; } }