Home Explore Blog CI



rustc

9th chunk of `src/tests/directives.md`
96c11c15ecc76183f7f89a02f6ea7b7b66a37012927e003e0000000100000b6a
To add a new directive property:

1. Look for the `pub struct TestProps` declaration in
   [`src/tools/compiletest/src/header.rs`] and add the new public property to
   the end of the declaration.
2. Look for the `impl TestProps` implementation block immediately following the
   struct declaration and initialize the new property to its default value.

### Adding a new directive parser

When `compiletest` encounters a test file, it parses the file a line at a time
by calling every parser defined in the `Config` struct's implementation block,
also in [`src/tools/compiletest/src/header.rs`] (note that the `Config` struct's
declaration block is found in [`src/tools/compiletest/src/common.rs`]).
`TestProps`'s `load_from()` method will try passing the current line of text to
each parser, which, in turn typically checks to see if the line begins with a
particular commented (`//@`) directive such as `//@ must-compile-successfully`
or `//@ failure-status`. Whitespace after the comment marker is optional.

Parsers will override a given directive property's default value merely by being
specified in the test file as a directive or by having a parameter value
specified in the test file, depending on the directive.

Parsers defined in `impl Config` are typically named `parse_<directive-name>`
(note kebab-case `<directive-command>` transformed to snake-case
`<directive_command>`). `impl Config` also defines several 'low-level' parsers
which make it simple to parse common patterns like simple presence or not
(`parse_name_directive()`), `directive:parameter(s)`
(`parse_name_value_directive()`), optional parsing only if a particular `cfg`
attribute is defined (`has_cfg_prefix()`) and many more. The low-level parsers
are found near the end of the `impl Config` block; be sure to look through them
and their associated parsers immediately above to see how they are used to avoid
writing additional parsing code unnecessarily.

As a concrete example, here is the implementation for the
`parse_failure_status()` parser, in [`src/tools/compiletest/src/header.rs`]:

```diff
@@ -232,6 +232,7 @@ pub struct TestProps {
     // customized normalization rules
     pub normalize_stdout: Vec<(String, String)>,
     pub normalize_stderr: Vec<(String, String)>,
+    pub failure_status: i32,
 }

 impl TestProps {
@@ -260,6 +261,7 @@ impl TestProps {
             run_pass: false,
             normalize_stdout: vec![],
             normalize_stderr: vec![],
+            failure_status: 101,
         }
     }

@@ -383,6 +385,10 @@ impl TestProps {
             if let Some(rule) = config.parse_custom_normalization(ln, "normalize-stderr") {
                 self.normalize_stderr.push(rule);
             }
+
+            if let Some(code) = config.parse_failure_status(ln) {
+                self.failure_status = code;
+            }
         });

         for key in &["RUST_TEST_NOCAPTURE", "RUST_TEST_THREADS"] {

Title: Adding Directive Properties and Parsers in Compiletest
Summary
This section describes how to add a new directive property to the `TestProps` struct in `src/tools/compiletest/src/header.rs` and how to add a new directive parser within the `Config` struct's implementation. It explains that the `load_from()` method of `TestProps` passes each line of a test file to the parsers, which check for specific commented directives (e.g., `//@ must-compile-successfully`). It also details how parsers can override directive properties and provides an example of the `parse_failure_status()` parser to illustrate the implementation process.