mirror of
https://github.com/rust-lang/rust.git
synced 2026-05-29 20:46:07 +03:00
Rollup merge of #147170 - Zalathar:directive, r=jieyouxu
compiletest: Pass around `DirectiveLine` instead of bare strings This is an incremental step towards being able to clean up and centralize compiletest directive parsing. My original plan was to add features to `DirectiveLine`, and then gradually migrate parsing code to use those features. However, that turned out to be impractical, because of how the existing directive parsers call each other. So instead this PR focuses on getting them to all take `DirectiveLine` instead of bare strings, to enable incremental work in the future. Because this is part of an ongoing cleanup, I've prioritised clean diffs over nice code, because much of this code is going to be modified again when `DirectiveLine` is more capable. r? jieyouxu
This commit is contained in:
@@ -63,9 +63,10 @@ pub fn from_reader<R: Read>(config: &Config, testfile: &Utf8Path, rdr: R) -> Sel
|
||||
&mut poisoned,
|
||||
testfile,
|
||||
rdr,
|
||||
&mut |DirectiveLine { line_number, raw_directive: ln, .. }| {
|
||||
parse_and_update_aux(config, ln, testfile, line_number, &mut props.aux);
|
||||
config.parse_and_update_revisions(testfile, line_number, ln, &mut props.revisions);
|
||||
// (dummy comment to force args into vertical layout)
|
||||
&mut |ref ln: DirectiveLine<'_>| {
|
||||
parse_and_update_aux(config, ln, testfile, &mut props.aux);
|
||||
config.parse_and_update_revisions(testfile, ln, &mut props.revisions);
|
||||
},
|
||||
);
|
||||
|
||||
@@ -367,8 +368,8 @@ fn load_from(&mut self, testfile: &Utf8Path, test_revision: Option<&str>, config
|
||||
&mut poisoned,
|
||||
testfile,
|
||||
file,
|
||||
&mut |directive @ DirectiveLine { line_number, raw_directive: ln, .. }| {
|
||||
if !directive.applies_to_test_revision(test_revision) {
|
||||
&mut |ref ln: DirectiveLine<'_>| {
|
||||
if !ln.applies_to_test_revision(test_revision) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -378,7 +379,6 @@ fn load_from(&mut self, testfile: &Utf8Path, test_revision: Option<&str>, config
|
||||
ln,
|
||||
ERROR_PATTERN,
|
||||
testfile,
|
||||
line_number,
|
||||
&mut self.error_patterns,
|
||||
|r| r,
|
||||
);
|
||||
@@ -386,7 +386,6 @@ fn load_from(&mut self, testfile: &Utf8Path, test_revision: Option<&str>, config
|
||||
ln,
|
||||
REGEX_ERROR_PATTERN,
|
||||
testfile,
|
||||
line_number,
|
||||
&mut self.regex_error_patterns,
|
||||
|r| r,
|
||||
);
|
||||
@@ -395,7 +394,6 @@ fn load_from(&mut self, testfile: &Utf8Path, test_revision: Option<&str>, config
|
||||
ln,
|
||||
DOC_FLAGS,
|
||||
testfile,
|
||||
line_number,
|
||||
&mut self.doc_flags,
|
||||
|r| r,
|
||||
);
|
||||
@@ -414,7 +412,7 @@ fn split_flags(flags: &str) -> Vec<String> {
|
||||
}
|
||||
|
||||
if let Some(flags) =
|
||||
config.parse_name_value_directive(ln, COMPILE_FLAGS, testfile, line_number)
|
||||
config.parse_name_value_directive(ln, COMPILE_FLAGS, testfile)
|
||||
{
|
||||
let flags = split_flags(&flags);
|
||||
for flag in &flags {
|
||||
@@ -425,39 +423,28 @@ fn split_flags(flags: &str) -> Vec<String> {
|
||||
self.compile_flags.extend(flags);
|
||||
}
|
||||
if config
|
||||
.parse_name_value_directive(
|
||||
ln,
|
||||
INCORRECT_COMPILER_FLAGS,
|
||||
testfile,
|
||||
line_number,
|
||||
)
|
||||
.parse_name_value_directive(ln, INCORRECT_COMPILER_FLAGS, testfile)
|
||||
.is_some()
|
||||
{
|
||||
panic!("`compiler-flags` directive should be spelled `compile-flags`");
|
||||
}
|
||||
|
||||
if let Some(edition) = config.parse_edition(ln, testfile, line_number) {
|
||||
if let Some(edition) = config.parse_edition(ln, testfile) {
|
||||
// The edition is added at the start, since flags from //@compile-flags must
|
||||
// be passed to rustc last.
|
||||
self.compile_flags.insert(0, format!("--edition={}", edition.trim()));
|
||||
has_edition = true;
|
||||
}
|
||||
|
||||
config.parse_and_update_revisions(
|
||||
testfile,
|
||||
line_number,
|
||||
ln,
|
||||
&mut self.revisions,
|
||||
);
|
||||
config.parse_and_update_revisions(testfile, ln, &mut self.revisions);
|
||||
|
||||
if let Some(flags) =
|
||||
config.parse_name_value_directive(ln, RUN_FLAGS, testfile, line_number)
|
||||
if let Some(flags) = config.parse_name_value_directive(ln, RUN_FLAGS, testfile)
|
||||
{
|
||||
self.run_flags.extend(split_flags(&flags));
|
||||
}
|
||||
|
||||
if self.pp_exact.is_none() {
|
||||
self.pp_exact = config.parse_pp_exact(ln, testfile, line_number);
|
||||
self.pp_exact = config.parse_pp_exact(ln, testfile);
|
||||
}
|
||||
|
||||
config.set_name_directive(ln, SHOULD_ICE, &mut self.should_ice);
|
||||
@@ -479,9 +466,7 @@ fn split_flags(flags: &str) -> Vec<String> {
|
||||
);
|
||||
config.set_name_directive(ln, NO_PREFER_DYNAMIC, &mut self.no_prefer_dynamic);
|
||||
|
||||
if let Some(m) =
|
||||
config.parse_name_value_directive(ln, PRETTY_MODE, testfile, line_number)
|
||||
{
|
||||
if let Some(m) = config.parse_name_value_directive(ln, PRETTY_MODE, testfile) {
|
||||
self.pretty_mode = m;
|
||||
}
|
||||
|
||||
@@ -492,13 +477,12 @@ fn split_flags(flags: &str) -> Vec<String> {
|
||||
);
|
||||
|
||||
// Call a helper method to deal with aux-related directives.
|
||||
parse_and_update_aux(config, ln, testfile, line_number, &mut self.aux);
|
||||
parse_and_update_aux(config, ln, testfile, &mut self.aux);
|
||||
|
||||
config.push_name_value_directive(
|
||||
ln,
|
||||
EXEC_ENV,
|
||||
testfile,
|
||||
line_number,
|
||||
&mut self.exec_env,
|
||||
Config::parse_env,
|
||||
);
|
||||
@@ -506,7 +490,6 @@ fn split_flags(flags: &str) -> Vec<String> {
|
||||
ln,
|
||||
UNSET_EXEC_ENV,
|
||||
testfile,
|
||||
line_number,
|
||||
&mut self.unset_exec_env,
|
||||
|r| r.trim().to_owned(),
|
||||
);
|
||||
@@ -514,7 +497,6 @@ fn split_flags(flags: &str) -> Vec<String> {
|
||||
ln,
|
||||
RUSTC_ENV,
|
||||
testfile,
|
||||
line_number,
|
||||
&mut self.rustc_env,
|
||||
Config::parse_env,
|
||||
);
|
||||
@@ -522,7 +504,6 @@ fn split_flags(flags: &str) -> Vec<String> {
|
||||
ln,
|
||||
UNSET_RUSTC_ENV,
|
||||
testfile,
|
||||
line_number,
|
||||
&mut self.unset_rustc_env,
|
||||
|r| r.trim().to_owned(),
|
||||
);
|
||||
@@ -530,7 +511,6 @@ fn split_flags(flags: &str) -> Vec<String> {
|
||||
ln,
|
||||
FORBID_OUTPUT,
|
||||
testfile,
|
||||
line_number,
|
||||
&mut self.forbid_output,
|
||||
|r| r,
|
||||
);
|
||||
@@ -566,7 +546,7 @@ fn split_flags(flags: &str) -> Vec<String> {
|
||||
}
|
||||
|
||||
if let Some(code) = config
|
||||
.parse_name_value_directive(ln, FAILURE_STATUS, testfile, line_number)
|
||||
.parse_name_value_directive(ln, FAILURE_STATUS, testfile)
|
||||
.and_then(|code| code.trim().parse::<i32>().ok())
|
||||
{
|
||||
self.failure_status = Some(code);
|
||||
@@ -588,7 +568,6 @@ fn split_flags(flags: &str) -> Vec<String> {
|
||||
ln,
|
||||
ASSEMBLY_OUTPUT,
|
||||
testfile,
|
||||
line_number,
|
||||
&mut self.assembly_output,
|
||||
|r| r.trim().to_string(),
|
||||
);
|
||||
@@ -602,7 +581,7 @@ fn split_flags(flags: &str) -> Vec<String> {
|
||||
// Unlike the other `name_value_directive`s this needs to be handled manually,
|
||||
// because it sets a `bool` flag.
|
||||
if let Some(known_bug) =
|
||||
config.parse_name_value_directive(ln, KNOWN_BUG, testfile, line_number)
|
||||
config.parse_name_value_directive(ln, KNOWN_BUG, testfile)
|
||||
{
|
||||
let known_bug = known_bug.trim();
|
||||
if known_bug == "unknown"
|
||||
@@ -632,24 +611,20 @@ fn split_flags(flags: &str) -> Vec<String> {
|
||||
ln,
|
||||
TEST_MIR_PASS,
|
||||
testfile,
|
||||
line_number,
|
||||
&mut self.mir_unit_test,
|
||||
|s| s.trim().to_string(),
|
||||
);
|
||||
config.set_name_directive(ln, REMAP_SRC_BASE, &mut self.remap_src_base);
|
||||
|
||||
if let Some(flags) =
|
||||
config.parse_name_value_directive(ln, LLVM_COV_FLAGS, testfile, line_number)
|
||||
config.parse_name_value_directive(ln, LLVM_COV_FLAGS, testfile)
|
||||
{
|
||||
self.llvm_cov_flags.extend(split_flags(&flags));
|
||||
}
|
||||
|
||||
if let Some(flags) = config.parse_name_value_directive(
|
||||
ln,
|
||||
FILECHECK_FLAGS,
|
||||
testfile,
|
||||
line_number,
|
||||
) {
|
||||
if let Some(flags) =
|
||||
config.parse_name_value_directive(ln, FILECHECK_FLAGS, testfile)
|
||||
{
|
||||
self.filecheck_flags.extend(split_flags(&flags));
|
||||
}
|
||||
|
||||
@@ -661,7 +636,6 @@ fn split_flags(flags: &str) -> Vec<String> {
|
||||
ln,
|
||||
directives::CORE_STUBS_COMPILE_FLAGS,
|
||||
testfile,
|
||||
line_number,
|
||||
) {
|
||||
let flags = split_flags(&flags);
|
||||
for flag in &flags {
|
||||
@@ -672,12 +646,9 @@ fn split_flags(flags: &str) -> Vec<String> {
|
||||
self.core_stubs_compile_flags.extend(flags);
|
||||
}
|
||||
|
||||
if let Some(err_kind) = config.parse_name_value_directive(
|
||||
ln,
|
||||
DONT_REQUIRE_ANNOTATIONS,
|
||||
testfile,
|
||||
line_number,
|
||||
) {
|
||||
if let Some(err_kind) =
|
||||
config.parse_name_value_directive(ln, DONT_REQUIRE_ANNOTATIONS, testfile)
|
||||
{
|
||||
self.dont_require_annotations
|
||||
.insert(ErrorKind::expect_from_user_str(err_kind.trim()));
|
||||
}
|
||||
@@ -734,7 +705,7 @@ fn split_flags(flags: &str) -> Vec<String> {
|
||||
}
|
||||
}
|
||||
|
||||
fn update_fail_mode(&mut self, ln: &str, config: &Config) {
|
||||
fn update_fail_mode(&mut self, ln: &DirectiveLine<'_>, config: &Config) {
|
||||
let check_ui = |mode: &str| {
|
||||
// Mode::Crashes may need build-fail in order to trigger llvm errors or stack overflows
|
||||
if config.mode != TestMode::Ui && config.mode != TestMode::Crashes {
|
||||
@@ -769,7 +740,12 @@ fn update_fail_mode(&mut self, ln: &str, config: &Config) {
|
||||
}
|
||||
}
|
||||
|
||||
fn update_pass_mode(&mut self, ln: &str, revision: Option<&str>, config: &Config) {
|
||||
fn update_pass_mode(
|
||||
&mut self,
|
||||
ln: &DirectiveLine<'_>,
|
||||
revision: Option<&str>,
|
||||
config: &Config,
|
||||
) {
|
||||
let check_no_run = |s| match (config.mode, s) {
|
||||
(TestMode::Ui, _) => (),
|
||||
(TestMode::Crashes, _) => (),
|
||||
@@ -814,7 +790,7 @@ pub fn local_pass_mode(&self) -> Option<PassMode> {
|
||||
self.pass_mode
|
||||
}
|
||||
|
||||
pub fn update_add_core_stubs(&mut self, ln: &str, config: &Config) {
|
||||
fn update_add_core_stubs(&mut self, ln: &DirectiveLine<'_>, config: &Config) {
|
||||
let add_core_stubs = config.parse_name_directive(ln, directives::ADD_CORE_STUBS);
|
||||
if add_core_stubs {
|
||||
if !matches!(config.mode, TestMode::Ui | TestMode::Codegen | TestMode::Assembly) {
|
||||
@@ -905,10 +881,12 @@ pub(crate) struct CheckDirectiveResult<'ln> {
|
||||
trailing_directive: Option<&'ln str>,
|
||||
}
|
||||
|
||||
pub(crate) fn check_directive<'a>(
|
||||
directive_ln: &'a str,
|
||||
fn check_directive<'a>(
|
||||
directive_ln: &DirectiveLine<'a>,
|
||||
mode: TestMode,
|
||||
) -> CheckDirectiveResult<'a> {
|
||||
let &DirectiveLine { raw_directive: directive_ln, .. } = directive_ln;
|
||||
|
||||
let (directive_name, post) = directive_ln.split_once([':', ' ']).unwrap_or((directive_ln, ""));
|
||||
|
||||
let is_known_directive = KNOWN_DIRECTIVE_NAMES.contains(&directive_name)
|
||||
@@ -980,7 +958,7 @@ fn iter_directives(
|
||||
// Perform unknown directive check on Rust files.
|
||||
if testfile.extension() == Some("rs") {
|
||||
let CheckDirectiveResult { is_known_directive, trailing_directive } =
|
||||
check_directive(directive_line.raw_directive, mode);
|
||||
check_directive(&directive_line, mode);
|
||||
|
||||
if !is_known_directive {
|
||||
*poisoned = true;
|
||||
@@ -1014,8 +992,7 @@ impl Config {
|
||||
fn parse_and_update_revisions(
|
||||
&self,
|
||||
testfile: &Utf8Path,
|
||||
line_number: usize,
|
||||
line: &str,
|
||||
line: &DirectiveLine<'_>,
|
||||
existing: &mut Vec<String>,
|
||||
) {
|
||||
const FORBIDDEN_REVISION_NAMES: [&str; 2] = [
|
||||
@@ -1028,8 +1005,7 @@ fn parse_and_update_revisions(
|
||||
const FILECHECK_FORBIDDEN_REVISION_NAMES: [&str; 9] =
|
||||
["CHECK", "COM", "NEXT", "SAME", "EMPTY", "NOT", "COUNT", "DAG", "LABEL"];
|
||||
|
||||
if let Some(raw) = self.parse_name_value_directive(line, "revisions", testfile, line_number)
|
||||
{
|
||||
if let Some(raw) = self.parse_name_value_directive(line, "revisions", testfile) {
|
||||
if self.mode == TestMode::RunMake {
|
||||
panic!("`run-make` mode tests do not support revisions: {}", testfile);
|
||||
}
|
||||
@@ -1074,13 +1050,8 @@ fn parse_env(nv: String) -> (String, String) {
|
||||
(name.to_owned(), value.to_owned())
|
||||
}
|
||||
|
||||
fn parse_pp_exact(
|
||||
&self,
|
||||
line: &str,
|
||||
testfile: &Utf8Path,
|
||||
line_number: usize,
|
||||
) -> Option<Utf8PathBuf> {
|
||||
if let Some(s) = self.parse_name_value_directive(line, "pp-exact", testfile, line_number) {
|
||||
fn parse_pp_exact(&self, line: &DirectiveLine<'_>, testfile: &Utf8Path) -> Option<Utf8PathBuf> {
|
||||
if let Some(s) = self.parse_name_value_directive(line, "pp-exact", testfile) {
|
||||
Some(Utf8PathBuf::from(&s))
|
||||
} else if self.parse_name_directive(line, "pp-exact") {
|
||||
testfile.file_name().map(Utf8PathBuf::from)
|
||||
@@ -1089,7 +1060,9 @@ fn parse_pp_exact(
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_custom_normalization(&self, raw_directive: &str) -> Option<NormalizeRule> {
|
||||
fn parse_custom_normalization(&self, line: &DirectiveLine<'_>) -> Option<NormalizeRule> {
|
||||
let &DirectiveLine { raw_directive, .. } = line;
|
||||
|
||||
// FIXME(Zalathar): Integrate name/value splitting into `DirectiveLine`
|
||||
// instead of doing it here.
|
||||
let (directive_name, raw_value) = raw_directive.split_once(':')?;
|
||||
@@ -1110,24 +1083,23 @@ fn parse_custom_normalization(&self, raw_directive: &str) -> Option<NormalizeRul
|
||||
Some(NormalizeRule { kind, regex, replacement })
|
||||
}
|
||||
|
||||
fn parse_name_directive(&self, line: &str, directive: &str) -> bool {
|
||||
fn parse_name_directive(&self, line: &DirectiveLine<'_>, directive: &str) -> bool {
|
||||
let &DirectiveLine { raw_directive: line, .. } = line;
|
||||
|
||||
// Ensure the directive is a whole word. Do not match "ignore-x86" when
|
||||
// the line says "ignore-x86_64".
|
||||
line.starts_with(directive)
|
||||
&& matches!(line.as_bytes().get(directive.len()), None | Some(&b' ') | Some(&b':'))
|
||||
}
|
||||
|
||||
fn parse_negative_name_directive(&self, line: &str, directive: &str) -> bool {
|
||||
line.starts_with("no-") && self.parse_name_directive(&line[3..], directive)
|
||||
}
|
||||
|
||||
pub fn parse_name_value_directive(
|
||||
fn parse_name_value_directive(
|
||||
&self,
|
||||
line: &str,
|
||||
line: &DirectiveLine<'_>,
|
||||
directive: &str,
|
||||
testfile: &Utf8Path,
|
||||
line_number: usize,
|
||||
) -> Option<String> {
|
||||
let &DirectiveLine { line_number, raw_directive: line, .. } = line;
|
||||
|
||||
let colon = directive.len();
|
||||
if line.starts_with(directive) && line.as_bytes().get(colon) == Some(&b':') {
|
||||
let value = line[(colon + 1)..].to_owned();
|
||||
@@ -1144,52 +1116,37 @@ pub fn parse_name_value_directive(
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_edition(&self, line: &str, testfile: &Utf8Path, line_number: usize) -> Option<String> {
|
||||
self.parse_name_value_directive(line, "edition", testfile, line_number)
|
||||
fn parse_edition(&self, line: &DirectiveLine<'_>, testfile: &Utf8Path) -> Option<String> {
|
||||
self.parse_name_value_directive(line, "edition", testfile)
|
||||
}
|
||||
|
||||
fn set_name_directive(&self, line: &str, directive: &str, value: &mut bool) {
|
||||
match value {
|
||||
true => {
|
||||
if self.parse_negative_name_directive(line, directive) {
|
||||
*value = false;
|
||||
}
|
||||
}
|
||||
false => {
|
||||
if self.parse_name_directive(line, directive) {
|
||||
*value = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
fn set_name_directive(&self, line: &DirectiveLine<'_>, directive: &str, value: &mut bool) {
|
||||
// If the flag is already true, don't bother looking at the directive.
|
||||
*value = *value || self.parse_name_directive(line, directive);
|
||||
}
|
||||
|
||||
fn set_name_value_directive<T>(
|
||||
&self,
|
||||
line: &str,
|
||||
line: &DirectiveLine<'_>,
|
||||
directive: &str,
|
||||
testfile: &Utf8Path,
|
||||
line_number: usize,
|
||||
value: &mut Option<T>,
|
||||
parse: impl FnOnce(String) -> T,
|
||||
) {
|
||||
if value.is_none() {
|
||||
*value =
|
||||
self.parse_name_value_directive(line, directive, testfile, line_number).map(parse);
|
||||
*value = self.parse_name_value_directive(line, directive, testfile).map(parse);
|
||||
}
|
||||
}
|
||||
|
||||
fn push_name_value_directive<T>(
|
||||
&self,
|
||||
line: &str,
|
||||
line: &DirectiveLine<'_>,
|
||||
directive: &str,
|
||||
testfile: &Utf8Path,
|
||||
line_number: usize,
|
||||
values: &mut Vec<T>,
|
||||
parse: impl FnOnce(String) -> T,
|
||||
) {
|
||||
if let Some(value) =
|
||||
self.parse_name_value_directive(line, directive, testfile, line_number).map(parse)
|
||||
{
|
||||
if let Some(value) = self.parse_name_value_directive(line, directive, testfile).map(parse) {
|
||||
values.push(value);
|
||||
}
|
||||
}
|
||||
@@ -1482,8 +1439,8 @@ pub(crate) fn make_test_description<R: Read>(
|
||||
&mut local_poisoned,
|
||||
path,
|
||||
src,
|
||||
&mut |directive @ DirectiveLine { line_number, raw_directive: ln, .. }| {
|
||||
if !directive.applies_to_test_revision(test_revision) {
|
||||
&mut |ref ln @ DirectiveLine { line_number, .. }| {
|
||||
if !ln.applies_to_test_revision(test_revision) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1507,9 +1464,9 @@ macro_rules! decision {
|
||||
decision!(cfg::handle_ignore(config, ln));
|
||||
decision!(cfg::handle_only(config, ln));
|
||||
decision!(needs::handle_needs(&cache.needs, config, ln));
|
||||
decision!(ignore_llvm(config, path, ln, line_number));
|
||||
decision!(ignore_backends(config, path, ln, line_number));
|
||||
decision!(needs_backends(config, path, ln, line_number));
|
||||
decision!(ignore_llvm(config, path, ln));
|
||||
decision!(ignore_backends(config, path, ln));
|
||||
decision!(needs_backends(config, path, ln));
|
||||
decision!(ignore_cdb(config, ln));
|
||||
decision!(ignore_gdb(config, ln));
|
||||
decision!(ignore_lldb(config, ln));
|
||||
@@ -1549,7 +1506,9 @@ macro_rules! decision {
|
||||
}
|
||||
}
|
||||
|
||||
fn ignore_cdb(config: &Config, line: &str) -> IgnoreDecision {
|
||||
fn ignore_cdb(config: &Config, line: &DirectiveLine<'_>) -> IgnoreDecision {
|
||||
let &DirectiveLine { raw_directive: line, .. } = line;
|
||||
|
||||
if config.debugger != Some(Debugger::Cdb) {
|
||||
return IgnoreDecision::Continue;
|
||||
}
|
||||
@@ -1572,7 +1531,9 @@ fn ignore_cdb(config: &Config, line: &str) -> IgnoreDecision {
|
||||
IgnoreDecision::Continue
|
||||
}
|
||||
|
||||
fn ignore_gdb(config: &Config, line: &str) -> IgnoreDecision {
|
||||
fn ignore_gdb(config: &Config, line: &DirectiveLine<'_>) -> IgnoreDecision {
|
||||
let &DirectiveLine { raw_directive: line, .. } = line;
|
||||
|
||||
if config.debugger != Some(Debugger::Gdb) {
|
||||
return IgnoreDecision::Continue;
|
||||
}
|
||||
@@ -1620,7 +1581,9 @@ fn ignore_gdb(config: &Config, line: &str) -> IgnoreDecision {
|
||||
IgnoreDecision::Continue
|
||||
}
|
||||
|
||||
fn ignore_lldb(config: &Config, line: &str) -> IgnoreDecision {
|
||||
fn ignore_lldb(config: &Config, line: &DirectiveLine<'_>) -> IgnoreDecision {
|
||||
let &DirectiveLine { raw_directive: line, .. } = line;
|
||||
|
||||
if config.debugger != Some(Debugger::Lldb) {
|
||||
return IgnoreDecision::Continue;
|
||||
}
|
||||
@@ -1642,14 +1605,9 @@ fn ignore_lldb(config: &Config, line: &str) -> IgnoreDecision {
|
||||
IgnoreDecision::Continue
|
||||
}
|
||||
|
||||
fn ignore_backends(
|
||||
config: &Config,
|
||||
path: &Utf8Path,
|
||||
line: &str,
|
||||
line_number: usize,
|
||||
) -> IgnoreDecision {
|
||||
fn ignore_backends(config: &Config, path: &Utf8Path, line: &DirectiveLine<'_>) -> IgnoreDecision {
|
||||
if let Some(backends_to_ignore) =
|
||||
config.parse_name_value_directive(line, "ignore-backends", path, line_number)
|
||||
config.parse_name_value_directive(line, "ignore-backends", path)
|
||||
{
|
||||
for backend in backends_to_ignore.split_whitespace().map(|backend| {
|
||||
match CodegenBackend::try_from(backend) {
|
||||
@@ -1669,15 +1627,8 @@ fn ignore_backends(
|
||||
IgnoreDecision::Continue
|
||||
}
|
||||
|
||||
fn needs_backends(
|
||||
config: &Config,
|
||||
path: &Utf8Path,
|
||||
line: &str,
|
||||
line_number: usize,
|
||||
) -> IgnoreDecision {
|
||||
if let Some(needed_backends) =
|
||||
config.parse_name_value_directive(line, "needs-backends", path, line_number)
|
||||
{
|
||||
fn needs_backends(config: &Config, path: &Utf8Path, line: &DirectiveLine<'_>) -> IgnoreDecision {
|
||||
if let Some(needed_backends) = config.parse_name_value_directive(line, "needs-backends", path) {
|
||||
if !needed_backends
|
||||
.split_whitespace()
|
||||
.map(|backend| match CodegenBackend::try_from(backend) {
|
||||
@@ -1699,9 +1650,9 @@ fn needs_backends(
|
||||
IgnoreDecision::Continue
|
||||
}
|
||||
|
||||
fn ignore_llvm(config: &Config, path: &Utf8Path, line: &str, line_number: usize) -> IgnoreDecision {
|
||||
fn ignore_llvm(config: &Config, path: &Utf8Path, line: &DirectiveLine<'_>) -> IgnoreDecision {
|
||||
if let Some(needed_components) =
|
||||
config.parse_name_value_directive(line, "needs-llvm-components", path, line_number)
|
||||
config.parse_name_value_directive(line, "needs-llvm-components", path)
|
||||
{
|
||||
let components: HashSet<_> = config.llvm_components.split_whitespace().collect();
|
||||
if let Some(missing_component) = needed_components
|
||||
@@ -1723,7 +1674,7 @@ fn ignore_llvm(config: &Config, path: &Utf8Path, line: &str, line_number: usize)
|
||||
// Note that these `min` versions will check for not just major versions.
|
||||
|
||||
if let Some(version_string) =
|
||||
config.parse_name_value_directive(line, "min-llvm-version", path, line_number)
|
||||
config.parse_name_value_directive(line, "min-llvm-version", path)
|
||||
{
|
||||
let min_version = extract_llvm_version(&version_string);
|
||||
// Ignore if actual version is smaller than the minimum required version.
|
||||
@@ -1735,7 +1686,7 @@ fn ignore_llvm(config: &Config, path: &Utf8Path, line: &str, line_number: usize)
|
||||
};
|
||||
}
|
||||
} else if let Some(version_string) =
|
||||
config.parse_name_value_directive(line, "max-llvm-major-version", path, line_number)
|
||||
config.parse_name_value_directive(line, "max-llvm-major-version", path)
|
||||
{
|
||||
let max_version = extract_llvm_version(&version_string);
|
||||
// Ignore if actual major version is larger than the maximum required major version.
|
||||
@@ -1749,7 +1700,7 @@ fn ignore_llvm(config: &Config, path: &Utf8Path, line: &str, line_number: usize)
|
||||
};
|
||||
}
|
||||
} else if let Some(version_string) =
|
||||
config.parse_name_value_directive(line, "min-system-llvm-version", path, line_number)
|
||||
config.parse_name_value_directive(line, "min-system-llvm-version", path)
|
||||
{
|
||||
let min_version = extract_llvm_version(&version_string);
|
||||
// Ignore if using system LLVM and actual version
|
||||
@@ -1762,7 +1713,7 @@ fn ignore_llvm(config: &Config, path: &Utf8Path, line: &str, line_number: usize)
|
||||
};
|
||||
}
|
||||
} else if let Some(version_range) =
|
||||
config.parse_name_value_directive(line, "ignore-llvm-version", path, line_number)
|
||||
config.parse_name_value_directive(line, "ignore-llvm-version", path)
|
||||
{
|
||||
// Syntax is: "ignore-llvm-version: <version1> [- <version2>]"
|
||||
let (v_min, v_max) =
|
||||
@@ -1788,7 +1739,7 @@ fn ignore_llvm(config: &Config, path: &Utf8Path, line: &str, line_number: usize)
|
||||
}
|
||||
}
|
||||
} else if let Some(version_string) =
|
||||
config.parse_name_value_directive(line, "exact-llvm-major-version", path, line_number)
|
||||
config.parse_name_value_directive(line, "exact-llvm-major-version", path)
|
||||
{
|
||||
// Syntax is "exact-llvm-major-version: <version>"
|
||||
let version = extract_llvm_version(&version_string);
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
use super::directives::{AUX_BIN, AUX_BUILD, AUX_CODEGEN_BACKEND, AUX_CRATE, PROC_MACRO};
|
||||
use crate::common::Config;
|
||||
use crate::directives::DirectiveLine;
|
||||
|
||||
/// Properties parsed from `aux-*` test directives.
|
||||
#[derive(Clone, Debug, Default)]
|
||||
@@ -45,40 +46,28 @@ pub(crate) fn all_aux_path_strings(&self) -> impl Iterator<Item = &str> {
|
||||
/// and update [`AuxProps`] accordingly.
|
||||
pub(super) fn parse_and_update_aux(
|
||||
config: &Config,
|
||||
ln: &str,
|
||||
directive_line: &DirectiveLine<'_>,
|
||||
testfile: &Utf8Path,
|
||||
line_number: usize,
|
||||
aux: &mut AuxProps,
|
||||
) {
|
||||
let &DirectiveLine { raw_directive: ln, .. } = directive_line;
|
||||
|
||||
if !(ln.starts_with("aux-") || ln.starts_with("proc-macro")) {
|
||||
return;
|
||||
}
|
||||
|
||||
config.push_name_value_directive(ln, AUX_BUILD, testfile, line_number, &mut aux.builds, |r| {
|
||||
let ln = directive_line;
|
||||
|
||||
config.push_name_value_directive(ln, AUX_BUILD, testfile, &mut aux.builds, |r| {
|
||||
r.trim().to_string()
|
||||
});
|
||||
config.push_name_value_directive(ln, AUX_BIN, testfile, line_number, &mut aux.bins, |r| {
|
||||
config
|
||||
.push_name_value_directive(ln, AUX_BIN, testfile, &mut aux.bins, |r| r.trim().to_string());
|
||||
config.push_name_value_directive(ln, AUX_CRATE, testfile, &mut aux.crates, parse_aux_crate);
|
||||
config.push_name_value_directive(ln, PROC_MACRO, testfile, &mut aux.proc_macros, |r| {
|
||||
r.trim().to_string()
|
||||
});
|
||||
config.push_name_value_directive(
|
||||
ln,
|
||||
AUX_CRATE,
|
||||
testfile,
|
||||
line_number,
|
||||
&mut aux.crates,
|
||||
parse_aux_crate,
|
||||
);
|
||||
config.push_name_value_directive(
|
||||
ln,
|
||||
PROC_MACRO,
|
||||
testfile,
|
||||
line_number,
|
||||
&mut aux.proc_macros,
|
||||
|r| r.trim().to_string(),
|
||||
);
|
||||
if let Some(r) =
|
||||
config.parse_name_value_directive(ln, AUX_CODEGEN_BACKEND, testfile, line_number)
|
||||
{
|
||||
if let Some(r) = config.parse_name_value_directive(ln, AUX_CODEGEN_BACKEND, testfile) {
|
||||
aux.codegen_backend = Some(r.trim().to_owned());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
use std::collections::HashSet;
|
||||
|
||||
use crate::common::{CompareMode, Config, Debugger};
|
||||
use crate::directives::IgnoreDecision;
|
||||
use crate::directives::{DirectiveLine, IgnoreDecision};
|
||||
|
||||
const EXTRA_ARCHS: &[&str] = &["spirv"];
|
||||
|
||||
pub(super) fn handle_ignore(config: &Config, line: &str) -> IgnoreDecision {
|
||||
pub(super) fn handle_ignore(config: &Config, line: &DirectiveLine<'_>) -> IgnoreDecision {
|
||||
let parsed = parse_cfg_name_directive(config, line, "ignore");
|
||||
let &DirectiveLine { raw_directive: line, .. } = line;
|
||||
|
||||
match parsed.outcome {
|
||||
MatchOutcome::NoMatch => IgnoreDecision::Continue,
|
||||
MatchOutcome::Match => IgnoreDecision::Ignore {
|
||||
@@ -21,8 +23,10 @@ pub(super) fn handle_ignore(config: &Config, line: &str) -> IgnoreDecision {
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn handle_only(config: &Config, line: &str) -> IgnoreDecision {
|
||||
pub(super) fn handle_only(config: &Config, line: &DirectiveLine<'_>) -> IgnoreDecision {
|
||||
let parsed = parse_cfg_name_directive(config, line, "only");
|
||||
let &DirectiveLine { raw_directive: line, .. } = line;
|
||||
|
||||
match parsed.outcome {
|
||||
MatchOutcome::Match => IgnoreDecision::Continue,
|
||||
MatchOutcome::NoMatch => IgnoreDecision::Ignore {
|
||||
@@ -43,9 +47,11 @@ pub(super) fn handle_only(config: &Config, line: &str) -> IgnoreDecision {
|
||||
/// or `only-windows`.
|
||||
fn parse_cfg_name_directive<'a>(
|
||||
config: &Config,
|
||||
line: &'a str,
|
||||
line: &'a DirectiveLine<'a>,
|
||||
prefix: &str,
|
||||
) -> ParsedNameDirective<'a> {
|
||||
let &DirectiveLine { raw_directive: line, .. } = line;
|
||||
|
||||
if !line.as_bytes().starts_with(prefix.as_bytes()) {
|
||||
return ParsedNameDirective::not_a_directive();
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
use crate::common::{Config, KNOWN_CRATE_TYPES, KNOWN_TARGET_HAS_ATOMIC_WIDTHS, Sanitizer};
|
||||
use crate::directives::{IgnoreDecision, llvm_has_libzstd};
|
||||
use crate::directives::{DirectiveLine, IgnoreDecision, llvm_has_libzstd};
|
||||
|
||||
pub(super) fn handle_needs(
|
||||
cache: &CachedNeedsConditions,
|
||||
config: &Config,
|
||||
ln: &str,
|
||||
ln: &DirectiveLine<'_>,
|
||||
) -> IgnoreDecision {
|
||||
// Note that we intentionally still put the needs- prefix here to make the file show up when
|
||||
// grepping for a directive name, even though we could technically strip that.
|
||||
@@ -181,6 +181,8 @@ pub(super) fn handle_needs(
|
||||
},
|
||||
];
|
||||
|
||||
let &DirectiveLine { raw_directive: ln, .. } = ln;
|
||||
|
||||
let (name, rest) = match ln.split_once([':', ' ']) {
|
||||
Some((name, rest)) => (name, Some(rest)),
|
||||
None => (ln, None),
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
|
||||
use camino::{Utf8Path, Utf8PathBuf};
|
||||
|
||||
use crate::common::Config;
|
||||
use crate::runtest::ProcRes;
|
||||
|
||||
/// Representation of information to invoke a debugger and check its output
|
||||
@@ -20,11 +19,7 @@ pub(super) struct DebuggerCommands {
|
||||
}
|
||||
|
||||
impl DebuggerCommands {
|
||||
pub fn parse_from(
|
||||
file: &Utf8Path,
|
||||
config: &Config,
|
||||
debugger_prefix: &str,
|
||||
) -> Result<Self, String> {
|
||||
pub fn parse_from(file: &Utf8Path, debugger_prefix: &str) -> Result<Self, String> {
|
||||
let command_directive = format!("{debugger_prefix}-command");
|
||||
let check_directive = format!("{debugger_prefix}-check");
|
||||
|
||||
@@ -47,14 +42,10 @@ pub fn parse_from(
|
||||
continue;
|
||||
};
|
||||
|
||||
if let Some(command) =
|
||||
config.parse_name_value_directive(&line, &command_directive, file, line_no)
|
||||
{
|
||||
if let Some(command) = parse_name_value(&line, &command_directive) {
|
||||
commands.push(command);
|
||||
}
|
||||
if let Some(pattern) =
|
||||
config.parse_name_value_directive(&line, &check_directive, file, line_no)
|
||||
{
|
||||
if let Some(pattern) = parse_name_value(&line, &check_directive) {
|
||||
check_lines.push((line_no, pattern));
|
||||
}
|
||||
}
|
||||
@@ -114,6 +105,18 @@ pub fn check_output(&self, debugger_run_result: &ProcRes) -> Result<(), String>
|
||||
}
|
||||
}
|
||||
|
||||
/// Split off from the main `parse_name_value_directive`, so that improvements
|
||||
/// to directive handling aren't held back by debuginfo test commands.
|
||||
fn parse_name_value(line: &str, name: &str) -> Option<String> {
|
||||
if let Some(after_name) = line.strip_prefix(name)
|
||||
&& let Some(value) = after_name.strip_prefix(':')
|
||||
{
|
||||
Some(value.to_owned())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Check that the pattern in `check_line` applies to `line`. Returns `true` if they do match.
|
||||
fn check_single_line(line: &str, check_line: &str) -> bool {
|
||||
// Allow check lines to leave parts unspecified (e.g., uninitialized
|
||||
|
||||
@@ -59,7 +59,7 @@ fn run_debuginfo_cdb_test_no_opt(&self) {
|
||||
}
|
||||
|
||||
// Parse debugger commands etc from test files
|
||||
let dbg_cmds = DebuggerCommands::parse_from(&self.testpaths.file, self.config, "cdb")
|
||||
let dbg_cmds = DebuggerCommands::parse_from(&self.testpaths.file, "cdb")
|
||||
.unwrap_or_else(|e| self.fatal(&e));
|
||||
|
||||
// https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/debugger-commands
|
||||
@@ -130,7 +130,7 @@ fn run_debuginfo_gdb_test(&self) {
|
||||
}
|
||||
|
||||
fn run_debuginfo_gdb_test_no_opt(&self) {
|
||||
let dbg_cmds = DebuggerCommands::parse_from(&self.testpaths.file, self.config, "gdb")
|
||||
let dbg_cmds = DebuggerCommands::parse_from(&self.testpaths.file, "gdb")
|
||||
.unwrap_or_else(|e| self.fatal(&e));
|
||||
let mut cmds = dbg_cmds.commands.join("\n");
|
||||
|
||||
@@ -397,7 +397,7 @@ fn run_debuginfo_lldb_test_no_opt(&self) {
|
||||
}
|
||||
|
||||
// Parse debugger commands etc from test files
|
||||
let dbg_cmds = DebuggerCommands::parse_from(&self.testpaths.file, self.config, "lldb")
|
||||
let dbg_cmds = DebuggerCommands::parse_from(&self.testpaths.file, "lldb")
|
||||
.unwrap_or_else(|e| self.fatal(&e));
|
||||
|
||||
// Write debugger script:
|
||||
|
||||
Reference in New Issue
Block a user