Skip to content

Commit 49aa6c5

Browse files
committed
Auto merge of #8844 - smoelius:fixed-paths, r=xFrednet
Check `.fixed` paths' existence in `run_ui` This PR adds a test to check that there exists a `.fixed` file for every `.stderr` file in `tests/ui` that mentions a `MachineApplicable` lint. The test leverages `compiletest-rs`'s `rustfix_coverage` option. I tried to add `.fixed` files where they appeared to be missing. However, 38 exceptional `.rs` files remain. Several of those include comments indicating that they are exceptions, though not all do. Apologies, as I have not tried to associate the 38 files with GH issues. (I think that would be a lot of work, and I worry about linking the wrong issue.) changelog: none
2 parents a5ece81 + 534fc5d commit 49aa6c5

Some content is hidden

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

55 files changed

+1807
-442
lines changed

tests/compile-test.rs

Lines changed: 84 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#![feature(test)] // compiletest_rs requires this attribute
22
#![feature(once_cell)]
3+
#![feature(is_sorted)]
34
#![cfg_attr(feature = "deny-warnings", deny(warnings))]
45
#![warn(rust_2018_idioms, unused_lifetimes)]
56

@@ -162,7 +163,8 @@ fn base_config(test_dir: &str) -> compiletest::Config {
162163
}
163164

164165
fn run_ui() {
165-
let config = base_config("ui");
166+
let mut config = base_config("ui");
167+
config.rustfix_coverage = true;
166168
// use tests/clippy.toml
167169
let _g = VarGuard::set("CARGO_MANIFEST_DIR", fs::canonicalize("tests").unwrap());
168170
let _threads = VarGuard::set(
@@ -175,6 +177,7 @@ fn run_ui() {
175177
}),
176178
);
177179
compiletest::run_tests(&config);
180+
check_rustfix_coverage();
178181
}
179182

