Skip to content

Commit a40940d

Browse files
committed
Auto merge of #11239 - oli-obk:ui_test, r=Alexendoo,flip1995
Update ui test crate This update also removes the `//`@run-rustfix`` flag, and just runs rustfix on all tests. This means I had to opt out of running rustfix on ~100 tests, but it also allowed me to remove the rustfix coverage check entirely, as it is now effectively builtin. changelog: update ui-test crate to 0.13 (automatically runs rustfix on all tests)
2 parents 1e8fdf4 + 3d3856f commit a40940d

File tree

1,264 files changed

+7082
-6140
lines changed

Some content is hidden

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

1,264 files changed

+7082
-6140
lines changed

.cargo/config.toml

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[alias]
2-
uitest = "test --test compile-test"
3-
uibless = "test --test compile-test -- -- --bless"
4-
bless = "test -- -- --bless"
2+
uitest = "test --test compile-test -- --check"
3+
uibless = "test --test compile-test"
4+
bless = "test"
55
dev = "run --package clippy_dev --bin clippy_dev --manifest-path clippy_dev/Cargo.toml --"
66
lintcheck = "run --package lintcheck --bin lintcheck --manifest-path lintcheck/Cargo.toml -- "
77
collect-metadata = "test --test dogfood --features internal -- run_metadata_collection_lint --ignored"

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ tempfile = { version = "3.2", optional = true }
2727
termize = "0.1"
2828

2929
[dev-dependencies]
30-
ui_test = "0.11.5"
30+
ui_test = "0.16.1"
3131
tester = "0.9"
3232
regex = "1.5"
3333
toml = "0.7.3"

book/src/development/adding_lints.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -161,8 +161,8 @@ The process of generating the `.stderr` file is the same, and prepending the
161161
## Rustfix tests
162162

163163
If the lint you are working on is making use of structured suggestions, the test
164-
file should include a `//@run-rustfix` comment at the top. This will
165-
additionally run [rustfix] for that test. Rustfix will apply the suggestions
164+
will create a `.fixed` file by running [rustfix] for that test.
165+
Rustfix will apply the suggestions
166166
from the lint to the code of the test file and compare that to the contents of a
167167
`.fixed` file.
168168

clippy_dev/src/update_lints.rs

