test(script): Switch frontmatter tests to end-to-end

This will make it easier to validate error improvements I'm working on
as well as make it easier to update from rust-lang/rust
This commit is contained in:
Ed Page 2025-08-29 15:25:19 -05:00
parent 79b6548c13
commit 57c97cc190
64 changed files with 1368 additions and 583 deletions

View File

@ -269,589 +269,6 @@ mod test_expand {
}
}
#[test]
fn rustc_dot_in_infostring_leading() {
// We don't validate infostrings besides `info == "cargo"`
assert_source(
r#"---.toml
//~^ ERROR: invalid infostring for frontmatter
---
// infostrings cannot have leading dots
fn main() {}
"#,
str![[r#"
shebang: None
info: ".toml"
frontmatter: "//~^ ERROR: invalid infostring for frontmatter\n"
content: "\n// infostrings cannot have leading dots\n\nfn main() {}\n"
"#]],
);
}
#[test]
fn rustc_dot_in_infostring_non_leading() {
assert_source(
r#"---Cargo.toml
---
// infostrings can contain dots as long as a dot isn't the first character.
//@ check-pass
fn main() {}
"#,
str![[r#"
shebang: None
info: "Cargo.toml"
frontmatter: ""
content: "\n// infostrings can contain dots as long as a dot isn't the first character.\n//@ check-pass\n\nfn main() {}\n"
"#]],
);
}
#[test]
fn rustc_escape() {
assert_source(
r#"----
---
----
//@ check-pass
// This test checks that longer dashes for opening and closing can be used to
// escape sequences such as three dashes inside the frontmatter block.
fn main() {}
"#,
str![[r#"
shebang: None
info: None
frontmatter: "\n---\n\n"
content: "\n//@ check-pass\n\n// This test checks that longer dashes for opening and closing can be used to\n// escape sequences such as three dashes inside the frontmatter block.\n\nfn main() {}\n"
"#]],
);
}
#[test]
fn rustc_extra_after_end() {
assert_err(
ScriptSource::parse(
r#"---
---cargo
//~^ ERROR: extra characters after frontmatter close are not allowed
fn main() {}
"#,
),
str!["trailing characters found after frontmatter close"],
);
}
#[test]
fn rustc_frontmatter_after_tokens() {
// Deferred to rustc since this requires knowledge of Rust grammar
assert_source(
r#"#![feature(frontmatter)]
---
//~^ ERROR: expected item, found `-`
// FIXME(frontmatter): make this diagnostic better
---
// frontmatters must be at the start of a file. This test ensures that.
fn main() {}
"#,
str![[r##"
shebang: None
info: None
frontmatter: None
content: "#![feature(frontmatter)]\n\n---\n//~^ ERROR: expected item, found `-`\n// FIXME(frontmatter): make this diagnostic better\n---\n\n// frontmatters must be at the start of a file. This test ensures that.\n\nfn main() {}\n"
"##]],
);
}
#[test]
fn rustc_frontmatter_inner_hyphens_1() {
assert_source(
r#"---
x ---🚧
---
// Regression test for #141483
//@check-pass
#![feature(frontmatter)]
fn main() {}
"#,
str![[r#"
shebang: None
info: None
frontmatter: "x ---🚧\u{fe0f}\n"
content: "\n// Regression test for #141483\n//@check-pass\n\n#![feature(frontmatter)]\n\nfn main() {}\n"
"#]],
);
}
#[test]
fn rustc_frontmatter_inner_hyphens_2() {
assert_source(
r#"---
x ---y
---
// Test that hypens are allowed inside frontmatters if there is some
// non-whitespace character preceding them.
//@check-pass
#![feature(frontmatter)]
fn main() {}
"#,
str![[r#"
shebang: None
info: None
frontmatter: "x ---y\n"
content: "\n// Test that hypens are allowed inside frontmatters if there is some\n// non-whitespace character preceding them.\n//@check-pass\n\n#![feature(frontmatter)]\n\nfn main() {}\n"
"#]],
);
}
#[test]
fn rustc_frontmatter_non_lexible_tokens() {
assert_source(
r#"---uwu
🏳
---
//@ check-pass
// check that frontmatter blocks can have tokens that are otherwise not accepted by
// the lexer as Rust code.
fn main() {}
"#,
str![[r#"
shebang: None
info: "uwu"
frontmatter: "🏳\u{fe0f}\u{200d}\u{fe0f}\n"
content: "\n//@ check-pass\n\n// check that frontmatter blocks can have tokens that are otherwise not accepted by\n// the lexer as Rust code.\n\nfn main() {}\n"
"#]],
);
}
#[test]
fn rustc_frontmatter_whitespace_1() {
// Deferred to rustc since this requires knowledge of Rust grammar
assert_source(
r#" ---
//~^ ERROR: invalid preceding whitespace for frontmatter opening
---
//~^ ERROR: invalid preceding whitespace for frontmatter close
// check that whitespaces should not precede the frontmatter opening or close.
fn main() {}
"#,
str![[r#"
shebang: None
info: None
frontmatter: None
content: " ---\n//~^ ERROR: invalid preceding whitespace for frontmatter opening\n ---\n//~^ ERROR: invalid preceding whitespace for frontmatter close\n\n// check that whitespaces should not precede the frontmatter opening or close.\n\nfn main() {}\n"
"#]],
);
}
#[test]
fn rustc_frontmatter_whitespace_2() {
assert_err(
ScriptSource::parse(
r#"---cargo
//@ compile-flags: --crate-type lib
fn foo(x: i32) -> i32 {
---x
//~^ ERROR: invalid preceding whitespace for frontmatter close
//~| ERROR: extra characters after frontmatter close are not allowed
}
//~^ ERROR: unexpected closing delimiter: `}`
// this test is for the weird case that valid Rust code can have three dashes
// within them and get treated as a frontmatter close.
"#,
),
str!["no closing `---` found for frontmatter"],
);
}
#[test]
fn rustc_frontmatter_whitespace_3() {
assert_source(
r#"
---cargo
---
// please note the whitespace characters after the first four lines.
// This ensures that we accept whitespaces before the frontmatter, after
// the frontmatter opening and the frontmatter close.
//@ check-pass
// ignore-tidy-end-whitespace
// ignore-tidy-leading-newlines
fn main() {}
"#,
str![[r#"
shebang: None
info: "cargo"
frontmatter: ""
content: "\n// please note the whitespace characters after the first four lines.\n// This ensures that we accept whitespaces before the frontmatter, after\n// the frontmatter opening and the frontmatter close.\n\n//@ check-pass\n// ignore-tidy-end-whitespace\n// ignore-tidy-leading-newlines\n\nfn main() {}\n"
"#]],
);
}
#[test]
fn rustc_frontmatter_whitespace_4() {
assert_source(
r#"--- cargo
---
//@ check-pass
// A frontmatter infostring can have leading whitespace.
fn main() {}
"#,
str![[r#"
shebang: None
info: "cargo"
frontmatter: ""
content: "\n//@ check-pass\n// A frontmatter infostring can have leading whitespace.\n\nfn main() {}\n"
"#]],
);
}
#[test]
fn rustc_hyphen_in_infostring_leading() {
// We don't validate infostrings besides `info == "cargo"`
assert_source(
r#"--- -toml
//~^ ERROR: invalid infostring for frontmatter
---
// infostrings cannot have leading hyphens
#![feature(frontmatter)]
fn main() {}
"#,
str![[r#"
shebang: None
info: "-toml"
frontmatter: "//~^ ERROR: invalid infostring for frontmatter\n"
content: "\n// infostrings cannot have leading hyphens\n\n#![feature(frontmatter)]\n\nfn main() {}\n"
"#]],
);
}
#[test]
fn rustc_hyphen_in_infostring_non_leading() {
assert_source(
r#"--- Cargo-toml
---
// infostrings can contain hyphens as long as a hyphen isn't the first character.
//@ check-pass
#![feature(frontmatter)]
fn main() {}
"#,
str![[r#"
shebang: None
info: "Cargo-toml"
frontmatter: ""
content: "\n// infostrings can contain hyphens as long as a hyphen isn't the first character.\n//@ check-pass\n\n#![feature(frontmatter)]\n\nfn main() {}\n"
"#]],
);
}
#[test]
fn rustc_included_frontmatter() {
// Deferred to rustc since this requires knowledge of Rust grammar
assert_source(
r#"#![feature(frontmatter)]
//@ check-pass
include!("auxiliary/lib.rs");
// auxiliary/lib.rs contains a frontmatter. Ensure that we can use them in an
// `include!` macro.
fn main() {
foo(1);
}
"#,
str![[r##"
shebang: None
info: None
frontmatter: None
content: "#![feature(frontmatter)]\n\n//@ check-pass\n\ninclude!(\"auxiliary/lib.rs\");\n\n// auxiliary/lib.rs contains a frontmatter. Ensure that we can use them in an\n// `include!` macro.\n\nfn main() {\n foo(1);\n}\n"
"##]],
);
}
#[test]
fn rustc_infostring_fail() {
// We don't validate infostrings besides `info == "cargo"`
assert_source(
r#"
---cargo,clippy
//~^ ERROR: invalid infostring for frontmatter
---
// infostrings can only be a single identifier.
fn main() {}
"#,
str![[r#"
shebang: None
info: "cargo,clippy"
frontmatter: "//~^ ERROR: invalid infostring for frontmatter\n"
content: "\n// infostrings can only be a single identifier.\n\nfn main() {}\n"
"#]],
);
}
#[test]
fn rustc_mismatch_1() {
assert_err(
ScriptSource::parse(
r#"---cargo
//~^ ERROR: frontmatter close does not match the opening
----
// there must be the same number of dashes for both the opening and the close
// of the frontmatter.
fn main() {}
"#,
),
str!["trailing characters found after frontmatter close"],
);
}
#[test]
fn rustc_mismatch_2() {
assert_err(
ScriptSource::parse(
r#"----cargo
//~^ ERROR: frontmatter close does not match the opening
---cargo
//~^ ERROR: extra characters after frontmatter close are not allowed
fn main() {}
"#,
),
str!["no closing `----` found for frontmatter"],
);
}
#[test]
fn rustc_multifrontmatter_2() {
// This should be valid, bug on rustc's side, see rust-lang/rust#141367
assert_source(
r#"---
---
//~^ ERROR: invalid preceding whitespace for frontmatter close
---
//~^ ERROR: expected item, found `-`
// FIXME(frontmatter): make this diagnostic better
---
fn main() {}
"#,
str![[r#"
shebang: None
info: None
frontmatter: " ---\n//~^ ERROR: invalid preceding whitespace for frontmatter close\n\n ---\n//~^ ERROR: expected item, found `-`\n// FIXME(frontmatter): make this diagnostic better\n"
content: "\nfn main() {}\n"
"#]],
);
}
#[test]
fn rustc_multifrontmatter() {
assert_err(
ScriptSource::parse(
r#"---
---
---
//~^ ERROR: expected item, found `-`
// FIXME(frontmatter): make this diagnostic better
---
// test that we do not parse another frontmatter block after the first one.
fn main() {}
"#,
),
str!["only one frontmatter is supported"],
);
}
#[test]
fn rustc_shebang() {
assert_source(
r#"#!/usr/bin/env -S cargo -Zscript
---
[dependencies]
clap = "4"
---
//@ check-pass
// Shebangs on a file can precede a frontmatter.
fn main () {}
"#,
str![[r##"
shebang: "#!/usr/bin/env -S cargo -Zscript\n"
info: None
frontmatter: "[dependencies]\nclap = \"4\"\n"
content: "\n//@ check-pass\n\n// Shebangs on a file can precede a frontmatter.\n\nfn main () {}\n"
"##]],
);
}
#[test]
fn rustc_unclosed_1() {
assert_err(
ScriptSource::parse(
r#"----cargo
//~^ ERROR: unclosed frontmatter
// This test checks that the #! characters can help us recover a frontmatter
// close. There should not be a "missing `main` function" error as the rest
// are properly parsed.
fn main() {}
"#,
),
str!["no closing `----` found for frontmatter"],
);
}
#[test]
fn rustc_unclosed_2() {
assert_err(
ScriptSource::parse(
r#"----cargo
//~^ ERROR: unclosed frontmatter
//~| ERROR: frontmatters are experimental
//@ compile-flags: --crate-type lib
// Leading whitespace on the feature line prevents recovery. However
// the dashes quoted will not be used for recovery and the entire file
// should be treated as within the frontmatter block.
fn foo() -> &str {
"----"
}
"#,
),
str!["no closing `----` found for frontmatter"],
);
}
#[test]
fn rustc_unclosed_3() {
assert_err(
ScriptSource::parse(
r#"----cargo
//~^ ERROR: frontmatter close does not match the opening
//@ compile-flags: --crate-type lib
// Unfortunate recovery situation. Not really preventable with improving the
// recovery strategy, but this type of code is rare enough already.
fn foo(x: i32) -> i32 {
---x
//~^ ERROR: invalid preceding whitespace for frontmatter close
//~| ERROR: extra characters after frontmatter close are not allowed
}
//~^ ERROR: unexpected closing delimiter: `}`
"#,
),
str!["no closing `----` found for frontmatter"],
);
}
#[test]
fn rustc_unclosed_4() {
assert_err(
ScriptSource::parse(
r#"
----cargo
//~^ ERROR: unclosed frontmatter
//! Similarly, a module-level content should allow for recovery as well (as
//! per unclosed-1.rs)
fn main() {}
"#,
),
str!["no closing `----` found for frontmatter"],
);
}
#[test]
fn rustc_unclosed_5() {
assert_err(
ScriptSource::parse(
r#"----cargo
//~^ ERROR: unclosed frontmatter
//~| ERROR: frontmatters are experimental
// Similarly, a use statement should allow for recovery as well (as
// per unclosed-1.rs)
use std::env;
fn main() {}
"#,
),
str!["no closing `----` found for frontmatter"],
);
}
#[test]
fn split_default() {
assert_source(

View File

@ -1 +1,2 @@
mod cargo;
mod rustc;

View File

@ -0,0 +1,415 @@
use std::collections::BTreeMap;
use snapbox::assert_data_eq;
use crate::prelude::*;
#[test]
fn ensure_all_fixtures_have_tests() {
let mut code_gen_divider = "//".to_owned();
code_gen_divider.push_str(" START CODE GENERATION");
let self_path = snapbox::utils::current_rs!();
let self_source = std::fs::read_to_string(&self_path).unwrap();
let (header, _) = self_source
.split_once(&code_gen_divider)
.expect("code-gen divider is present");
let header = header.trim();
let fixture_root = snapbox::utils::current_dir!().join("rustc_fixtures");
let mut fixtures = BTreeMap::new();
for entry in std::fs::read_dir(fixture_root).unwrap() {
let entry = entry.unwrap();
let path = entry.path();
let fn_name = file_to_fn(&path);
fixtures
.entry(fn_name.clone())
.or_insert_with(|| Fixture::new(fn_name))
.add_path(path);
}
let fixtures = fixtures
.into_values()
.filter(Fixture::is_valid)
.map(|f| f.to_string())
.collect::<String>();
let actual = format!(
"{header}
{code_gen_divider}
{fixtures}"
);
assert_data_eq!(actual, snapbox::Data::read_from(&self_path, None).raw());
}
fn file_to_fn(path: &std::path::Path) -> String {
let name = path.file_stem().unwrap().to_str().unwrap();
name.replace("-", "_")
}
fn sanitize_path(path: &std::path::Path) -> String {
path.strip_prefix(env!("CARGO_MANIFEST_DIR"))
.unwrap()
.as_os_str()
.to_string_lossy()
.replace("\\", "/")
}
struct Fixture {
fn_name: String,
input: std::path::PathBuf,
output: Option<std::path::PathBuf>,
}
impl Fixture {
fn new(fn_name: String) -> Self {
Self {
fn_name,
input: Default::default(),
output: Default::default(),
}
}
fn is_valid(&self) -> bool {
!self.input.as_os_str().is_empty()
}
fn add_path(&mut self, path: std::path::PathBuf) {
if path.extension().map(|ext| ext.to_str().unwrap()) == Some("rs") {
assert!(
self.input.as_os_str().is_empty(),
"similarly named fixtures:/n{}/n{}",
self.input.display(),
path.display()
);
self.input = path;
} else {
assert!(
self.output.is_none(),
"conflicting assertions:/n{}/n{}",
self.output.as_ref().unwrap().display(),
path.display()
);
self.output = Some(path);
}
}
}
impl std::fmt::Display for Fixture {
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let fn_name = &self.fn_name;
let fixture_path = sanitize_path(&self.input);
match self
.output
.as_ref()
.map(|path| path.extension().unwrap().to_str().unwrap())
{
Some("stderr") => {
let assertion_path = sanitize_path(self.output.as_ref().unwrap());
write!(
fmt,
r#"
#[cargo_test(nightly, reason = "-Zscript is unstable")]
#[rustfmt::skip] // code-generated
fn {fn_name}() {{
let fixture_path = {fixture_path:?};
let assertion_path = {assertion_path:?};
assert_failure(fixture_path, assertion_path);
}}
"#
)
}
Some("stdout") | None => {
let mut backup_path = self.input.clone();
backup_path.set_extension("stdout");
let assertion_path = sanitize_path(self.output.as_ref().unwrap_or(&backup_path));
write!(
fmt,
r#"
#[cargo_test(nightly, reason = "-Zscript is unstable")]
#[rustfmt::skip] // code-generated
fn {fn_name}() {{
let fixture_path = {fixture_path:?};
let assertion_path = {assertion_path:?};
assert_success(fixture_path, assertion_path);
}}
"#
)
}
Some(_) => {
panic!(
"unsupported assertiong: {}",
self.output.as_ref().unwrap().display()
)
}
}
}
}
#[track_caller]
fn assert_success(fixture_path: &str, assertion_path: &str) {
let p = cargo_test_support::project()
.file("script", &std::fs::read_to_string(fixture_path).unwrap())
.build();
// `read-manifest` to validate frontmatter content without processing deps, compiling
p.cargo("-Zscript read-manifest --manifest-path script")
.masquerade_as_nightly_cargo(&["script"])
.with_stdout_data(snapbox::Data::read_from(
std::path::Path::new(assertion_path),
Some(snapbox::data::DataFormat::Json),
))
.run();
}
#[track_caller]
fn assert_failure(fixture_path: &str, assertion_path: &str) {
let p = cargo_test_support::project()
.file("script", &std::fs::read_to_string(fixture_path).unwrap())
.build();
// `read-manifest` to validate frontmatter content without processing deps, compiling
p.cargo("-Zscript read-manifest --manifest-path script")
.masquerade_as_nightly_cargo(&["script"])
.with_status(101)
.with_stderr_data(snapbox::Data::read_from(
std::path::Path::new(assertion_path),
None,
))
.run();
}
// START CODE GENERATION
#[cargo_test(nightly, reason = "-Zscript is unstable")]
#[rustfmt::skip] // code-generated
fn dot_in_infostring_leading() {
let fixture_path = "tests/testsuite/script/rustc_fixtures/dot-in-infostring-leading.rs";
let assertion_path = "tests/testsuite/script/rustc_fixtures/dot-in-infostring-leading.stderr";
assert_failure(fixture_path, assertion_path);
}
#[cargo_test(nightly, reason = "-Zscript is unstable")]
#[rustfmt::skip] // code-generated
fn dot_in_infostring_non_leading() {
let fixture_path = "tests/testsuite/script/rustc_fixtures/dot-in-infostring-non-leading.rs";
let assertion_path = "tests/testsuite/script/rustc_fixtures/dot-in-infostring-non-leading.stderr";
assert_failure(fixture_path, assertion_path);
}
#[cargo_test(nightly, reason = "-Zscript is unstable")]
#[rustfmt::skip] // code-generated
fn escape() {
let fixture_path = "tests/testsuite/script/rustc_fixtures/escape.rs";
let assertion_path = "tests/testsuite/script/rustc_fixtures/escape.stdout";
assert_success(fixture_path, assertion_path);
}
#[cargo_test(nightly, reason = "-Zscript is unstable")]
#[rustfmt::skip] // code-generated
fn extra_after_end() {
let fixture_path = "tests/testsuite/script/rustc_fixtures/extra-after-end.rs";
let assertion_path = "tests/testsuite/script/rustc_fixtures/extra-after-end.stderr";
assert_failure(fixture_path, assertion_path);
}
#[cargo_test(nightly, reason = "-Zscript is unstable")]
#[rustfmt::skip] // code-generated
fn frontmatter_after_tokens() {
let fixture_path = "tests/testsuite/script/rustc_fixtures/frontmatter-after-tokens.rs";
let assertion_path = "tests/testsuite/script/rustc_fixtures/frontmatter-after-tokens.stdout";
assert_success(fixture_path, assertion_path);
}
#[cargo_test(nightly, reason = "-Zscript is unstable")]
#[rustfmt::skip] // code-generated
fn frontmatter_contains_whitespace() {
let fixture_path = "tests/testsuite/script/rustc_fixtures/frontmatter-contains-whitespace.rs";
let assertion_path = "tests/testsuite/script/rustc_fixtures/frontmatter-contains-whitespace.stderr";
assert_failure(fixture_path, assertion_path);
}
#[cargo_test(nightly, reason = "-Zscript is unstable")]
#[rustfmt::skip] // code-generated
fn frontmatter_crlf() {
let fixture_path = "tests/testsuite/script/rustc_fixtures/frontmatter-crlf.rs";
let assertion_path = "tests/testsuite/script/rustc_fixtures/frontmatter-crlf.stdout";
assert_success(fixture_path, assertion_path);
}
#[cargo_test(nightly, reason = "-Zscript is unstable")]
#[rustfmt::skip] // code-generated
fn frontmatter_inner_hyphens_1() {
let fixture_path = "tests/testsuite/script/rustc_fixtures/frontmatter-inner-hyphens-1.rs";
let assertion_path = "tests/testsuite/script/rustc_fixtures/frontmatter-inner-hyphens-1.stdout";
assert_success(fixture_path, assertion_path);
}
#[cargo_test(nightly, reason = "-Zscript is unstable")]
#[rustfmt::skip] // code-generated
fn frontmatter_inner_hyphens_2() {
let fixture_path = "tests/testsuite/script/rustc_fixtures/frontmatter-inner-hyphens-2.rs";
let assertion_path = "tests/testsuite/script/rustc_fixtures/frontmatter-inner-hyphens-2.stdout";
assert_success(fixture_path, assertion_path);
}
#[cargo_test(nightly, reason = "-Zscript is unstable")]
#[rustfmt::skip] // code-generated
fn frontmatter_non_lexible_tokens() {
let fixture_path = "tests/testsuite/script/rustc_fixtures/frontmatter-non-lexible-tokens.rs";
let assertion_path = "tests/testsuite/script/rustc_fixtures/frontmatter-non-lexible-tokens.stdout";
assert_success(fixture_path, assertion_path);
}
#[cargo_test(nightly, reason = "-Zscript is unstable")]
#[rustfmt::skip] // code-generated
fn frontmatter_whitespace_1() {
let fixture_path = "tests/testsuite/script/rustc_fixtures/frontmatter-whitespace-1.rs";
let assertion_path = "tests/testsuite/script/rustc_fixtures/frontmatter-whitespace-1.stdout";
assert_success(fixture_path, assertion_path);
}
#[cargo_test(nightly, reason = "-Zscript is unstable")]
#[rustfmt::skip] // code-generated
fn frontmatter_whitespace_2() {
let fixture_path = "tests/testsuite/script/rustc_fixtures/frontmatter-whitespace-2.rs";
let assertion_path = "tests/testsuite/script/rustc_fixtures/frontmatter-whitespace-2.stderr";
assert_failure(fixture_path, assertion_path);
}
#[cargo_test(nightly, reason = "-Zscript is unstable")]
#[rustfmt::skip] // code-generated
fn frontmatter_whitespace_3() {
let fixture_path = "tests/testsuite/script/rustc_fixtures/frontmatter-whitespace-3.rs";
let assertion_path = "tests/testsuite/script/rustc_fixtures/frontmatter-whitespace-3.stdout";
assert_success(fixture_path, assertion_path);
}
#[cargo_test(nightly, reason = "-Zscript is unstable")]
#[rustfmt::skip] // code-generated
fn frontmatter_whitespace_4() {
let fixture_path = "tests/testsuite/script/rustc_fixtures/frontmatter-whitespace-4.rs";
let assertion_path = "tests/testsuite/script/rustc_fixtures/frontmatter-whitespace-4.stdout";
assert_success(fixture_path, assertion_path);
}
#[cargo_test(nightly, reason = "-Zscript is unstable")]
#[rustfmt::skip] // code-generated
fn hyphen_in_infostring_leading() {
let fixture_path = "tests/testsuite/script/rustc_fixtures/hyphen-in-infostring-leading.rs";
let assertion_path = "tests/testsuite/script/rustc_fixtures/hyphen-in-infostring-leading.stderr";
assert_failure(fixture_path, assertion_path);
}
#[cargo_test(nightly, reason = "-Zscript is unstable")]
#[rustfmt::skip] // code-generated
fn hyphen_in_infostring_non_leading() {
let fixture_path = "tests/testsuite/script/rustc_fixtures/hyphen-in-infostring-non-leading.rs";
let assertion_path = "tests/testsuite/script/rustc_fixtures/hyphen-in-infostring-non-leading.stderr";
assert_failure(fixture_path, assertion_path);
}
#[cargo_test(nightly, reason = "-Zscript is unstable")]
#[rustfmt::skip] // code-generated
fn included_frontmatter() {
let fixture_path = "tests/testsuite/script/rustc_fixtures/included-frontmatter.rs";
let assertion_path = "tests/testsuite/script/rustc_fixtures/included-frontmatter.stdout";
assert_success(fixture_path, assertion_path);
}
#[cargo_test(nightly, reason = "-Zscript is unstable")]
#[rustfmt::skip] // code-generated
fn infostring_fail() {
let fixture_path = "tests/testsuite/script/rustc_fixtures/infostring-fail.rs";
let assertion_path = "tests/testsuite/script/rustc_fixtures/infostring-fail.stderr";
assert_failure(fixture_path, assertion_path);
}
#[cargo_test(nightly, reason = "-Zscript is unstable")]
#[rustfmt::skip] // code-generated
fn mismatch_1() {
let fixture_path = "tests/testsuite/script/rustc_fixtures/mismatch-1.rs";
let assertion_path = "tests/testsuite/script/rustc_fixtures/mismatch-1.stderr";
assert_failure(fixture_path, assertion_path);
}
#[cargo_test(nightly, reason = "-Zscript is unstable")]
#[rustfmt::skip] // code-generated
fn mismatch_2() {
let fixture_path = "tests/testsuite/script/rustc_fixtures/mismatch-2.rs";
let assertion_path = "tests/testsuite/script/rustc_fixtures/mismatch-2.stderr";
assert_failure(fixture_path, assertion_path);
}
#[cargo_test(nightly, reason = "-Zscript is unstable")]
#[rustfmt::skip] // code-generated
fn multifrontmatter() {
let fixture_path = "tests/testsuite/script/rustc_fixtures/multifrontmatter.rs";
let assertion_path = "tests/testsuite/script/rustc_fixtures/multifrontmatter.stderr";
assert_failure(fixture_path, assertion_path);
}
#[cargo_test(nightly, reason = "-Zscript is unstable")]
#[rustfmt::skip] // code-generated
fn multifrontmatter_2() {
let fixture_path = "tests/testsuite/script/rustc_fixtures/multifrontmatter-2.rs";
let assertion_path = "tests/testsuite/script/rustc_fixtures/multifrontmatter-2.stdout";
assert_success(fixture_path, assertion_path);
}
#[cargo_test(nightly, reason = "-Zscript is unstable")]
#[rustfmt::skip] // code-generated
fn proc_macro_observer() {
let fixture_path = "tests/testsuite/script/rustc_fixtures/proc-macro-observer.rs";
let assertion_path = "tests/testsuite/script/rustc_fixtures/proc-macro-observer.stdout";
assert_success(fixture_path, assertion_path);
}
#[cargo_test(nightly, reason = "-Zscript is unstable")]
#[rustfmt::skip] // code-generated
fn shebang() {
let fixture_path = "tests/testsuite/script/rustc_fixtures/shebang.rs";
let assertion_path = "tests/testsuite/script/rustc_fixtures/shebang.stdout";
assert_success(fixture_path, assertion_path);
}
#[cargo_test(nightly, reason = "-Zscript is unstable")]
#[rustfmt::skip] // code-generated
fn unclosed_1() {
let fixture_path = "tests/testsuite/script/rustc_fixtures/unclosed-1.rs";
let assertion_path = "tests/testsuite/script/rustc_fixtures/unclosed-1.stderr";
assert_failure(fixture_path, assertion_path);
}
#[cargo_test(nightly, reason = "-Zscript is unstable")]
#[rustfmt::skip] // code-generated
fn unclosed_2() {
let fixture_path = "tests/testsuite/script/rustc_fixtures/unclosed-2.rs";
let assertion_path = "tests/testsuite/script/rustc_fixtures/unclosed-2.stderr";
assert_failure(fixture_path, assertion_path);
}
#[cargo_test(nightly, reason = "-Zscript is unstable")]
#[rustfmt::skip] // code-generated
fn unclosed_3() {
let fixture_path = "tests/testsuite/script/rustc_fixtures/unclosed-3.rs";
let assertion_path = "tests/testsuite/script/rustc_fixtures/unclosed-3.stderr";
assert_failure(fixture_path, assertion_path);
}
#[cargo_test(nightly, reason = "-Zscript is unstable")]
#[rustfmt::skip] // code-generated
fn unclosed_4() {
let fixture_path = "tests/testsuite/script/rustc_fixtures/unclosed-4.rs";
let assertion_path = "tests/testsuite/script/rustc_fixtures/unclosed-4.stderr";
assert_failure(fixture_path, assertion_path);
}
#[cargo_test(nightly, reason = "-Zscript is unstable")]
#[rustfmt::skip] // code-generated
fn unclosed_5() {
let fixture_path = "tests/testsuite/script/rustc_fixtures/unclosed-5.rs";
let assertion_path = "tests/testsuite/script/rustc_fixtures/unclosed-5.stderr";
assert_failure(fixture_path, assertion_path);
}

View File

@ -0,0 +1,10 @@
Canonical home for these tests is https://github.com/rust-lang/rust/tree/master/tests/ui/frontmatter
To update
1. Sync changes to this directory
2. Run `SNAPSHOTS=overwrite cargo test --test testsuite -- script::rustc` to register new test cases
2. Run `SNAPSHOTS=overwrite cargo test --test testsuite -- script::rustc` to update snapshots for new test cases
Note:
- A `.stderr` file is assumed that the test fill fail
- A `.stdout` file is assumed that the test fill succeed

View File

@ -0,0 +1,6 @@
---something
---
pub fn foo(x: i32) -> i32 {
-x
}

View File

@ -0,0 +1,8 @@
extern crate proc_macro;
use proc_macro::TokenStream;
#[proc_macro]
pub fn check(_: TokenStream) -> TokenStream {
assert_eq!(6, "---\n---".parse::<TokenStream>().unwrap().into_iter().count());
Default::default()
}

View File

@ -0,0 +1,9 @@
---.toml
//~^ ERROR: invalid infostring for frontmatter
---
// infostrings cannot have leading dots
#![feature(frontmatter)]
fn main() {}

View File

@ -0,0 +1 @@
[ERROR] frontmatter infostring `.toml` is unsupported by cargo; specify `cargo` for embedding a manifest

View File

@ -0,0 +1,10 @@
---Cargo.toml
---
// infostrings can contain dots as long as a dot isn't the first character.
//@ check-pass
// CARGO(fail): unsupported infostring
#![feature(frontmatter)]
fn main() {}

View File

@ -0,0 +1 @@
[ERROR] frontmatter infostring `Cargo.toml` is unsupported by cargo; specify `cargo` for embedding a manifest

View File

@ -0,0 +1,17 @@
----
package.description = """
---
"""
----
//@ check-pass
// This test checks that longer dashes for opening and closing can be used to
// escape sequences such as three dashes inside the frontmatter block.
#![feature(frontmatter)]
fn main() {}

View File

@ -0,0 +1,41 @@
{
"authors": [],
"categories": [],
"default_run": null,
"dependencies": [],
"description": "\n---\n\n",
"documentation": null,
"edition": "2024",
"features": {},
"homepage": null,
"id": "path+[ROOTURL]/foo/script#0.0.0",
"keywords": [],
"license": null,
"license_file": null,
"links": null,
"manifest_path": "[ROOT]/foo/script",
"metadata": null,
"name": "script",
"publish": [],
"readme": null,
"repository": null,
"rust_version": null,
"source": null,
"targets": [
{
"crate_types": [
"bin"
],
"doc": true,
"doctest": false,
"edition": "2024",
"kind": [
"bin"
],
"name": "script",
"src_path": "[ROOT]/foo/script",
"test": true
}
],
"version": "0.0.0"
}

View File

@ -0,0 +1,7 @@
---
---cargo
//~^ ERROR: extra characters after frontmatter close are not allowed
#![feature(frontmatter)]
fn main() {}

View File

@ -0,0 +1 @@
[ERROR] trailing characters found after frontmatter close

View File

@ -0,0 +1,11 @@
#![feature(frontmatter)]
---
//~^ ERROR: expected item, found `-`
// FIXME(frontmatter): make this diagnostic better
---
// frontmatters must be at the start of a file. This test ensures that.
// CARGO(pass): can't detect this, deferring to rustc
fn main() {}

View File

@ -0,0 +1,41 @@
{
"authors": [],
"categories": [],
"default_run": null,
"dependencies": [],
"description": null,
"documentation": null,
"edition": "2024",
"features": {},
"homepage": null,
"id": "path+[ROOTURL]/foo/script#0.0.0",
"keywords": [],
"license": null,
"license_file": null,
"links": null,
"manifest_path": "[ROOT]/foo/script",
"metadata": null,
"name": "script",
"publish": [],
"readme": null,
"repository": null,
"rust_version": null,
"source": null,
"targets": [
{
"crate_types": [
"bin"
],
"doc": true,
"doctest": false,
"edition": "2024",
"kind": [
"bin"
],
"name": "script",
"src_path": "[ROOT]/foo/script",
"test": true
}
],
"version": "0.0.0"
}

View File

@ -0,0 +1,23 @@
#!/usr/bin/env -S cargo -Zscript
---cargo
# Beware editing: it has numerous whitespace characters which are important.
# It contains one ranges from the 'PATTERN_WHITE_SPACE' property outlined in
# https: //unicode.org/Public/UNIDATA/PropList.txt
#
# The characters in the first expression of the assertion can be generated
# from: "4\u{0C}+\n\t\r7\t*\u{20}2\u{85}/\u{200E}3\u{200F}*\u{2028}2\u{2029}"
package.description = """
4 +
7 * 2…/3*2
"""
---
//@ check-pass
// Ensure the frontmatter can contain any whitespace
// CARGO(fail): However, TOML cannot
#![feature(frontmatter)]
fn main() {}

View File

@ -0,0 +1,6 @@
[ERROR] invalid multi-line basic string, expected `/`, characters
--> script:8:2
|
8 | 4 +
| ^
|

View File

@ -0,0 +1,13 @@
#!/usr/bin/env -S cargo -Zscript
---
[dependencies]
clap = "4"
---
//@ check-pass
// crlf line endings should be accepted
#![feature(frontmatter)]
fn main() {}

View File

@ -0,0 +1,54 @@
{
"authors": [],
"categories": [],
"default_run": null,
"dependencies": [
{
"features": [],
"kind": null,
"name": "clap",
"optional": false,
"registry": null,
"rename": null,
"req": "^4",
"source": "registry+https://github.com/rust-lang/crates.io-index",
"target": null,
"uses_default_features": true
}
],
"description": null,
"documentation": null,
"edition": "2024",
"features": {},
"homepage": null,
"id": "path+[ROOTURL]/foo/script#0.0.0",
"keywords": [],
"license": null,
"license_file": null,
"links": null,
"manifest_path": "[ROOT]/foo/script",
"metadata": null,
"name": "script",
"publish": [],
"readme": null,
"repository": null,
"rust_version": null,
"source": null,
"targets": [
{
"crate_types": [
"bin"
],
"doc": true,
"doctest": false,
"edition": "2024",
"kind": [
"bin"
],
"name": "script",
"src_path": "[ROOT]/foo/script",
"test": true
}
],
"version": "0.0.0"
}

View File

@ -0,0 +1,12 @@
---
package.description = """
x ---🚧
"""
---
// Regression test for #141483
//@check-pass
#![feature(frontmatter)]
fn main() {}

View File

@ -0,0 +1,41 @@
{
"authors": [],
"categories": [],
"default_run": null,
"dependencies": [],
"description": "x ---🚧️\n",
"documentation": null,
"edition": "2024",
"features": {},
"homepage": null,
"id": "path+[ROOTURL]/foo/script#0.0.0",
"keywords": [],
"license": null,
"license_file": null,
"links": null,
"manifest_path": "[ROOT]/foo/script",
"metadata": null,
"name": "script",
"publish": [],
"readme": null,
"repository": null,
"rust_version": null,
"source": null,
"targets": [
{
"crate_types": [
"bin"
],
"doc": true,
"doctest": false,
"edition": "2024",
"kind": [
"bin"
],
"name": "script",
"src_path": "[ROOT]/foo/script",
"test": true
}
],
"version": "0.0.0"
}

View File

@ -0,0 +1,13 @@
---
package.description = """
x ---y
"""
---
// Test that hypens are allowed inside frontmatters if there is some
// non-whitespace character preceding them.
//@check-pass
#![feature(frontmatter)]
fn main() {}

View File

@ -0,0 +1,41 @@
{
"authors": [],
"categories": [],
"default_run": null,
"dependencies": [],
"description": "x ---y\n",
"documentation": null,
"edition": "2024",
"features": {},
"homepage": null,
"id": "path+[ROOTURL]/foo/script#0.0.0",
"keywords": [],
"license": null,
"license_file": null,
"links": null,
"manifest_path": "[ROOT]/foo/script",
"metadata": null,
"name": "script",
"publish": [],
"readme": null,
"repository": null,
"rust_version": null,
"source": null,
"targets": [
{
"crate_types": [
"bin"
],
"doc": true,
"doctest": false,
"edition": "2024",
"kind": [
"bin"
],
"name": "script",
"src_path": "[ROOT]/foo/script",
"test": true
}
],
"version": "0.0.0"
}

View File

@ -0,0 +1,14 @@
---cargo
package.description = """
🏳
"""
---
//@ check-pass
#![feature(frontmatter)]
// check that frontmatter blocks can have tokens that are otherwise not accepted by
// the lexer as Rust code.
fn main() {}

View File

@ -0,0 +1,41 @@
{
"authors": [],
"categories": [],
"default_run": null,
"dependencies": [],
"description": "🏳️‍⚧️\n",
"documentation": null,
"edition": "2024",
"features": {},
"homepage": null,
"id": "path+[ROOTURL]/foo/script#0.0.0",
"keywords": [],
"license": null,
"license_file": null,
"links": null,
"manifest_path": "[ROOT]/foo/script",
"metadata": null,
"name": "script",
"publish": [],
"readme": null,
"repository": null,
"rust_version": null,
"source": null,
"targets": [
{
"crate_types": [
"bin"
],
"doc": true,
"doctest": false,
"edition": "2024",
"kind": [
"bin"
],
"name": "script",
"src_path": "[ROOT]/foo/script",
"test": true
}
],
"version": "0.0.0"
}

View File

@ -0,0 +1,11 @@
---
//~^ ERROR: invalid preceding whitespace for frontmatter opening
//~^^ ERROR: unclosed frontmatter
---
#![feature(frontmatter)]
// check that whitespaces should not precede the frontmatter opening or close.
// CARGO(pass): not technitcally a frontmatter, so defer to rustc to error
fn main() {}

View File

@ -0,0 +1,41 @@
{
"authors": [],
"categories": [],
"default_run": null,
"dependencies": [],
"description": null,
"documentation": null,
"edition": "2024",
"features": {},
"homepage": null,
"id": "path+[ROOTURL]/foo/script#0.0.0",
"keywords": [],
"license": null,
"license_file": null,
"links": null,
"manifest_path": "[ROOT]/foo/script",
"metadata": null,
"name": "script",
"publish": [],
"readme": null,
"repository": null,
"rust_version": null,
"source": null,
"targets": [
{
"crate_types": [
"bin"
],
"doc": true,
"doctest": false,
"edition": "2024",
"kind": [
"bin"
],
"name": "script",
"src_path": "[ROOT]/foo/script",
"test": true
}
],
"version": "0.0.0"
}

View File

@ -0,0 +1,14 @@
---cargo
//~^ ERROR: unclosed frontmatter
//@ compile-flags: --crate-type lib
#![feature(frontmatter)]
fn foo(x: i32) -> i32 {
---x
//~^ WARNING: use of a double negation [double_negations]
}
// this test is for the weird case that valid Rust code can have three dashes
// within them and get treated as a frontmatter close.

View File

@ -0,0 +1 @@
[ERROR] no closing `---` found for frontmatter

View File

@ -0,0 +1,16 @@
---cargo
---
// please note the whitespace characters after the first four lines.
// This ensures that we accept whitespaces before the frontmatter, after
// the frontmatter opening and the frontmatter close.
//@ check-pass
// ignore-tidy-end-whitespace
// ignore-tidy-leading-newlines
#![feature(frontmatter)]
fn main() {}

View File

@ -0,0 +1,41 @@
{
"authors": [],
"categories": [],
"default_run": null,
"dependencies": [],
"description": null,
"documentation": null,
"edition": "2024",
"features": {},
"homepage": null,
"id": "path+[ROOTURL]/foo/script#0.0.0",
"keywords": [],
"license": null,
"license_file": null,
"links": null,
"manifest_path": "[ROOT]/foo/script",
"metadata": null,
"name": "script",
"publish": [],
"readme": null,
"repository": null,
"rust_version": null,
"source": null,
"targets": [
{
"crate_types": [
"bin"
],
"doc": true,
"doctest": false,
"edition": "2024",
"kind": [
"bin"
],
"name": "script",
"src_path": "[ROOT]/foo/script",
"test": true
}
],
"version": "0.0.0"
}

View File

@ -0,0 +1,9 @@
--- cargo
---
//@ check-pass
// A frontmatter infostring can have leading whitespace.
#![feature(frontmatter)]
fn main() {}

View File

@ -0,0 +1,41 @@
{
"authors": [],
"categories": [],
"default_run": null,
"dependencies": [],
"description": null,
"documentation": null,
"edition": "2024",
"features": {},
"homepage": null,
"id": "path+[ROOTURL]/foo/script#0.0.0",
"keywords": [],
"license": null,
"license_file": null,
"links": null,
"manifest_path": "[ROOT]/foo/script",
"metadata": null,
"name": "script",
"publish": [],
"readme": null,
"repository": null,
"rust_version": null,
"source": null,
"targets": [
{
"crate_types": [
"bin"
],
"doc": true,
"doctest": false,
"edition": "2024",
"kind": [
"bin"
],
"name": "script",
"src_path": "[ROOT]/foo/script",
"test": true
}
],
"version": "0.0.0"
}

View File

@ -0,0 +1,9 @@
--- -toml
//~^ ERROR: invalid infostring for frontmatter
---
// infostrings cannot have leading hyphens
#![feature(frontmatter)]
fn main() {}

View File

@ -0,0 +1 @@
[ERROR] frontmatter infostring `-toml` is unsupported by cargo; specify `cargo` for embedding a manifest

View File

@ -0,0 +1,10 @@
--- Cargo-toml
---
// infostrings can contain hyphens as long as a hyphen isn't the first character.
//@ check-pass
// CARGO(fail): unsupported infostring
#![feature(frontmatter)]
fn main() {}

View File

@ -0,0 +1 @@
[ERROR] frontmatter infostring `Cargo-toml` is unsupported by cargo; specify `cargo` for embedding a manifest

View File

@ -0,0 +1,12 @@
#![feature(frontmatter)]
//@ check-pass
include!("auxiliary/lib.rs");
// auxiliary/lib.rs contains a frontmatter. Ensure that we can use them in an
// `include!` macro.
fn main() {
foo(1);
}

View File

@ -0,0 +1,41 @@
{
"authors": [],
"categories": [],
"default_run": null,
"dependencies": [],
"description": null,
"documentation": null,
"edition": "2024",
"features": {},
"homepage": null,
"id": "path+[ROOTURL]/foo/script#0.0.0",
"keywords": [],
"license": null,
"license_file": null,
"links": null,
"manifest_path": "[ROOT]/foo/script",
"metadata": null,
"name": "script",
"publish": [],
"readme": null,
"repository": null,
"rust_version": null,
"source": null,
"targets": [
{
"crate_types": [
"bin"
],
"doc": true,
"doctest": false,
"edition": "2024",
"kind": [
"bin"
],
"name": "script",
"src_path": "[ROOT]/foo/script",
"test": true
}
],
"version": "0.0.0"
}

View File

@ -0,0 +1,9 @@
---cargo,clippy
//~^ ERROR: invalid infostring for frontmatter
---
// infostrings can only be a single identifier.
#![feature(frontmatter)]
fn main() {}

View File

@ -0,0 +1 @@
[ERROR] cargo does not support frontmatter infostring attributes like `clippy` at this time

View File

@ -0,0 +1,10 @@
---cargo
//~^ ERROR: frontmatter close does not match the opening
----
// there must be the same number of dashes for both the opening and the close
// of the frontmatter.
#![feature(frontmatter)]
fn main() {}

View File

@ -0,0 +1 @@
[ERROR] trailing characters found after frontmatter close

View File

@ -0,0 +1,8 @@
----cargo
//~^ ERROR: frontmatter close does not match the opening
---cargo
//~^ ERROR: extra characters after frontmatter close are not allowed
#![feature(frontmatter)]
fn main() {}

View File

@ -0,0 +1 @@
[ERROR] no closing `----` found for frontmatter

View File

@ -0,0 +1,14 @@
---
package.description = """
---
---
"""
---
// hyphens only need to be escaped when at the start of a line
//@ check-pass
#![feature(frontmatter)]
fn main() {}

View File

@ -0,0 +1,41 @@
{
"authors": [],
"categories": [],
"default_run": null,
"dependencies": [],
"description": " ---\n\n ---\n",
"documentation": null,
"edition": "2024",
"features": {},
"homepage": null,
"id": "path+[ROOTURL]/foo/script#0.0.0",
"keywords": [],
"license": null,
"license_file": null,
"links": null,
"manifest_path": "[ROOT]/foo/script",
"metadata": null,
"name": "script",
"publish": [],
"readme": null,
"repository": null,
"rust_version": null,
"source": null,
"targets": [
{
"crate_types": [
"bin"
],
"doc": true,
"doctest": false,
"edition": "2024",
"kind": [
"bin"
],
"name": "script",
"src_path": "[ROOT]/foo/script",
"test": true
}
],
"version": "0.0.0"
}

View File

@ -0,0 +1,13 @@
---
---
---
//~^ ERROR: expected item, found `-`
// FIXME(frontmatter): make this diagnostic better
---
// test that we do not parse another frontmatter block after the first one.
#![feature(frontmatter)]
fn main() {}

View File

@ -0,0 +1 @@
[ERROR] only one frontmatter is supported

View File

@ -0,0 +1,11 @@
//@ check-pass
//@ proc-macro: makro.rs
//@ edition: 2021
makro::check!();
// checks that a proc-macro doesn't know or parse frontmatters at all and instead treats
// it as normal Rust code.
// see auxiliary/makro.rs for how it is tested.
fn main() {}

View File

@ -0,0 +1,41 @@
{
"authors": [],
"categories": [],
"default_run": null,
"dependencies": [],
"description": null,
"documentation": null,
"edition": "2024",
"features": {},
"homepage": null,
"id": "path+[ROOTURL]/foo/script#0.0.0",
"keywords": [],
"license": null,
"license_file": null,
"links": null,
"manifest_path": "[ROOT]/foo/script",
"metadata": null,
"name": "script",
"publish": [],
"readme": null,
"repository": null,
"rust_version": null,
"source": null,
"targets": [
{
"crate_types": [
"bin"
],
"doc": true,
"doctest": false,
"edition": "2024",
"kind": [
"bin"
],
"name": "script",
"src_path": "[ROOT]/foo/script",
"test": true
}
],
"version": "0.0.0"
}

View File

@ -0,0 +1,13 @@
#!/usr/bin/env -S cargo -Zscript
---
[dependencies]
clap = "4"
---
//@ check-pass
// Shebangs on a file can precede a frontmatter.
#![feature(frontmatter)]
fn main () {}

View File

@ -0,0 +1,54 @@
{
"authors": [],
"categories": [],
"default_run": null,
"dependencies": [
{
"features": [],
"kind": null,
"name": "clap",
"optional": false,
"registry": null,
"rename": null,
"req": "^4",
"source": "registry+https://github.com/rust-lang/crates.io-index",
"target": null,
"uses_default_features": true
}
],
"description": null,
"documentation": null,
"edition": "2024",
"features": {},
"homepage": null,
"id": "path+[ROOTURL]/foo/script#0.0.0",
"keywords": [],
"license": null,
"license_file": null,
"links": null,
"manifest_path": "[ROOT]/foo/script",
"metadata": null,
"name": "script",
"publish": [],
"readme": null,
"repository": null,
"rust_version": null,
"source": null,
"targets": [
{
"crate_types": [
"bin"
],
"doc": true,
"doctest": false,
"edition": "2024",
"kind": [
"bin"
],
"name": "script",
"src_path": "[ROOT]/foo/script",
"test": true
}
],
"version": "0.0.0"
}

View File

@ -0,0 +1,10 @@
----cargo
//~^ ERROR: unclosed frontmatter
// This test checks that the #! characters can help us recover a frontmatter
// close. There should not be a "missing `main` function" error as the rest
// are properly parsed.
#![feature(frontmatter)]
fn main() {}

View File

@ -0,0 +1 @@
[ERROR] no closing `----` found for frontmatter

View File

@ -0,0 +1,15 @@
----cargo
//~^ ERROR: unclosed frontmatter
//~| ERROR: frontmatters are experimental
//@ compile-flags: --crate-type lib
// Leading whitespace on the feature line prevents recovery. However
// the dashes quoted will not be used for recovery and the entire file
// should be treated as within the frontmatter block.
#![feature(frontmatter)]
fn foo() -> &str {
"----"
}

View File

@ -0,0 +1 @@
[ERROR] no closing `----` found for frontmatter

View File

@ -0,0 +1,16 @@
----cargo
//~^ ERROR: frontmatter close does not match the opening
//@ compile-flags: --crate-type lib
// Unfortunate recovery situation. Not really preventable with improving the
// recovery strategy, but this type of code is rare enough already.
#![feature(frontmatter)]
fn foo(x: i32) -> i32 {
---x
//~^ ERROR: invalid preceding whitespace for frontmatter close
//~| ERROR: extra characters after frontmatter close are not allowed
}
//~^ ERROR: unexpected closing delimiter: `}`

View File

@ -0,0 +1 @@
[ERROR] no closing `----` found for frontmatter

View File

@ -0,0 +1,9 @@
----cargo
//~^ ERROR: unclosed frontmatter
//! Similarly, a module-level content should allow for recovery as well (as
//! per unclosed-1.rs)
#![feature(frontmatter)]
fn main() {}

View File

@ -0,0 +1 @@
[ERROR] no closing `----` found for frontmatter

View File

@ -0,0 +1,10 @@
----cargo
//~^ ERROR: unclosed frontmatter
//~| ERROR: frontmatters are experimental
// Similarly, a use statement should allow for recovery as well (as
// per unclosed-1.rs)
use std::env;
fn main() {}

View File

@ -0,0 +1 @@
[ERROR] no closing `----` found for frontmatter