180183
fn run_internal_tests() {
@@ -337,6 +340,86 @@ fn compile_test() {
337340
run_internal_tests();
338341
}
339342

343+
const RUSTFIX_COVERAGE_KNOWN_EXCEPTIONS: &[&str] = &[
344+
"assign_ops2.rs",
345+
"cast_size_32bit.rs",
346+
"char_lit_as_u8.rs",
347+
"cmp_owned/without_suggestion.rs",
348+
"crashes/ice-6250.rs",
349+
"crashes/ice-6251.rs",
350+
"dbg_macro.rs",
351+
"deref_addrof_double_trigger.rs",
352+
"doc/unbalanced_ticks.rs",
353+
"eprint_with_newline.rs",
354+
"explicit_counter_loop.rs",
355+
"iter_skip_next_unfixable.rs",
356+
"let_and_return.rs",
357+
"literals.rs",
358+
"map_flatten.rs",
359+
"map_unwrap_or.rs",
360+
"match_bool.rs",
361+
"mem_replace_macro.rs",
362+
"needless_arbitrary_self_type_unfixable.rs",
363+
"needless_borrow_pat.rs",
364+
"needless_for_each_unfixable.rs",
365+
"nonminimal_bool.rs",
366+
"print_literal.rs",
367+
"print_with_newline.rs",
368+
"redundant_static_lifetimes_multiple.rs",
369+
"ref_binding_to_reference.rs",
370+
"repl_uninit.rs",
371+
"result_map_unit_fn_unfixable.rs",
372+
"search_is_some.rs",
373+
"single_component_path_imports_nested_first.rs",
374+
"string_add.rs",
375+
"toplevel_ref_arg_non_rustfix.rs",
376+
"unit_arg.rs",
377+
"unnecessary_clone.rs",
378+
"unnecessary_lazy_eval_unfixable.rs",
379+
"write_literal.rs",
380+
"write_literal_2.rs",
381+
"write_with_newline.rs",
382+
];
383+
384+
fn check_rustfix_coverage() {
385+
let missing_coverage_path = Path::new("target/debug/test/ui/rustfix_missing_coverage.txt");
386+
387+
if let Ok(missing_coverage_contents) = std::fs::read_to_string(missing_coverage_path) {
388+
assert!(RUSTFIX_COVERAGE_KNOWN_EXCEPTIONS.iter().is_sorted_by_key(Path::new));
389+
390+
for rs_path in missing_coverage_contents.lines() {
391+
let filename = Path::new(rs_path).strip_prefix("tests/ui/").unwrap();
392+
assert!(
393+
RUSTFIX_COVERAGE_KNOWN_EXCEPTIONS
394+
.binary_search_by_key(&filename, Path::new)
395+
.is_ok(),
396+
"`{}` runs `MachineApplicable` diagnostics but is missing a `run-rustfix` annotation. \
397+
Please either add `// run-rustfix` at the top of the file or add the file to \
398+
`RUSTFIX_COVERAGE_KNOWN_EXCEPTIONS` in `tests/compile-test.rs`.",
399+
rs_path,
400+
);
401+
}
402+
}
403+
}
404+
405+
#[test]
406+
fn rustfix_coverage_known_exceptions_accuracy() {
407+
for filename in RUSTFIX_COVERAGE_KNOWN_EXCEPTIONS {
408+
let rs_path = Path::new("tests/ui").join(filename);
409+
assert!(
410+
rs_path.exists(),
411+
"`{}` does not exists",
412+
rs_path.strip_prefix(env!("CARGO_MANIFEST_DIR")).unwrap().display()
413+
);
414+
let fixed_path = rs_path.with_extension("fixed");
415+
assert!(
416+
!fixed_path.exists(),
417+
"`{}` exists",
418+
fixed_path.strip_prefix(env!("CARGO_MANIFEST_DIR")).unwrap().display()
419+
);
420+
}
421+
}
422+
340423
/// Restores an env var on drop
341424
#[must_use]
342425
struct VarGuard {
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
// run-rustfix
2+
#![deny(clippy::bind_instead_of_map)]
3+
#![allow(clippy::blocks_in_if_conditions)]
4+
5+
pub fn main() {
6+
let _ = Some("42").map(|s| if s.len() < 42 { 0 } else { s.len() });
7+
let _ = Some("42").and_then(|s| if s.len() < 42 { None } else { Some(s.len()) });
8+
9+
let _ = Ok::<_, ()>("42").map(|s| if s.len() < 42 { 0 } else { s.len() });
10+
let _ = Ok::<_, ()>("42").and_then(|s| if s.len() < 42 { Err(()) } else { Ok(s.len()) });
11+
12+
let _ = Err::<(), _>("42").map_err(|s| if s.len() < 42 { s.len() + 20 } else { s.len() });
13+
let _ = Err::<(), _>("42").or_else(|s| if s.len() < 42 { Ok(()) } else { Err(s.len()) });
14+
15+
hard_example();
16+
macro_example();
17+
}
18+
19+
fn hard_example() {
20+
Some("42").map(|s| {
21+
if {
22+
if s == "43" {
23+
return 43;
24+
}
25+
s == "42"
26+
} {
27+
return 45;
28+
}
29+
match s.len() {
30+
10 => 2,
31+
20 => {
32+
if foo() {
33+
return {
34+
if foo() {
35+
return 20;
36+
}
37+
println!("foo");
38+
3
39+
};
40+
}
41+
20
42+
},
43+
40 => 30,
44+
_ => 1,
45+
}
46+
});
47+
}
48+
49+
fn foo() -> bool {
50+
true
51+
}
52+
53+
macro_rules! m {
54+
() => {
55+
Some(10)
56+
};
57+
}
58+
59+
fn macro_example() {
60+
let _ = Some("").and_then(|s| if s.len() == 20 { m!() } else { Some(20) });
61+
let _ = Some("").map(|s| if s.len() == 20 { m!() } else { Some(20) });
62+
}

tests/ui/bind_instead_of_map_multipart.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// run-rustfix
12
#![deny(clippy::bind_instead_of_map)]
23
#![allow(clippy::blocks_in_if_conditions)]
34

tests/ui/bind_instead_of_map_multipart.stderr

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
error: using `Option.and_then(|x| Some(y))`, which is more succinctly expressed as `map(|x| y)`
2-
--> $DIR/bind_instead_of_map_multipart.rs:5:13
2+
--> $DIR/bind_instead_of_map_multipart.rs:6:13
33
|
44
LL | let _ = Some("42").and_then(|s| if s.len() < 42 { Some(0) } else { Some(s.len()) });
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
66
|
77
note: the lint level is defined here
8-
--> $DIR/bind_instead_of_map_multipart.rs:1:9
8+
--> $DIR/bind_instead_of_map_multipart.rs:2:9
99
|
1010
LL | #![deny(clippy::bind_instead_of_map)]
1111
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -15,7 +15,7 @@ LL | let _ = Some("42").map(|s| if s.len() < 42 { 0 } else { s.len() });
1515
| ~~~ ~ ~~~~~~~
1616

1717
error: using `Result.and_then(|x| Ok(y))`, which is more succinctly expressed as `map(|x| y)`
18-
--> $DIR/bind_instead_of_map_multipart.rs:8:13
18+
--> $DIR/bind_instead_of_map_multipart.rs:9:13
1919
|
2020
LL | let _ = Ok::<_, ()>("42").and_then(|s| if s.len() < 42 { Ok(0) } else { Ok(s.len()) });
2121
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -26,7 +26,7 @@ LL | let _ = Ok::<_, ()>("42").map(|s| if s.len() < 42 { 0 } else { s.len()
2626
| ~~~ ~ ~~~~~~~
2727

2828
error: using `Result.or_else(|x| Err(y))`, which is more succinctly expressed as `map_err(|x| y)`
29-
--> $DIR/bind_instead_of_map_multipart.rs:11:13
29+
--> $DIR/bind_instead_of_map_multipart.rs:12:13
3030
|
3131
LL | let _ = Err::<(), _>("42").or_else(|s| if s.len() < 42 { Err(s.len() + 20) } else { Err(s.len()) });
3232
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -37,7 +37,7 @@ LL | let _ = Err::<(), _>("42").map_err(|s| if s.len() < 42 { s.len() + 20 }
3737
| ~~~~~~~ ~~~~~~~~~~~~ ~~~~~~~
3838

3939
error: using `Option.and_then(|x| Some(y))`, which is more succinctly expressed as `map(|x| y)`
40-
--> $DIR/bind_instead_of_map_multipart.rs:19:5
40+
--> $DIR/bind_instead_of_map_multipart.rs:20:5
4141
|
4242
LL | / Some("42").and_then(|s| {
4343
LL | | if {
@@ -59,7 +59,7 @@ LL | s == "42"
5959
...
6060

6161
error: using `Option.and_then(|x| Some(y))`, which is more succinctly expressed as `map(|x| y)`
62-
--> $DIR/bind_instead_of_map_multipart.rs:60:13
62+
--> $DIR/bind_instead_of_map_multipart.rs:61:13
6363
|
6464
LL | let _ = Some("").and_then(|s| if s.len() == 20 { Some(m!()) } else { Some(Some(20)) });
6565
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

tests/ui/crashes/ice-7169.fixed

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// run-rustfix
2+
#![allow(dead_code)]
3+
4+
#[derive(Default)]
5+
struct A<T> {
6+
a: Vec<A<T>>,
7+
b: T,
8+
}
9+
10+
fn main() {
11+
if Ok::<_, ()>(A::<String>::default()).is_ok() {}
12+
}

tests/ui/crashes/ice-7169.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
// run-rustfix
2+
#![allow(dead_code)]
3+
14
#[derive(Default)]
25
struct A<T> {
36
a: Vec<A<T>>,

tests/ui/crashes/ice-7169.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: redundant pattern matching, consider using `is_ok()`
2-
--> $DIR/ice-7169.rs:8:12
2+
--> $DIR/ice-7169.rs:11:12
33
|
44
LL | if let Ok(_) = Ok::<_, ()>(A::<String>::default()) {}
55
| -------^^^^^-------------------------------------- help: try this: `if Ok::<_, ()>(A::<String>::default()).is_ok()`

tests/ui/crashes/ice-8250.fixed

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// run-rustfix
2+
fn _f(s: &str) -> Option<()> {
3+
let _ = s[1..].split('.').next()?;
4+
Some(())
5+
}
6+
7+
fn main() {}

tests/ui/crashes/ice-8250.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// run-rustfix
12
fn _f(s: &str) -> Option<()> {
23
let _ = s[1..].splitn(2, '.').next()?;
34
Some(())

tests/ui/crashes/ice-8250.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: unnecessary use of `splitn`
2-
--> $DIR/ice-8250.rs:2:13
2+
--> $DIR/ice-8250.rs:3:13
33
|
44
LL | let _ = s[1..].splitn(2, '.').next()?;
55
| ^^^^^^^^^^^^^^^^^^^^^ help: try this: `s[1..].split('.')`

tests/ui/crashes/ice-8821.fixed

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// run-rustfix
2+
#![warn(clippy::let_unit_value)]
3+
4+
fn f() {}
5+
static FN: fn() = f;
6+
7+
fn main() {
8+
FN();
9+
}

tests/ui/crashes/ice-8821.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// run-rustfix
12
#![warn(clippy::let_unit_value)]
23

34
fn f() {}

tests/ui/crashes/ice-8821.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: this let-binding has unit value
2-
--> $DIR/ice-8821.rs:7:5
2+
--> $DIR/ice-8821.rs:8:5
33
|
44
LL | let _: () = FN();
55
| ^^^^^^^^^^^^^^^^^ help: omit the `let` binding: `FN();`

0 commit comments

Comments
 (0)