-1
Original file line numberDiff line numberDiff line change
@@ -690,7 +690,6 @@ fn gen_deprecated_lints_test(lints: &[DeprecatedLint]) -> String {
690690
fn gen_renamed_lints_test(lints: &[RenamedLint]) -> String {
691691
let mut seen_lints = HashSet::new();
692692
let mut res: String = GENERATED_FILE_COMMENT.into();
693-
res.push_str("//@run-rustfix\n\n");
694693
for lint in lints {
695694
if seen_lints.insert(&lint.new_name) {
696695
writeln!(res, "#![allow({})]", lint.new_name).unwrap();

tests/compile-test.rs

+72-123
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
#![warn(rust_2018_idioms, unused_lifetimes)]
66
#![allow(unused_extern_crates)]
77

8-
use compiletest::{status_emitter, CommandBuilder, OutputConflictHandling};
8+
use compiletest::{status_emitter, Args, CommandBuilder, OutputConflictHandling};
99
use ui_test as compiletest;
1010
use ui_test::Mode as TestMode;
1111

@@ -110,28 +110,33 @@ mod test_utils;
110110
// whether to run internal tests or not
111111
const RUN_INTERNAL_TESTS: bool = cfg!(feature = "internal");
112112

113-
fn base_config(test_dir: &str) -> compiletest::Config {
113+
fn canonicalize(path: impl AsRef<Path>) -> PathBuf {
114+
let path = path.as_ref();
115+
fs::create_dir_all(path).unwrap();
116+
fs::canonicalize(path).unwrap_or_else(|err| panic!("{} cannot be canonicalized: {err}", path.display()))
117+
}
118+
119+
fn base_config(test_dir: &str) -> (compiletest::Config, Args) {
120+
let args = Args::test().unwrap();
114121
let mut config = compiletest::Config {
115-
mode: TestMode::Yolo,
122+
mode: TestMode::Yolo { rustfix: true },
116123
stderr_filters: vec![],
117124
stdout_filters: vec![],
118-
output_conflict_handling: if var_os("RUSTC_BLESS").is_some_and(|v| v != "0")
119-
|| env::args().any(|arg| arg == "--bless")
125+
output_conflict_handling: if var_os("GITHUB_ACTION").is_none()
126+
&& (var_os("RUSTC_BLESS").is_some_and(|v| v != "0") || !args.check)
120127
{
121128
OutputConflictHandling::Bless
122129
} else {
123130
OutputConflictHandling::Error("cargo uibless".into())
124131
},
125132
target: None,
126-
out_dir: PathBuf::from(std::env::var_os("CARGO_TARGET_DIR").unwrap_or("target".into())).join("ui_test"),
133+
out_dir: canonicalize(
134+
std::env::var_os("CARGO_TARGET_DIR")
135+
.map_or_else(|| std::env::current_dir().unwrap().join("target"), PathBuf::from),
136+
)
137+
.join("ui_test"),
127138
..compiletest::Config::rustc(Path::new("tests").join(test_dir))
128139
};
129-
130-
if let Some(_path) = option_env!("RUSTC_LIB_PATH") {
131-
//let path = PathBuf::from(path);
132-
//config.run_lib_path = path.clone();
133-
//config.compile_lib_path = path;
134-
}
135140
let current_exe_path = env::current_exe().unwrap();
136141
let deps_path = current_exe_path.parent().unwrap();
137142
let profile_path = deps_path.parent().unwrap();
@@ -164,7 +169,7 @@ fn base_config(test_dir: &str) -> compiletest::Config {
164169
} else {
165170
"clippy-driver"
166171
});
167-
config
172+
(config, args)
168173
}
169174

170175
fn test_filter() -> Box<dyn Sync + Fn(&Path) -> bool> {
@@ -177,10 +182,10 @@ fn test_filter() -> Box<dyn Sync + Fn(&Path) -> bool> {
177182
}
178183

179184
fn run_ui() {
180-
let config = base_config("ui");
185+
let (config, args) = base_config("ui");
181186
//config.rustfix_coverage = true;
182187
// use tests/clippy.toml
183-
let _g = VarGuard::set("CARGO_MANIFEST_DIR", fs::canonicalize("tests").unwrap());
188+
let _g = VarGuard::set("CARGO_MANIFEST_DIR", canonicalize("tests"));
184189
let _threads = VarGuard::set(
185190
"RUST_TEST_THREADS",
186191
// if RUST_TEST_THREADS is set, adhere to it, otherwise override it
@@ -193,43 +198,54 @@ fn run_ui() {
193198

194199
let test_filter = test_filter();
195200

201+
let quiet = args.quiet;
202+
196203
compiletest::run_tests_generic(
197-
config,
198-
move |path| compiletest::default_file_filter(path) && test_filter(path),
204+
vec![config],
205+
args,
206+
move |path, args, config| compiletest::default_file_filter(path, args, config) && test_filter(path),
199207
compiletest::default_per_file_config,
200-
status_emitter::Text,
208+
if quiet {
209+
status_emitter::Text::quiet()
210+
} else {
211+
status_emitter::Text::verbose()
212+
},
201213
)
202214
.unwrap();
203-
check_rustfix_coverage();
204215
}
205216

206217
fn run_internal_tests() {
207218
// only run internal tests with the internal-tests feature
208219
if !RUN_INTERNAL_TESTS {
209220
return;
210221
}
211-
let mut config = base_config("ui-internal");
222+
let (mut config, args) = base_config("ui-internal");
212223
if let OutputConflictHandling::Error(err) = &mut config.output_conflict_handling {
213-
*err = "cargo uitest --features internal -- -- --bless".into();
224+
*err = "cargo uitest --features internal".into();
214225
}
215226
let test_filter = test_filter();
227+
let quiet = args.quiet;
216228

217229
compiletest::run_tests_generic(
218-
config,
219-
move |path| compiletest::default_file_filter(path) && test_filter(path),
230+
vec![config],
231+
args,
232+
move |path, args, config| compiletest::default_file_filter(path, args, config) && test_filter(path),
220233
compiletest::default_per_file_config,
221-
status_emitter::Text,
234+
if quiet {
235+
status_emitter::Text::quiet()
236+
} else {
237+
status_emitter::Text::verbose()
238+
},
222239
)
223240
.unwrap();
224241
}
225242

226243
fn run_ui_toml() {
227-
let mut config = base_config("ui-toml");
244+
let (mut config, args) = base_config("ui-toml");
228245

229246
config.stderr_filter(
230247
&regex::escape(
231-
&fs::canonicalize("tests")
232-
.unwrap()
248+
&canonicalize("tests")
233249
.parent()
234250
.unwrap()
235251
.display()
@@ -240,19 +256,23 @@ fn run_ui_toml() {
240256
);
241257

242258
let test_filter = test_filter();
259+
let quiet = args.quiet;
243260

244261
ui_test::run_tests_generic(
245-
config,
246-
|path| compiletest::default_file_filter(path) && test_filter(path),
247-
|config, path| {
248-
let mut config = config.clone();
262+
vec![config],
263+
args,
264+
|path, args, config| compiletest::default_file_filter(path, args, config) && test_filter(path),
265+
|config, path, _file_contents| {
249266
config
250267
.program
251268
.envs
252269
.push(("CLIPPY_CONF_DIR".into(), Some(path.parent().unwrap().into())));
253-
Some(config)
254270
},
255-
status_emitter::Text,
271+
if quiet {
272+
status_emitter::Text::quiet()
273+
} else {
274+
status_emitter::Text::verbose()
275+
},
256276
)
257277
.unwrap();
258278
}
@@ -262,7 +282,7 @@ fn run_ui_cargo() {
262282
return;
263283
}
264284

265-
let mut config = base_config("ui-cargo");
285+
let (mut config, args) = base_config("ui-cargo");
266286
config.program.input_file_flag = CommandBuilder::cargo().input_file_flag;
267287
config.program.out_dir_flag = CommandBuilder::cargo().out_dir_flag;
268288
config.program.args = vec!["clippy".into(), "--color".into(), "never".into(), "--quiet".into()];
@@ -282,8 +302,7 @@ fn run_ui_cargo() {
282302

283303
config.stderr_filter(
284304
&regex::escape(
285-
&fs::canonicalize("tests")
286-
.unwrap()
305+
&canonicalize("tests")
287306
.parent()
288307
.unwrap()
289308
.display()
@@ -294,16 +313,26 @@ fn run_ui_cargo() {
294313
);
295314

296315
let test_filter = test_filter();
316+
let quiet = args.quiet;
297317

298318
ui_test::run_tests_generic(
299-
config,
300-
|path| test_filter(path) && path.ends_with("Cargo.toml"),
301-
|config, path| {
302-
let mut config = config.clone();
303-
config.out_dir = PathBuf::from("target/ui_test_cargo/").join(path.parent().unwrap());
304-
Some(config)
319+
vec![config],
320+
args,
321+
|path, _args, _config| test_filter(path) && path.ends_with("Cargo.toml"),
322+
|config, path, _file_contents| {
323+
config.out_dir = canonicalize(
324+
std::env::current_dir()
325+
.unwrap()
326+
.join("target")
327+
.join("ui_test_cargo/")
328+
.join(path.parent().unwrap()),
329+
);
330+
},
331+
if quiet {
332+
status_emitter::Text::quiet()
333+
} else {
334+
status_emitter::Text::verbose()
305335
},
306-
status_emitter::Text,
307336
)
308337
.unwrap();
309338
}
@@ -328,7 +357,6 @@ fn main() {
328357
"cargo" => run_ui_cargo as fn(),
329358
"toml" => run_ui_toml as fn(),
330359
"internal" => run_internal_tests as fn(),
331-
"rustfix-coverage-known-exceptions-accuracy" => rustfix_coverage_known_exceptions_accuracy as fn(),
332360
"ui-cargo-toml-metadata" => ui_cargo_toml_metadata as fn(),
333361

334362
_ => panic!("unknown speedtest: {speedtest} || accepted speedtests are: [ui, cargo, toml, internal]"),
@@ -355,89 +383,10 @@ fn main() {
355383
run_ui_toml();
356384
run_ui_cargo();
357385
run_internal_tests();
358-
rustfix_coverage_known_exceptions_accuracy();
359386
ui_cargo_toml_metadata();
360387
}
361388
}
362389

363-
const RUSTFIX_COVERAGE_KNOWN_EXCEPTIONS: &[&str] = &[
364-
"assign_ops2.rs",
365-
"borrow_deref_ref_unfixable.rs",
366-
"cast_size_32bit.rs",
367-
"char_lit_as_u8.rs",
368-
"cmp_owned/without_suggestion.rs",
369-
"dbg_macro.rs",
370-
"deref_addrof_double_trigger.rs",
371-
"doc/unbalanced_ticks.rs",
372-
"eprint_with_newline.rs",
373-
"explicit_counter_loop.rs",
374-
"iter_skip_next_unfixable.rs",
375-
"let_and_return.rs",
376-
"literals.rs",
377-
"map_flatten.rs",
378-
"map_unwrap_or.rs",
379-
"match_bool.rs",
380-
"mem_replace_macro.rs",
381-
"needless_arbitrary_self_type_unfixable.rs",
382-
"needless_borrow_pat.rs",
383-
"needless_for_each_unfixable.rs",
384-
"nonminimal_bool.rs",
385-
"print_literal.rs",
386-
"redundant_static_lifetimes_multiple.rs",
387-
"ref_binding_to_reference.rs",
388-
"repl_uninit.rs",
389-
"result_map_unit_fn_unfixable.rs",
390-
"search_is_some.rs",
391-
"single_component_path_imports_nested_first.rs",
392-
"string_add.rs",
393-
"suspicious_to_owned.rs",
394-
"toplevel_ref_arg_non_rustfix.rs",
395-
"unit_arg.rs",
396-
"unnecessary_clone.rs",
397-
"unnecessary_lazy_eval_unfixable.rs",
398-
"write_literal.rs",
399-
"write_literal_2.rs",
400-
];
401-
402-
fn check_rustfix_coverage() {
403-
let missing_coverage_path = Path::new("debug/test/ui/rustfix_missing_coverage.txt");
404-
let missing_coverage_path = if let Ok(target_dir) = std::env::var("CARGO_TARGET_DIR") {
405-
PathBuf::from(target_dir).join(missing_coverage_path)
406-
} else {
407-
missing_coverage_path.to_path_buf()
408-
};
409-
410-
if let Ok(missing_coverage_contents) = std::fs::read_to_string(missing_coverage_path) {
411-
assert!(RUSTFIX_COVERAGE_KNOWN_EXCEPTIONS.iter().is_sorted_by_key(Path::new));
412-
413-
for rs_file in missing_coverage_contents.lines() {
414-
let rs_path = Path::new(rs_file);
415-
if rs_path.starts_with("tests/ui/crashes") {
416-
continue;
417-
}
418-
assert!(rs_path.starts_with("tests/ui/"), "{rs_file:?}");
419-
let filename = rs_path.strip_prefix("tests/ui/").unwrap();
420-
assert!(
421-
RUSTFIX_COVERAGE_KNOWN_EXCEPTIONS
422-
.binary_search_by_key(&filename, Path::new)
423-
.is_ok(),
424-
"`{rs_file}` runs `MachineApplicable` diagnostics but is missing a `run-rustfix` annotation. \
425-
Please either add `//@run-rustfix` at the top of the file or add the file to \
426-
`RUSTFIX_COVERAGE_KNOWN_EXCEPTIONS` in `tests/compile-test.rs`.",
427-
);
428-
}
429-
}
430-
}
431-
432-
fn rustfix_coverage_known_exceptions_accuracy() {
433-
for filename in RUSTFIX_COVERAGE_KNOWN_EXCEPTIONS {
434-
let rs_path = Path::new("tests/ui").join(filename);
435-
assert!(rs_path.exists(), "`{}` does not exist", rs_path.display());
436-
let fixed_path = rs_path.with_extension("fixed");
437-
assert!(!fixed_path.exists(), "`{}` exists", fixed_path.display());
438-
}
439-
}
440-
441390
fn ui_cargo_toml_metadata() {
442391
let ui_cargo_path = Path::new("tests/ui-cargo");
443392
let cargo_common_metadata_path = ui_cargo_path.join("cargo_common_metadata");

tests/headers.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ fn old_test_headers() {
1616
continue;
1717
}
1818

19-
let file = fs::read_to_string(entry.path()).unwrap();
19+
let file = fs::read_to_string(entry.path()).unwrap_or_else(|err| panic!("{}: {err}", entry.path().display()));
2020

2121
if let Some(header) = old_headers.find(&file) {
2222
println!("Found header `{}` in {}", header.as_str(), entry.path().display());

tests/ui-internal/collapsible_span_lint_calls.fixed

-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
//@run-rustfix
21
#![deny(clippy::internal)]
32
#![allow(clippy::missing_clippy_version_attribute)]
43
#![feature(rustc_private)]

tests/ui-internal/collapsible_span_lint_calls.rs

-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
//@run-rustfix
21
#![deny(clippy::internal)]
32
#![allow(clippy::missing_clippy_version_attribute)]
43
#![feature(rustc_private)]

0 commit comments

Comments
 (0)