useself::progress::Progress; use anyhow::Result; use flate2::read::GzDecoder; use rayon::iter::{IntoParallelRefIterator, ParallelIterator}; use rayon::ThreadPoolBuilder; use std::collections::BTreeSet; use std::env; use std::ffi::OsStr; use std::fs; use std::path::{Path, PathBuf}; use tar::Archive; use walkdir::{DirEntry, WalkDir};
// TODO: lazy type alias syntax with where-clause in trailing position // https://github.com/dtolnay/syn/issues/1525 "src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/type_item_where_clause.rs", "src/tools/rustfmt/tests/source/type-alias-where-clauses-with-comments.rs", "src/tools/rustfmt/tests/source/type-alias-where-clauses.rs", "src/tools/rustfmt/tests/target/type-alias-where-clauses-with-comments.rs", "src/tools/rustfmt/tests/target/type-alias-where-clauses.rs", "tests/rustdoc/typedef-inner-variants-lazy_type_alias.rs",
// Compile-fail variadics in not the last position of a function parameter list "src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/fn_def_param.rs", "src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/param_list_vararg.rs", "tests/ui/parser/variadic-ffi-syntactic-pass.rs",
// Need at least one trait in impl Trait, no such type as impl 'static "tests/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs",
// Various extensions to Rust syntax made up by rust-analyzer "src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/const_param_default_path.rs", "src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/use_tree_abs_star.rs", "src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0015_use_tree.rs", "src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0029_range_forms.rs", "src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0051_parameter_attrs.rs", "src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0055_dot_dot_dot.rs", "src/tools/rust-analyzer/crates/parser/test_data/parser/ok/0068_item_modifiers.rs", "src/tools/rust-analyzer/crates/syntax/test_data/parser/validation/0031_block_inner_attrs.rs", "src/tools/rust-analyzer/crates/syntax/test_data/parser/validation/0038_endless_inclusive_range.rs", "src/tools/rust-analyzer/crates/syntax/test_data/parser/validation/0045_ambiguous_trait_object.rs", "src/tools/rust-analyzer/crates/syntax/test_data/parser/validation/0046_mutable_const_item.rs",
// Edition 2015 code using identifiers that are now keywords // TODO: some of these we should probably parse "src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/dyn_trait_type_weak.rs", "src/tools/rustfmt/tests/source/configs/indent_style/block_call.rs", "src/tools/rustfmt/tests/source/configs/use_try_shorthand/false.rs", "src/tools/rustfmt/tests/source/configs/use_try_shorthand/true.rs", "src/tools/rustfmt/tests/source/issue_1306.rs", "src/tools/rustfmt/tests/source/try-conversion.rs", "src/tools/rustfmt/tests/target/configs/indent_style/block_call.rs", "src/tools/rustfmt/tests/target/configs/use_try_shorthand/false.rs", "src/tools/rustfmt/tests/target/issue-1681.rs", "src/tools/rustfmt/tests/target/issue_1306.rs", "tests/ui/dyn-keyword/dyn-2015-no-warnings-without-lints.rs", "tests/ui/editions/edition-keywords-2015-2015.rs", "tests/ui/editions/edition-keywords-2015-2018.rs", "tests/ui/lint/lint_pre_expansion_extern_module_aux.rs", "tests/ui/macros/macro-comma-support-rpass.rs", "tests/ui/macros/try-macro.rs", "tests/ui/parser/extern-crate-async.rs", "tests/ui/try-block/try-is-identifier-edition2015.rs",
// Generated file containing a top-level expression, used with `include!` "compiler/rustc_codegen_gcc/src/intrinsic/archs.rs",
// Not actually test cases "tests/ui/lint/expansion-time-include.rs", "tests/ui/macros/auxiliary/macro-comma-support.rs", "tests/ui/macros/auxiliary/macro-include-items-expr.rs", "tests/ui/macros/include-single-expr-helper.rs", "tests/ui/macros/include-single-expr-helper-1.rs", "tests/ui/parser/issues/auxiliary/issue-21146-inc.rs",
];
#[rustfmt::skip] static EXCLUDE_DIRS: &[&str] = &[ // Inputs that intentionally do not parse "src/tools/rust-analyzer/crates/parser/test_data/parser/err", "src/tools/rust-analyzer/crates/parser/test_data/parser/inline/err",
// Inputs that lex but do not necessarily parse "src/tools/rust-analyzer/crates/parser/test_data/lexer",
// Inputs that used to crash rust-analyzer, but aren't necessarily supposed to parse "src/tools/rust-analyzer/crates/syntax/test_data/parser/fuzz-failures", "src/tools/rust-analyzer/crates/syntax/test_data/reparse/fuzz-failures",
// Inputs that crash rustc, making no claim about whether they are valid Rust "tests/crashes",
];
// Directories in which a .stderr implies the corresponding .rs is not expected // to work. static UI_TEST_DIRS: &[&str] = &["tests/ui", "tests/rustdoc-ui"];
let repo_dir = Path::new("tests/rust"); for entry in WalkDir::new(repo_dir)
.into_iter()
.filter_entry(base_dir_filter)
{ let entry = entry.unwrap(); if !entry.file_type().is_dir() {
rs_files.insert(entry.into_path());
}
}
for ui_test_dir in UI_TEST_DIRS { for entry in WalkDir::new(repo_dir.join(ui_test_dir)) { letmut path = entry.unwrap().into_path(); if path.extension() == Some(OsStr::new("stderr")) { loop {
rs_files.remove(&path.with_extension("rs"));
path = path.with_extension(""); if path.extension().is_none() { break;
}
}
}
}
}
#[allow(dead_code)] pubfn abort_after() -> usize { match env::var("ABORT_AFTER_FAILURE") {
Ok(s) => s.parse().expect("failed to parse ABORT_AFTER_FAILURE"),
Err(_) => usize::MAX,
}
}
pubfn rayon_init() { let stack_size = match env::var("RUST_MIN_STACK") {
Ok(s) => s.parse().expect("failed to parse RUST_MIN_STACK"),
Err(_) => 1024 * 1024 * if cfg!(debug_assertions) { 40 } else { 20 },
};
ThreadPoolBuilder::new()
.stack_size(stack_size)
.build_global()
.unwrap();
}
pubfn clone_rust() { let needs_clone = match fs::read_to_string("tests/rust/COMMIT") {
Err(_) => true,
Ok(contents) => contents.trim() != REVISION,
}; if needs_clone {
download_and_unpack().unwrap();
}
letmut missing = String::new(); let test_src = Path::new("tests/rust");
letmut exclude_files_set = BTreeSet::new(); for exclude in EXCLUDE_FILES { if !exclude_files_set.insert(exclude) {
panic!("duplicate path in EXCLUDE_FILES: {}", exclude);
} for dir in EXCLUDE_DIRS { if Path::new(exclude).starts_with(dir) {
panic!("excluded file {} is inside an excluded dir", exclude);
}
} if !test_src.join(exclude).is_file() {
missing += "\ntests/rust/";
missing += exclude;
}
}
letmut exclude_dirs_set = BTreeSet::new(); for exclude in EXCLUDE_DIRS { if !exclude_dirs_set.insert(exclude) {
panic!("duplicate path in EXCLUDE_DIRS: {}", exclude);
} if !test_src.join(exclude).is_dir() {
missing += "\ntests/rust/";
missing += exclude;
missing += "/";
}
}
if !missing.is_empty() {
panic!("excluded test file does not exist:{}\n", missing);
}
}
fn download_and_unpack() -> Result<()> { let url = format!( "https://github.com/rust-lang/rust/archive/{}.tar.gz",
REVISION
); let response = reqwest::blocking::get(url)?.error_for_status()?; let progress = Progress::new(response); let decoder = GzDecoder::new(progress); letmut archive = Archive::new(decoder); let prefix = format!("rust-{}", REVISION);
let tests_rust = Path::new("tests/rust"); if tests_rust.exists() {
fs::remove_dir_all(tests_rust)?;
}
for entry in archive.entries()? { letmut entry = entry?; let path = entry.path()?; if path == Path::new("pax_global_header") { continue;
} let relative = path.strip_prefix(&prefix)?; let out = tests_rust.join(relative);
entry.unpack(&out)?;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.