Skip to content

Commit 454bb33

Browse files
committed
Merge remote-tracking branch 'upstream/master' into rustup
2 parents 091239e + 780572b commit 454bb33

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+679
-164
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1439,6 +1439,7 @@ Released 2018-09-13
14391439
[`match_same_arms`]: https://rust-lang.github.io/rust-clippy/master/index.html#match_same_arms
14401440
[`match_single_binding`]: https://rust-lang.github.io/rust-clippy/master/index.html#match_single_binding
14411441
[`match_wild_err_arm`]: https://rust-lang.github.io/rust-clippy/master/index.html#match_wild_err_arm
1442+
[`match_wildcard_for_single_variants`]: https://rust-lang.github.io/rust-clippy/master/index.html#match_wildcard_for_single_variants
14421443
[`maybe_infinite_iter`]: https://rust-lang.github.io/rust-clippy/master/index.html#maybe_infinite_iter
14431444
[`mem_discriminant_non_enum`]: https://rust-lang.github.io/rust-clippy/master/index.html#mem_discriminant_non_enum
14441445
[`mem_forget`]: https://rust-lang.github.io/rust-clippy/master/index.html#mem_forget

clippy_dev/src/new_lint.rs

Lines changed: 106 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,91 +1,110 @@
11
use crate::clippy_project_root;
2-
use std::fs::{File, OpenOptions};
3-
use std::io;
2+
use std::fs::{self, OpenOptions};
43
use std::io::prelude::*;
5-
use std::io::ErrorKind;
6-
use std::path::Path;
4+
use std::io::{self, ErrorKind};
5+
use std::path::{Path, PathBuf};
6+
7+
struct LintData<'a> {
8+
pass: &'a str,
9+
name: &'a str,
10+
category: &'a str,
11+
project_root: PathBuf,
12+
}
13+
14+
trait Context {
15+
fn context<C: AsRef<str>>(self, text: C) -> Self;
16+
}
717

