1fad3a1d3Sopenharmony_ci#![allow(clippy::manual_assert)]
2fad3a1d3Sopenharmony_ci
3fad3a1d3Sopenharmony_cimod progress;
4fad3a1d3Sopenharmony_ci
5fad3a1d3Sopenharmony_ciuse self::progress::Progress;
6fad3a1d3Sopenharmony_ciuse anyhow::Result;
7fad3a1d3Sopenharmony_ciuse flate2::read::GzDecoder;
8fad3a1d3Sopenharmony_ciuse rayon::iter::{IntoParallelRefIterator, ParallelIterator};
9fad3a1d3Sopenharmony_ciuse std::collections::BTreeSet;
10fad3a1d3Sopenharmony_ciuse std::ffi::OsStr;
11fad3a1d3Sopenharmony_ciuse std::fs;
12fad3a1d3Sopenharmony_ciuse std::path::{Path, PathBuf};
13fad3a1d3Sopenharmony_ciuse tar::Archive;
14fad3a1d3Sopenharmony_ciuse walkdir::{DirEntry, WalkDir};
15fad3a1d3Sopenharmony_ci
16fad3a1d3Sopenharmony_ciconst REVISION: &str = "b10cfcd65fd7f7b1ab9beb34798b2108de003452";
17fad3a1d3Sopenharmony_ci
18fad3a1d3Sopenharmony_ci#[rustfmt::skip]
19fad3a1d3Sopenharmony_cistatic EXCLUDE_FILES: &[&str] = &[
20fad3a1d3Sopenharmony_ci    // TODO: CStr literals: c"…", cr"…"
21fad3a1d3Sopenharmony_ci    // https://github.com/dtolnay/syn/issues/1502
22fad3a1d3Sopenharmony_ci    "src/tools/clippy/tests/ui/needless_raw_string.rs",
23fad3a1d3Sopenharmony_ci    "src/tools/clippy/tests/ui/needless_raw_string_hashes.rs",
24fad3a1d3Sopenharmony_ci    "src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0085_expr_literals.rs",
25fad3a1d3Sopenharmony_ci
26fad3a1d3Sopenharmony_ci    // TODO: explicit tail calls: `become _g()`
27fad3a1d3Sopenharmony_ci    // https://github.com/dtolnay/syn/issues/1501
28fad3a1d3Sopenharmony_ci    "tests/ui/explicit-tail-calls/return-lifetime-sub.rs",
29fad3a1d3Sopenharmony_ci
30fad3a1d3Sopenharmony_ci    // TODO: non-lifetime binders: `where for<'a, T> &'a Struct<T>: Trait`
31fad3a1d3Sopenharmony_ci    // https://github.com/dtolnay/syn/issues/1435
32fad3a1d3Sopenharmony_ci    "src/tools/rustfmt/tests/source/issue_5721.rs",
33fad3a1d3Sopenharmony_ci    "src/tools/rustfmt/tests/source/non-lifetime-binders.rs",
34fad3a1d3Sopenharmony_ci    "src/tools/rustfmt/tests/target/issue_5721.rs",
35fad3a1d3Sopenharmony_ci    "src/tools/rustfmt/tests/target/non-lifetime-binders.rs",
36fad3a1d3Sopenharmony_ci    "tests/rustdoc-json/non_lifetime_binders.rs",
37fad3a1d3Sopenharmony_ci    "tests/rustdoc/inline_cross/auxiliary/non_lifetime_binders.rs",
38fad3a1d3Sopenharmony_ci    "tests/rustdoc/non_lifetime_binders.rs",
39fad3a1d3Sopenharmony_ci
40fad3a1d3Sopenharmony_ci    // TODO: return type notation: `where T: Trait<method(): Send>`
41fad3a1d3Sopenharmony_ci    // https://github.com/dtolnay/syn/issues/1434
42fad3a1d3Sopenharmony_ci    "src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0208_associated_return_type_bounds.rs",
43fad3a1d3Sopenharmony_ci    "tests/ui/associated-type-bounds/return-type-notation/basic.rs",
44fad3a1d3Sopenharmony_ci    "tests/ui/feature-gates/feature-gate-return_type_notation.rs",
45fad3a1d3Sopenharmony_ci
46fad3a1d3Sopenharmony_ci    // TODO: lazy type alias syntax with where-clause in trailing position
47fad3a1d3Sopenharmony_ci    // https://github.com/dtolnay/syn/issues/1525
48fad3a1d3Sopenharmony_ci    "tests/rustdoc/typedef-inner-variants-lazy_type_alias.rs",
49fad3a1d3Sopenharmony_ci
50fad3a1d3Sopenharmony_ci    // TODO: gen blocks and functions
51fad3a1d3Sopenharmony_ci    // https://github.com/dtolnay/syn/issues/1526
52fad3a1d3Sopenharmony_ci    "compiler/rustc_codegen_cranelift/example/gen_block_iterate.rs",
53fad3a1d3Sopenharmony_ci    "tests/ui/coroutine/gen_block_is_iter.rs",
54fad3a1d3Sopenharmony_ci    "tests/ui/coroutine/gen_block_iterate.rs",
55fad3a1d3Sopenharmony_ci
56fad3a1d3Sopenharmony_ci    // TODO: struct literal in match guard
57fad3a1d3Sopenharmony_ci    // https://github.com/dtolnay/syn/issues/1527
58fad3a1d3Sopenharmony_ci    "tests/ui/parser/struct-literal-in-match-guard.rs",
59fad3a1d3Sopenharmony_ci
60fad3a1d3Sopenharmony_ci    // Compile-fail expr parameter in const generic position: f::<1 + 2>()
61fad3a1d3Sopenharmony_ci    "tests/ui/const-generics/early/closing-args-token.rs",
62fad3a1d3Sopenharmony_ci    "tests/ui/const-generics/early/const-expression-parameter.rs",
63fad3a1d3Sopenharmony_ci
64fad3a1d3Sopenharmony_ci    // Compile-fail variadics in not the last position of a function parameter list
65fad3a1d3Sopenharmony_ci    "tests/ui/parser/variadic-ffi-syntactic-pass.rs",
66fad3a1d3Sopenharmony_ci
67fad3a1d3Sopenharmony_ci    // Need at least one trait in impl Trait, no such type as impl 'static
68fad3a1d3Sopenharmony_ci    "tests/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs",
69fad3a1d3Sopenharmony_ci
70fad3a1d3Sopenharmony_ci    // Negative polarity trait bound: `where T: !Copy`
71fad3a1d3Sopenharmony_ci    "src/tools/rustfmt/tests/target/negative-bounds.rs",
72fad3a1d3Sopenharmony_ci
73fad3a1d3Sopenharmony_ci    // Lifetime bound inside for<>: `T: ~const ?for<'a: 'b> Trait<'a>`
74fad3a1d3Sopenharmony_ci    "tests/ui/rfcs/rfc-2632-const-trait-impl/tilde-const-syntax.rs",
75fad3a1d3Sopenharmony_ci
76fad3a1d3Sopenharmony_ci    // Const impl that is not a trait impl: `impl ~const T {}`
77fad3a1d3Sopenharmony_ci    "tests/ui/rfcs/rfc-2632-const-trait-impl/syntax.rs",
78fad3a1d3Sopenharmony_ci
79fad3a1d3Sopenharmony_ci    // Deprecated anonymous parameter syntax in traits
80fad3a1d3Sopenharmony_ci    "src/tools/rustfmt/tests/source/trait.rs",
81fad3a1d3Sopenharmony_ci    "src/tools/rustfmt/tests/target/trait.rs",
82fad3a1d3Sopenharmony_ci    "tests/ui/issues/issue-13105.rs",
83fad3a1d3Sopenharmony_ci    "tests/ui/issues/issue-13775.rs",
84fad3a1d3Sopenharmony_ci    "tests/ui/issues/issue-34074.rs",
85fad3a1d3Sopenharmony_ci    "tests/ui/proc-macro/trait-fn-args-2015.rs",
86fad3a1d3Sopenharmony_ci
87fad3a1d3Sopenharmony_ci    // Deprecated where-clause location
88fad3a1d3Sopenharmony_ci    "src/tools/rustfmt/tests/source/issue_4257.rs",
89fad3a1d3Sopenharmony_ci    "src/tools/rustfmt/tests/source/issue_4911.rs",
90fad3a1d3Sopenharmony_ci    "src/tools/rustfmt/tests/target/issue_4257.rs",
91fad3a1d3Sopenharmony_ci    "src/tools/rustfmt/tests/target/issue_4911.rs",
92fad3a1d3Sopenharmony_ci    "tests/pretty/gat-bounds.rs",
93fad3a1d3Sopenharmony_ci    "tests/rustdoc/generic-associated-types/gats.rs",
94fad3a1d3Sopenharmony_ci
95fad3a1d3Sopenharmony_ci    // Deprecated trait object syntax with parenthesized generic arguments and no dyn keyword
96fad3a1d3Sopenharmony_ci    "src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0004_value_parameters_no_patterns.rs",
97fad3a1d3Sopenharmony_ci    "src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0104_path_fn_trait_args.rs",
98fad3a1d3Sopenharmony_ci    "src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0202_typepathfn_with_coloncolon.rs",
99fad3a1d3Sopenharmony_ci    "src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0209_bare_dyn_types_with_paren_as_generic_args.rs",
100fad3a1d3Sopenharmony_ci    "src/tools/rustfmt/tests/source/attrib.rs",
101fad3a1d3Sopenharmony_ci    "src/tools/rustfmt/tests/source/closure.rs",
102fad3a1d3Sopenharmony_ci    "src/tools/rustfmt/tests/source/existential_type.rs",
103fad3a1d3Sopenharmony_ci    "src/tools/rustfmt/tests/source/fn-simple.rs",
104fad3a1d3Sopenharmony_ci    "src/tools/rustfmt/tests/source/fn_args_layout-vertical.rs",
105fad3a1d3Sopenharmony_ci    "src/tools/rustfmt/tests/source/issue-4689/one.rs",
106fad3a1d3Sopenharmony_ci    "src/tools/rustfmt/tests/source/issue-4689/two.rs",
107fad3a1d3Sopenharmony_ci    "src/tools/rustfmt/tests/source/paths.rs",
108fad3a1d3Sopenharmony_ci    "src/tools/rustfmt/tests/source/structs.rs",
109fad3a1d3Sopenharmony_ci    "src/tools/rustfmt/tests/target/attrib.rs",
110fad3a1d3Sopenharmony_ci    "src/tools/rustfmt/tests/target/closure.rs",
111fad3a1d3Sopenharmony_ci    "src/tools/rustfmt/tests/target/existential_type.rs",
112fad3a1d3Sopenharmony_ci    "src/tools/rustfmt/tests/target/fn-simple.rs",
113fad3a1d3Sopenharmony_ci    "src/tools/rustfmt/tests/target/fn.rs",
114fad3a1d3Sopenharmony_ci    "src/tools/rustfmt/tests/target/fn_args_layout-vertical.rs",
115fad3a1d3Sopenharmony_ci    "src/tools/rustfmt/tests/target/issue-4689/one.rs",
116fad3a1d3Sopenharmony_ci    "src/tools/rustfmt/tests/target/issue-4689/two.rs",
117fad3a1d3Sopenharmony_ci    "src/tools/rustfmt/tests/target/paths.rs",
118fad3a1d3Sopenharmony_ci    "src/tools/rustfmt/tests/target/structs.rs",
119fad3a1d3Sopenharmony_ci    "tests/codegen-units/item-collection/non-generic-closures.rs",
120fad3a1d3Sopenharmony_ci    "tests/debuginfo/recursive-enum.rs",
121fad3a1d3Sopenharmony_ci    "tests/pretty/closure-reform-pretty.rs",
122fad3a1d3Sopenharmony_ci    "tests/run-make/reproducible-build-2/reproducible-build.rs",
123fad3a1d3Sopenharmony_ci    "tests/run-make/reproducible-build/reproducible-build.rs",
124fad3a1d3Sopenharmony_ci    "tests/ui/auxiliary/typeid-intrinsic-aux1.rs",
125fad3a1d3Sopenharmony_ci    "tests/ui/auxiliary/typeid-intrinsic-aux2.rs",
126fad3a1d3Sopenharmony_ci    "tests/ui/impl-trait/generic-with-implicit-hrtb-without-dyn.rs",
127fad3a1d3Sopenharmony_ci    "tests/ui/lifetimes/auxiliary/lifetime_bound_will_change_warning_lib.rs",
128fad3a1d3Sopenharmony_ci    "tests/ui/lifetimes/bare-trait-object-borrowck.rs",
129fad3a1d3Sopenharmony_ci    "tests/ui/lifetimes/bare-trait-object.rs",
130fad3a1d3Sopenharmony_ci    "tests/ui/parser/bounds-obj-parens.rs",
131fad3a1d3Sopenharmony_ci
132fad3a1d3Sopenharmony_ci    // Invalid unparenthesized range pattern inside slice pattern: `[1..]`
133fad3a1d3Sopenharmony_ci    "tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.rs",
134fad3a1d3Sopenharmony_ci
135fad3a1d3Sopenharmony_ci    // Various extensions to Rust syntax made up by rust-analyzer
136fad3a1d3Sopenharmony_ci    "src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0012_type_item_where_clause.rs",
137fad3a1d3Sopenharmony_ci    "src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0058_range_pat.rs",
138fad3a1d3Sopenharmony_ci    "src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0123_param_list_vararg.rs",
139fad3a1d3Sopenharmony_ci    "src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0131_existential_type.rs",
140fad3a1d3Sopenharmony_ci    "src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0156_fn_def_param.rs",
141fad3a1d3Sopenharmony_ci    "src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0179_use_tree_abs_star.rs",
142fad3a1d3Sopenharmony_ci    "src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0188_const_param_default_path.rs",
143fad3a1d3Sopenharmony_ci    "src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0015_use_tree.rs",
144fad3a1d3Sopenharmony_ci    "src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0029_range_forms.rs",
145fad3a1d3Sopenharmony_ci    "src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0051_parameter_attrs.rs",
146fad3a1d3Sopenharmony_ci    "src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0055_dot_dot_dot.rs",
147fad3a1d3Sopenharmony_ci    "src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0068_item_modifiers.rs",
148fad3a1d3Sopenharmony_ci    "src/tools/rust-analyzer/crates/syntax/test_data/parser/validation/0031_block_inner_attrs.rs",
149fad3a1d3Sopenharmony_ci    "src/tools/rust-analyzer/crates/syntax/test_data/parser/validation/0038_endless_inclusive_range.rs",
150fad3a1d3Sopenharmony_ci    "src/tools/rust-analyzer/crates/syntax/test_data/parser/validation/0045_ambiguous_trait_object.rs",
151fad3a1d3Sopenharmony_ci    "src/tools/rust-analyzer/crates/syntax/test_data/parser/validation/0046_mutable_const_item.rs",
152fad3a1d3Sopenharmony_ci
153fad3a1d3Sopenharmony_ci    // Placeholder syntax for "throw expressions"
154fad3a1d3Sopenharmony_ci    "compiler/rustc_errors/src/translation.rs",
155fad3a1d3Sopenharmony_ci    "src/tools/clippy/tests/ui/needless_return.rs",
156fad3a1d3Sopenharmony_ci    "src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0204_yeet_expr.rs",
157fad3a1d3Sopenharmony_ci    "tests/pretty/yeet-expr.rs",
158fad3a1d3Sopenharmony_ci    "tests/ui/try-trait/yeet-for-option.rs",
159fad3a1d3Sopenharmony_ci    "tests/ui/try-trait/yeet-for-result.rs",
160fad3a1d3Sopenharmony_ci
161fad3a1d3Sopenharmony_ci    // Edition 2015 code using identifiers that are now keywords
162fad3a1d3Sopenharmony_ci    // TODO: some of these we should probably parse
163fad3a1d3Sopenharmony_ci    "src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0159_try_macro_fallback.rs",
164fad3a1d3Sopenharmony_ci    "src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/0160_try_macro_rules.rs",
165fad3a1d3Sopenharmony_ci    "src/tools/rustfmt/tests/source/configs/indent_style/block_call.rs",
166fad3a1d3Sopenharmony_ci    "src/tools/rustfmt/tests/source/configs/use_try_shorthand/false.rs",
167fad3a1d3Sopenharmony_ci    "src/tools/rustfmt/tests/source/configs/use_try_shorthand/true.rs",
168fad3a1d3Sopenharmony_ci    "src/tools/rustfmt/tests/source/issue_1306.rs",
169fad3a1d3Sopenharmony_ci    "src/tools/rustfmt/tests/source/try-conversion.rs",
170fad3a1d3Sopenharmony_ci    "src/tools/rustfmt/tests/target/configs/indent_style/block_call.rs",
171fad3a1d3Sopenharmony_ci    "src/tools/rustfmt/tests/target/configs/use_try_shorthand/false.rs",
172fad3a1d3Sopenharmony_ci    "src/tools/rustfmt/tests/target/issue-1681.rs",
173fad3a1d3Sopenharmony_ci    "src/tools/rustfmt/tests/target/issue_1306.rs",
174fad3a1d3Sopenharmony_ci    "tests/ui/dyn-keyword/dyn-2015-no-warnings-without-lints.rs",
175fad3a1d3Sopenharmony_ci    "tests/ui/editions/edition-keywords-2015-2015.rs",
176fad3a1d3Sopenharmony_ci    "tests/ui/editions/edition-keywords-2015-2018.rs",
177fad3a1d3Sopenharmony_ci    "tests/ui/lint/lint_pre_expansion_extern_module_aux.rs",
178fad3a1d3Sopenharmony_ci    "tests/ui/macros/macro-comma-support-rpass.rs",
179fad3a1d3Sopenharmony_ci    "tests/ui/macros/try-macro.rs",
180fad3a1d3Sopenharmony_ci    "tests/ui/parser/extern-crate-async.rs",
181fad3a1d3Sopenharmony_ci    "tests/ui/try-block/try-is-identifier-edition2015.rs",
182fad3a1d3Sopenharmony_ci
183fad3a1d3Sopenharmony_ci    // Excessive nesting
184fad3a1d3Sopenharmony_ci    "tests/ui/issues/issue-74564-if-expr-stack-overflow.rs",
185fad3a1d3Sopenharmony_ci
186fad3a1d3Sopenharmony_ci    // Testing tools on invalid syntax
187fad3a1d3Sopenharmony_ci    "src/tools/rustfmt/tests/coverage/target/comments.rs",
188fad3a1d3Sopenharmony_ci    "src/tools/rustfmt/tests/parser/issue-4126/invalid.rs",
189fad3a1d3Sopenharmony_ci    "src/tools/rustfmt/tests/parser/issue_4418.rs",
190fad3a1d3Sopenharmony_ci    "src/tools/rustfmt/tests/parser/unclosed-delims/issue_4466.rs",
191fad3a1d3Sopenharmony_ci    "src/tools/rustfmt/tests/source/configs/disable_all_formatting/true.rs",
192fad3a1d3Sopenharmony_ci    "src/tools/rustfmt/tests/source/configs/spaces_around_ranges/false.rs",
193fad3a1d3Sopenharmony_ci    "src/tools/rustfmt/tests/source/configs/spaces_around_ranges/true.rs",
194fad3a1d3Sopenharmony_ci    "src/tools/rustfmt/tests/source/type.rs",
195fad3a1d3Sopenharmony_ci    "src/tools/rustfmt/tests/target/configs/spaces_around_ranges/false.rs",
196fad3a1d3Sopenharmony_ci    "src/tools/rustfmt/tests/target/configs/spaces_around_ranges/true.rs",
197fad3a1d3Sopenharmony_ci    "src/tools/rustfmt/tests/target/type.rs",
198fad3a1d3Sopenharmony_ci    "tests/run-make/translation/test.rs",
199fad3a1d3Sopenharmony_ci    "tests/ui/generics/issue-94432-garbage-ice.rs",
200fad3a1d3Sopenharmony_ci
201fad3a1d3Sopenharmony_ci    // Generated file containing a top-level expression, used with `include!`
202fad3a1d3Sopenharmony_ci    "compiler/rustc_codegen_gcc/src/intrinsic/archs.rs",
203fad3a1d3Sopenharmony_ci
204fad3a1d3Sopenharmony_ci    // Clippy lint lists represented as expressions
205fad3a1d3Sopenharmony_ci    "src/tools/clippy/clippy_lints/src/lib.deprecated.rs",
206fad3a1d3Sopenharmony_ci
207fad3a1d3Sopenharmony_ci    // Not actually test cases
208fad3a1d3Sopenharmony_ci    "tests/ui/lint/expansion-time-include.rs",
209fad3a1d3Sopenharmony_ci    "tests/ui/macros/auxiliary/macro-comma-support.rs",
210fad3a1d3Sopenharmony_ci    "tests/ui/macros/auxiliary/macro-include-items-expr.rs",
211fad3a1d3Sopenharmony_ci    "tests/ui/macros/include-single-expr-helper.rs",
212fad3a1d3Sopenharmony_ci    "tests/ui/macros/include-single-expr-helper-1.rs",
213fad3a1d3Sopenharmony_ci    "tests/ui/parser/issues/auxiliary/issue-21146-inc.rs",
214fad3a1d3Sopenharmony_ci];
215fad3a1d3Sopenharmony_ci
216fad3a1d3Sopenharmony_ci#[rustfmt::skip]
217fad3a1d3Sopenharmony_cistatic EXCLUDE_DIRS: &[&str] = &[
218fad3a1d3Sopenharmony_ci    // Inputs that intentionally do not parse
219fad3a1d3Sopenharmony_ci    "src/tools/rust-analyzer/crates/parser/test_data/parser/err",
220fad3a1d3Sopenharmony_ci    "src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err",
221fad3a1d3Sopenharmony_ci
222fad3a1d3Sopenharmony_ci    // Inputs that lex but do not necessarily parse
223fad3a1d3Sopenharmony_ci    "src/tools/rust-analyzer/crates/parser/test_data/lexer",
224fad3a1d3Sopenharmony_ci
225fad3a1d3Sopenharmony_ci    // Inputs that used to crash rust-analyzer, but aren't necessarily supposed to parse
226fad3a1d3Sopenharmony_ci    "src/tools/rust-analyzer/crates/syntax/test_data/parser/fuzz-failures",
227fad3a1d3Sopenharmony_ci    "src/tools/rust-analyzer/crates/syntax/test_data/reparse/fuzz-failures",
228fad3a1d3Sopenharmony_ci];
229fad3a1d3Sopenharmony_ci
230fad3a1d3Sopenharmony_ci// Directories in which a .stderr implies the corresponding .rs is not expected
231fad3a1d3Sopenharmony_ci// to work.
232fad3a1d3Sopenharmony_cistatic UI_TEST_DIRS: &[&str] = &["tests/ui", "tests/rustdoc-ui"];
233fad3a1d3Sopenharmony_ci
234fad3a1d3Sopenharmony_cipub fn for_each_rust_file(for_each: impl Fn(&Path) + Sync + Send) {
235fad3a1d3Sopenharmony_ci    let mut rs_files = BTreeSet::new();
236fad3a1d3Sopenharmony_ci
237fad3a1d3Sopenharmony_ci    let repo_dir = Path::new("tests/rust");
238fad3a1d3Sopenharmony_ci    for entry in WalkDir::new(repo_dir)
239fad3a1d3Sopenharmony_ci        .into_iter()
240fad3a1d3Sopenharmony_ci        .filter_entry(base_dir_filter)
241fad3a1d3Sopenharmony_ci    {
242fad3a1d3Sopenharmony_ci        let entry = entry.unwrap();
243fad3a1d3Sopenharmony_ci        if !entry.file_type().is_dir() {
244fad3a1d3Sopenharmony_ci            rs_files.insert(entry.into_path());
245fad3a1d3Sopenharmony_ci        }
246fad3a1d3Sopenharmony_ci    }
247fad3a1d3Sopenharmony_ci
248fad3a1d3Sopenharmony_ci    for ui_test_dir in UI_TEST_DIRS {
249fad3a1d3Sopenharmony_ci        for entry in WalkDir::new(repo_dir.join(ui_test_dir)) {
250fad3a1d3Sopenharmony_ci            let mut path = entry.unwrap().into_path();
251fad3a1d3Sopenharmony_ci            if path.extension() == Some(OsStr::new("stderr")) {
252fad3a1d3Sopenharmony_ci                loop {
253fad3a1d3Sopenharmony_ci                    rs_files.remove(&path.with_extension("rs"));
254fad3a1d3Sopenharmony_ci                    path = path.with_extension("");
255fad3a1d3Sopenharmony_ci                    if path.extension().is_none() {
256fad3a1d3Sopenharmony_ci                        break;
257fad3a1d3Sopenharmony_ci                    }
258fad3a1d3Sopenharmony_ci                }
259fad3a1d3Sopenharmony_ci            }
260fad3a1d3Sopenharmony_ci        }
261fad3a1d3Sopenharmony_ci    }
262fad3a1d3Sopenharmony_ci
263fad3a1d3Sopenharmony_ci    rs_files.par_iter().map(PathBuf::as_path).for_each(for_each);
264fad3a1d3Sopenharmony_ci}
265fad3a1d3Sopenharmony_ci
266fad3a1d3Sopenharmony_cipub fn base_dir_filter(entry: &DirEntry) -> bool {
267fad3a1d3Sopenharmony_ci    let path = entry.path();
268fad3a1d3Sopenharmony_ci
269fad3a1d3Sopenharmony_ci    let mut path_string = path.to_string_lossy();
270fad3a1d3Sopenharmony_ci    if cfg!(windows) {
271fad3a1d3Sopenharmony_ci        path_string = path_string.replace('\\', "/").into();
272fad3a1d3Sopenharmony_ci    }
273fad3a1d3Sopenharmony_ci    let path_string = if path_string == "tests/rust" {
274fad3a1d3Sopenharmony_ci        return true;
275fad3a1d3Sopenharmony_ci    } else if let Some(path) = path_string.strip_prefix("tests/rust/") {
276fad3a1d3Sopenharmony_ci        path
277fad3a1d3Sopenharmony_ci    } else {
278fad3a1d3Sopenharmony_ci        panic!("unexpected path in Rust dist: {}", path_string);
279fad3a1d3Sopenharmony_ci    };
280fad3a1d3Sopenharmony_ci
281fad3a1d3Sopenharmony_ci    if path.is_dir() {
282fad3a1d3Sopenharmony_ci        return !EXCLUDE_DIRS.contains(&path_string);
283fad3a1d3Sopenharmony_ci    }
284fad3a1d3Sopenharmony_ci
285fad3a1d3Sopenharmony_ci    if path.extension() != Some(OsStr::new("rs")) {
286fad3a1d3Sopenharmony_ci        return false;
287fad3a1d3Sopenharmony_ci    }
288fad3a1d3Sopenharmony_ci
289fad3a1d3Sopenharmony_ci    !EXCLUDE_FILES.contains(&path_string)
290fad3a1d3Sopenharmony_ci}
291fad3a1d3Sopenharmony_ci
292fad3a1d3Sopenharmony_ci#[allow(dead_code)]
293fad3a1d3Sopenharmony_cipub fn edition(path: &Path) -> &'static str {
294fad3a1d3Sopenharmony_ci    if path.ends_with("dyn-2015-no-warnings-without-lints.rs") {
295fad3a1d3Sopenharmony_ci        "2015"
296fad3a1d3Sopenharmony_ci    } else {
297fad3a1d3Sopenharmony_ci        "2018"
298fad3a1d3Sopenharmony_ci    }
299fad3a1d3Sopenharmony_ci}
300fad3a1d3Sopenharmony_ci
301fad3a1d3Sopenharmony_cipub fn clone_rust() {
302fad3a1d3Sopenharmony_ci    let needs_clone = match fs::read_to_string("tests/rust/COMMIT") {
303fad3a1d3Sopenharmony_ci        Err(_) => true,
304fad3a1d3Sopenharmony_ci        Ok(contents) => contents.trim() != REVISION,
305fad3a1d3Sopenharmony_ci    };
306fad3a1d3Sopenharmony_ci    if needs_clone {
307fad3a1d3Sopenharmony_ci        download_and_unpack().unwrap();
308fad3a1d3Sopenharmony_ci    }
309fad3a1d3Sopenharmony_ci
310fad3a1d3Sopenharmony_ci    let mut missing = String::new();
311fad3a1d3Sopenharmony_ci    let test_src = Path::new("tests/rust");
312fad3a1d3Sopenharmony_ci
313fad3a1d3Sopenharmony_ci    let mut exclude_files_set = BTreeSet::new();
314fad3a1d3Sopenharmony_ci    for exclude in EXCLUDE_FILES {
315fad3a1d3Sopenharmony_ci        if !exclude_files_set.insert(exclude) {
316fad3a1d3Sopenharmony_ci            panic!("duplicate path in EXCLUDE_FILES: {}", exclude);
317fad3a1d3Sopenharmony_ci        }
318fad3a1d3Sopenharmony_ci        for dir in EXCLUDE_DIRS {
319fad3a1d3Sopenharmony_ci            if Path::new(exclude).starts_with(dir) {
320fad3a1d3Sopenharmony_ci                panic!("excluded file {} is inside an excluded dir", exclude);
321fad3a1d3Sopenharmony_ci            }
322fad3a1d3Sopenharmony_ci        }
323fad3a1d3Sopenharmony_ci        if !test_src.join(exclude).is_file() {
324fad3a1d3Sopenharmony_ci            missing += "\ntests/rust/";
325fad3a1d3Sopenharmony_ci            missing += exclude;
326fad3a1d3Sopenharmony_ci        }
327fad3a1d3Sopenharmony_ci    }
328fad3a1d3Sopenharmony_ci
329fad3a1d3Sopenharmony_ci    let mut exclude_dirs_set = BTreeSet::new();
330fad3a1d3Sopenharmony_ci    for exclude in EXCLUDE_DIRS {
331fad3a1d3Sopenharmony_ci        if !exclude_dirs_set.insert(exclude) {
332fad3a1d3Sopenharmony_ci            panic!("duplicate path in EXCLUDE_DIRS: {}", exclude);
333fad3a1d3Sopenharmony_ci        }
334fad3a1d3Sopenharmony_ci        if !test_src.join(exclude).is_dir() {
335fad3a1d3Sopenharmony_ci            missing += "\ntests/rust/";
336fad3a1d3Sopenharmony_ci            missing += exclude;
337fad3a1d3Sopenharmony_ci            missing += "/";
338fad3a1d3Sopenharmony_ci        }
339fad3a1d3Sopenharmony_ci    }
340fad3a1d3Sopenharmony_ci
341fad3a1d3Sopenharmony_ci    if !missing.is_empty() {
342fad3a1d3Sopenharmony_ci        panic!("excluded test file does not exist:{}\n", missing);
343fad3a1d3Sopenharmony_ci    }
344fad3a1d3Sopenharmony_ci}
345fad3a1d3Sopenharmony_ci
346fad3a1d3Sopenharmony_cifn download_and_unpack() -> Result<()> {
347fad3a1d3Sopenharmony_ci    let url = format!(
348fad3a1d3Sopenharmony_ci        "https://github.com/rust-lang/rust/archive/{}.tar.gz",
349fad3a1d3Sopenharmony_ci        REVISION
350fad3a1d3Sopenharmony_ci    );
351fad3a1d3Sopenharmony_ci    let response = reqwest::blocking::get(url)?.error_for_status()?;
352fad3a1d3Sopenharmony_ci    let progress = Progress::new(response);
353fad3a1d3Sopenharmony_ci    let decoder = GzDecoder::new(progress);
354fad3a1d3Sopenharmony_ci    let mut archive = Archive::new(decoder);
355fad3a1d3Sopenharmony_ci    let prefix = format!("rust-{}", REVISION);
356fad3a1d3Sopenharmony_ci
357fad3a1d3Sopenharmony_ci    let tests_rust = Path::new("tests/rust");
358fad3a1d3Sopenharmony_ci    if tests_rust.exists() {
359fad3a1d3Sopenharmony_ci        fs::remove_dir_all(tests_rust)?;
360fad3a1d3Sopenharmony_ci    }
361fad3a1d3Sopenharmony_ci
362fad3a1d3Sopenharmony_ci    for entry in archive.entries()? {
363fad3a1d3Sopenharmony_ci        let mut entry = entry?;
364fad3a1d3Sopenharmony_ci        let path = entry.path()?;
365fad3a1d3Sopenharmony_ci        if path == Path::new("pax_global_header") {
366fad3a1d3Sopenharmony_ci            continue;
367fad3a1d3Sopenharmony_ci        }
368fad3a1d3Sopenharmony_ci        let relative = path.strip_prefix(&prefix)?;
369fad3a1d3Sopenharmony_ci        let out = tests_rust.join(relative);
370fad3a1d3Sopenharmony_ci        entry.unpack(&out)?;
371fad3a1d3Sopenharmony_ci    }
372fad3a1d3Sopenharmony_ci
373fad3a1d3Sopenharmony_ci    fs::write("tests/rust/COMMIT", REVISION)?;
374fad3a1d3Sopenharmony_ci    Ok(())
375fad3a1d3Sopenharmony_ci}
376