Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 31 additions & 1 deletion src/tools/compiletest/src/directives.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,36 @@ mod needs;
#[cfg(test)]
mod tests;

/// A line number in a file. Internally the first line has index 1.
/// If it is 0 it means "no specific line" (used e.g. for implied directives).
/// When displayed, the first line is 1.
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub(crate) struct LineNumber(usize);

impl LineNumber {
/// Create a LineNumber from a zero-based line index. I.e. if `zero_based`
/// is `0` it means "the first line".
pub(crate) fn from_zero_based(zero_based: usize) -> Self {
// Ensure to panic on overflow.
LineNumber(zero_based.strict_add(1))
}

pub(crate) fn from_one_based(one_based: usize) -> LineNumber {
assert!(one_based > 0);
LineNumber(one_based)
}

pub(crate) fn none() -> LineNumber {
LineNumber(0)
}
}

impl std::fmt::Display for LineNumber {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}

pub struct DirectivesCache {
/// "Conditions" used by `ignore-*` and `only-*` directives, prepared in
/// advance so that they don't have to be evaluated repeatedly.
Expand Down Expand Up @@ -591,7 +621,7 @@ fn iter_directives(
];
// Process the extra implied directives, with a dummy line number of 0.
for directive_str in extra_directives {
let directive_line = line_directive(testfile, 0, directive_str)
let directive_line = line_directive(testfile, LineNumber::none(), directive_str)
.unwrap_or_else(|| panic!("bad extra-directive line: {directive_str:?}"));
it(&directive_line);
}
Expand Down
3 changes: 3 additions & 0 deletions src/tools/compiletest/src/directives/file.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use camino::Utf8Path;

use crate::directives::LineNumber;
use crate::directives::line::{DirectiveLine, line_directive};

pub(crate) struct FileDirectives<'a> {
Expand All @@ -12,6 +13,8 @@ impl<'a> FileDirectives<'a> {
let mut lines = vec![];

for (line_number, ln) in (1..).zip(file_contents.lines()) {
let line_number = LineNumber::from_one_based(line_number);

let ln = ln.trim();

if let Some(directive_line) = line_directive(path, line_number, ln) {
Expand Down
6 changes: 4 additions & 2 deletions src/tools/compiletest/src/directives/line.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@ use std::fmt;

use camino::Utf8Path;

use crate::directives::LineNumber;

const COMPILETEST_DIRECTIVE_PREFIX: &str = "//@";

/// If the given line begins with the appropriate comment prefix for a directive,
/// returns a struct containing various parts of the directive.
pub(crate) fn line_directive<'a>(
file_path: &'a Utf8Path,
line_number: usize,
line_number: LineNumber,
original_line: &'a str,
) -> Option<DirectiveLine<'a>> {
// Ignore lines that don't start with the comment prefix.
Expand Down Expand Up @@ -60,7 +62,7 @@ pub(crate) struct DirectiveLine<'a> {
/// Mostly used for diagnostics, but some directives (e.g. `//@ pp-exact`)
/// also use it to compute a value based on the filename.
pub(crate) file_path: &'a Utf8Path,
pub(crate) line_number: usize,
pub(crate) line_number: LineNumber,

/// Some test directives start with a revision name in square brackets
/// (e.g. `[foo]`), and only apply to that revision of the test.
Expand Down
7 changes: 4 additions & 3 deletions src/tools/compiletest/src/directives/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ use semver::Version;
use crate::common::{Config, Debugger, TestMode};
use crate::directives::{
self, AuxProps, DIRECTIVE_HANDLERS_MAP, DirectivesCache, EarlyProps, Edition, EditionRange,
FileDirectives, KNOWN_DIRECTIVE_NAMES_SET, extract_llvm_version, extract_version_range,
line_directive, parse_edition, parse_normalize_rule,
FileDirectives, KNOWN_DIRECTIVE_NAMES_SET, LineNumber, extract_llvm_version,
extract_version_range, line_directive, parse_edition, parse_normalize_rule,
};
use crate::executor::{CollectedTestDesc, ShouldFail};

Expand Down Expand Up @@ -1000,7 +1000,8 @@ fn parse_edition_range(line: &str) -> Option<EditionRange> {
let config = cfg().build();

let line_with_comment = format!("//@ {line}");
let line = line_directive(Utf8Path::new("tmp.rs"), 0, &line_with_comment).unwrap();
let line =
line_directive(Utf8Path::new("tmp.rs"), LineNumber::none(), &line_with_comment).unwrap();

super::parse_edition_range(&config, &line)
}
Expand Down
17 changes: 8 additions & 9 deletions src/tools/compiletest/src/runtest/debugger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,17 @@ use std::io::{BufRead, BufReader};

use camino::{Utf8Path, Utf8PathBuf};

use crate::directives::LineNumber;
use crate::runtest::ProcRes;

/// Representation of information to invoke a debugger and check its output
pub(super) struct DebuggerCommands {
/// Commands for the debuuger
pub commands: Vec<String>,
/// Lines to insert breakpoints at
pub breakpoint_lines: Vec<usize>,
pub breakpoint_lines: Vec<LineNumber>,
/// Contains the source line number to check and the line itself
check_lines: Vec<(usize, String)>,
check_lines: Vec<(LineNumber, String)>,
/// Source file name
file: Utf8PathBuf,
}
Expand All @@ -26,15 +27,14 @@ impl DebuggerCommands {
let mut breakpoint_lines = vec![];
let mut commands = vec![];
let mut check_lines = vec![];
let mut counter = 0;
let reader = BufReader::new(File::open(file.as_std_path()).unwrap());
for (line_no, line) in reader.lines().enumerate() {
counter += 1;
let line = line.map_err(|e| format!("Error while parsing debugger commands: {}", e))?;
let line_number = LineNumber::from_zero_based(line_no);

// Breakpoints appear on lines with actual code, typically at the end of the line.
if line.contains("#break") {
breakpoint_lines.push(counter);
breakpoint_lines.push(line_number);
continue;
}

Expand All @@ -46,7 +46,7 @@ impl DebuggerCommands {
commands.push(command);
}
if let Some(pattern) = parse_name_value(&line, &check_directive) {
check_lines.push((line_no, pattern));
check_lines.push((line_number, pattern));
}
}

Expand Down Expand Up @@ -88,15 +88,14 @@ impl DebuggerCommands {
);

for (src_lineno, err_line) in missing {
write!(msg, "\n ({fname}:{num}) `{err_line}`", num = src_lineno + 1).unwrap();
write!(msg, "\n ({fname}:{src_lineno}) `{err_line}`").unwrap();
}

if !found.is_empty() {
let init = "\nthe following subset of check directive(s) was found successfully:";
msg.push_str(init);
for (src_lineno, found_line) in found {
write!(msg, "\n ({fname}:{num}) `{found_line}`", num = src_lineno + 1)
.unwrap();
write!(msg, "\n ({fname}:{src_lineno}) `{found_line}`").unwrap();
}
}

Expand Down
Loading