8-
/// Creates files required to implement and test a new lint and runs `update_lints`.
18+
impl<T> Context for io::Result<T> {
19+
fn context<C: AsRef<str>>(self, text: C) -> Self {
20+
match self {
21+
Ok(t) => Ok(t),
22+
Err(e) => {
23+
let message = format!("{}: {}", text.as_ref(), e);
24+
Err(io::Error::new(ErrorKind::Other, message))
25+
},
26+
}
27+
}
28+
}
29+
30+
/// Creates the files required to implement and test a new lint and runs `update_lints`.
931
///
1032
/// # Errors
1133
///
12-
/// This function errors, if the files couldn't be created
13-
pub fn create(pass: Option<&str>, lint_name: Option<&str>, category: Option<&str>) -> Result<(), io::Error> {
14-
let pass = pass.expect("`pass` argument is validated by clap");
15-
let lint_name = lint_name.expect("`name` argument is validated by clap");
16-
let category = category.expect("`category` argument is validated by clap");
17-
18-
match open_files(lint_name) {
19-
Ok((mut test_file, mut lint_file)) => {
20-
let (pass_type, pass_lifetimes, pass_import, context_import) = match pass {
21-
"early" => ("EarlyLintPass", "", "use rustc_ast::ast::*;", "EarlyContext"),
22-
"late" => ("LateLintPass", "<'_, '_>", "use rustc_hir::*;", "LateContext"),
23-
_ => {
24-
unreachable!("`pass_type` should only ever be `early` or `late`!");
25-
},
26-
};
27-
28-
let camel_case_name = to_camel_case(lint_name);
29-
30-
if let Err(e) = test_file.write_all(get_test_file_contents(lint_name).as_bytes()) {
31-
return Err(io::Error::new(
32-
ErrorKind::Other,
33-
format!("Could not write to test file: {}", e),
34-
));
35-
};
36-
37-
if let Err(e) = lint_file.write_all(
38-
get_lint_file_contents(
39-
pass_type,
40-
pass_lifetimes,
41-
lint_name,
42-
&camel_case_name,
43-
category,
44-
pass_import,
45-
context_import,
46-
)
47-
.as_bytes(),
48-
) {
49-
return Err(io::Error::new(
50-
ErrorKind::Other,
51-
format!("Could not write to lint file: {}", e),
52-
));
53-
}
54-
Ok(())
34+
/// This function errors out if the files couldn't be created or written to.
35+
pub fn create(pass: Option<&str>, lint_name: Option<&str>, category: Option<&str>) -> io::Result<()> {
36+
let lint = LintData {
37+
pass: pass.expect("`pass` argument is validated by clap"),
38+
name: lint_name.expect("`name` argument is validated by clap"),
39+
category: category.expect("`category` argument is validated by clap"),
40+
project_root: clippy_project_root(),
41+
};
42+
43+
create_lint(&lint).context("Unable to create lint implementation")?;
44+
create_test(&lint).context("Unable to create a test for the new lint")
45+
}
46+
47+
fn create_lint(lint: &LintData) -> io::Result<()> {
48+
let (pass_type, pass_lifetimes, pass_import, context_import) = match lint.pass {
49+
"early" => ("EarlyLintPass", "", "use rustc_ast::ast::*;", "EarlyContext"),
50+
"late" => ("LateLintPass", "<'_, '_>", "use rustc_hir::*;", "LateContext"),
51+
_ => {
52+
unreachable!("`pass_type` should only ever be `early` or `late`!");
5553
},
56-
Err(e) => Err(io::Error::new(
57-
ErrorKind::Other,
58-
format!("Unable to create lint: {}", e),
59-
)),
60-
}
54+
};
55+
56+
let camel_case_name = to_camel_case(lint.name);
57+
let lint_contents = get_lint_file_contents(
58+
pass_type,
59+
pass_lifetimes,
60+
lint.name,
61+
&camel_case_name,
62+
lint.category,
63+
pass_import,
64+
context_import,
65+
);
66+
67+
let lint_path = format!("clippy_lints/src/{}.rs", lint.name);
68+
write_file(lint.project_root.join(&lint_path), lint_contents.as_bytes())
6169
}
6270

63-
fn open_files(lint_name: &str) -> Result<(File, File), io::Error> {
64-
let project_root = clippy_project_root();
71+
fn create_test(lint: &LintData) -> io::Result<()> {
72+
fn create_project_layout<P: Into<PathBuf>>(lint_name: &str, location: P, case: &str, hint: &str) -> io::Result<()> {
73+
let mut path = location.into().join(case);
74+
fs::create_dir(&path)?;
75+
write_file(path.join("Cargo.toml"), get_manifest_contents(lint_name, hint))?;
6576

66-
let test_file_path = project_root.join("tests").join("ui").join(format!("{}.rs", lint_name));
67-
let lint_file_path = project_root
68-
.join("clippy_lints")
69-
.join("src")
70-
.join(format!("{}.rs", lint_name));
77+
path.push("src");
78+
fs::create_dir(&path)?;
79+
write_file(path.join("main.rs"), get_test_file_contents(lint_name))?;
7180

72-
if Path::new(&test_file_path).exists() {
73-
return Err(io::Error::new(
74-
ErrorKind::AlreadyExists,
75-
format!("test file {:?} already exists", test_file_path),
76-
));
81+
Ok(())
7782
}
78-
if Path::new(&lint_file_path).exists() {
79-
return Err(io::Error::new(
80-
ErrorKind::AlreadyExists,
81-
format!("lint file {:?} already exists", lint_file_path),
82-
));
83+
84+
if lint.category == "cargo" {
85+
let relative_test_dir = format!("tests/ui-cargo/{}", lint.name);
86+
let test_dir = lint.project_root.join(relative_test_dir);
87+
fs::create_dir(&test_dir)?;
88+
89+
create_project_layout(lint.name, &test_dir, "fail", "Content that triggers the lint goes here")?;
90+
create_project_layout(lint.name, &test_dir, "pass", "This file should not trigger the lint")
91+
} else {
92+
let test_path = format!("tests/ui/{}.rs", lint.name);
93+
let test_contents = get_test_file_contents(lint.name);
94+
write_file(lint.project_root.join(test_path), test_contents)
8395
}
96+
}
8497

85-
let test_file = OpenOptions::new().write(true).create_new(true).open(test_file_path)?;
86-
let lint_file = OpenOptions::new().write(true).create_new(true).open(lint_file_path)?;
98+
fn write_file<P: AsRef<Path>, C: AsRef<[u8]>>(path: P, contents: C) -> io::Result<()> {
99+
fn inner(path: &Path, contents: &[u8]) -> io::Result<()> {
100+
OpenOptions::new()
101+
.write(true)
102+
.create_new(true)
103+
.open(path)?
104+
.write_all(contents)
105+
}
87106

88-
Ok((test_file, lint_file))
107+
inner(path.as_ref(), contents.as_ref()).context(format!("writing to file: {}", path.as_ref().display()))
89108
}
90109

91110
fn to_camel_case(name: &str) -> String {
@@ -112,6 +131,20 @@ fn main() {{
112131
)
113132
}
114133

134+
fn get_manifest_contents(lint_name: &str, hint: &str) -> String {
135+
format!(
136+
r#"
137+
# {}
138+
139+
[package]
140+
name = "{}"
141+
version = "0.1.0"
142+
publish = false
143+
"#,
144+
hint, lint_name
145+
)
146+
}
147+
115148
fn get_lint_file_contents(
116149
pass_type: &str,
117150
pass_lifetimes: &str,

clippy_lints/src/cargo_common_metadata.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ declare_clippy_lint! {
2323
/// [package]
2424
/// name = "clippy"
2525
/// version = "0.0.212"
26+
/// authors = ["Someone <[email protected]>"]
2627
/// description = "A bunch of helpful lints to avoid common pitfalls in Rust"
2728
/// repository = "https://github.com/rust-lang/rust-clippy"
2829
/// readme = "README.md"

clippy_lints/src/float_literal.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for FloatLiteral {
7777
let type_suffix = match lit_float_ty {
7878
LitFloatType::Suffixed(FloatTy::F32) => Some("f32"),
7979
LitFloatType::Suffixed(FloatTy::F64) => Some("f64"),
80-
_ => None
80+
LitFloatType::Unsuffixed => None
8181
};
8282
let (is_whole, mut float_str) = match fty {
8383
FloatTy::F32 => {

clippy_lints/src/lib.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -638,6 +638,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
638638
&matches::MATCH_OVERLAPPING_ARM,
639639
&matches::MATCH_REF_PATS,
640640
&matches::MATCH_SINGLE_BINDING,
641+
&matches::MATCH_WILDCARD_FOR_SINGLE_VARIANTS,
641642
&matches::MATCH_WILD_ERR_ARM,
642643
&matches::REST_PAT_IN_FULLY_BOUND_STRUCTS,
643644
&matches::SINGLE_MATCH,
@@ -1139,6 +1140,8 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
11391140
LintId::of(&macro_use::MACRO_USE_IMPORTS),
11401141
LintId::of(&match_on_vec_items::MATCH_ON_VEC_ITEMS),
11411142
LintId::of(&matches::MATCH_BOOL),
1143+
LintId::of(&matches::MATCH_WILDCARD_FOR_SINGLE_VARIANTS),
1144+
LintId::of(&matches::MATCH_WILD_ERR_ARM),
11421145
LintId::of(&matches::SINGLE_MATCH_ELSE),
11431146
LintId::of(&methods::FILTER_MAP),
11441147
LintId::of(&methods::FILTER_MAP_NEXT),
@@ -1283,7 +1286,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
12831286
LintId::of(&matches::MATCH_OVERLAPPING_ARM),
12841287
LintId::of(&matches::MATCH_REF_PATS),
12851288
LintId::of(&matches::MATCH_SINGLE_BINDING),
1286-
LintId::of(&matches::MATCH_WILD_ERR_ARM),
12871289
LintId::of(&matches::SINGLE_MATCH),
12881290
LintId::of(&matches::WILDCARD_IN_OR_PATTERNS),
12891291
LintId::of(&mem_discriminant::MEM_DISCRIMINANT_NON_ENUM),
@@ -1474,7 +1476,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
14741476
LintId::of(&matches::INFALLIBLE_DESTRUCTURING_MATCH),
14751477
LintId::of(&matches::MATCH_OVERLAPPING_ARM),
14761478
LintId::of(&matches::MATCH_REF_PATS),
1477-
LintId::of(&matches::MATCH_WILD_ERR_ARM),
14781479
LintId::of(&matches::SINGLE_MATCH),
14791480
LintId::of(&mem_replace::MEM_REPLACE_OPTION_WITH_NONE),
14801481
LintId::of(&mem_replace::MEM_REPLACE_WITH_DEFAULT),

0 commit comments

Comments
 (0)