From 3518d8dbffbaa09463c5d4b9d6d0afead915697e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Sat, 7 Feb 2026 15:16:39 +0100 Subject: [PATCH] Add per-feature smoke test suite --- Cargo.toml | 2 +- src/lib/fmter/item.rs | 3 --- test/README.md | 25 +++++++++++++++++++ .../feature/async_for_loop-lookalike-2015.rs | 7 ++++++ test/smoke/feature/async_for_loop.rs | 11 ++++++++ test/smoke/feature/async_trait_bounds.rs | 11 ++++++++ test/smoke/feature/auto_traits.rs | 6 +++++ test/smoke/feature/box_patterns.rs | 19 ++++++++++++++ test/smoke/feature/builtin_syntax.rs | 12 +++++++++ test/smoke/feature/closure_lifetime_binder.rs | 18 +++++++++++++ test/smoke/feature/const_block_items.rs | 14 +++++++++++ test/smoke/feature/const_closures.rs | 12 +++++++++ test/smoke/feature/const_trait_impl.rs | 25 +++++++++++++++++++ test/smoke/feature/contracts_internals.rs | 16 ++++++++++++ test/smoke/feature/coroutines.rs | 0 test/smoke/feature/decl_macro.rs | 6 +++++ test/smoke/feature/default_field_values.rs | 18 +++++++++++++ test/smoke/feature/ergonomic_clones.rs | 0 test/smoke/feature/explicit_tail_calls.rs | 0 .../feature/final_associated_functions.rs | 0 test/smoke/feature/fn_delegation.rs | 0 test/smoke/feature/frontmatter.rs | 0 test/smoke/feature/gen_blocks.rs | 0 test/smoke/feature/generic_const_items.rs | 0 test/smoke/feature/guard_patterns.rs | 0 test/smoke/feature/min_generic_const_args.rs | 0 test/smoke/feature/more_qualified_paths.rs | 0 test/smoke/feature/mut_ref.rs | 0 test/smoke/feature/negative_bounds.rs | 0 test/smoke/feature/negative_impls.rs | 0 test/smoke/feature/never_patterns.rs | 0 test/smoke/feature/pin_ergonomics.rs | 0 test/smoke/feature/postfix_match.rs | 0 test/smoke/feature/return_type_notation.rs | 0 test/smoke/feature/specialization.rs | 0 test/smoke/feature/stmt_expr_attributes.rs | 0 test/smoke/feature/super_let.rs | 0 test/smoke/feature/trait_alias.rs | 0 test/smoke/feature/try_blocks.rs | 0 .../smoke/feature/try_blocks_heterogeneous.rs | 0 test/smoke/feature/unsafe_binders.rs | 0 test/smoke/feature/unsafe_fields.rs | 0 test/smoke/feature/where_clause_attrs.rs | 0 test/smoke/feature/yeet_expr.rs | 0 test/smoke/feature/yield_expr.rs | 0 45 files changed, 201 insertions(+), 4 deletions(-) create mode 100644 test/README.md create mode 100644 test/smoke/feature/async_for_loop-lookalike-2015.rs create mode 100644 test/smoke/feature/async_for_loop.rs create mode 100644 test/smoke/feature/async_trait_bounds.rs create mode 100644 test/smoke/feature/auto_traits.rs create mode 100644 test/smoke/feature/box_patterns.rs create mode 100644 test/smoke/feature/builtin_syntax.rs create mode 100644 test/smoke/feature/closure_lifetime_binder.rs create mode 100644 test/smoke/feature/const_block_items.rs create mode 100644 test/smoke/feature/const_closures.rs create mode 100644 test/smoke/feature/const_trait_impl.rs create mode 100644 test/smoke/feature/contracts_internals.rs create mode 100644 test/smoke/feature/coroutines.rs create mode 100644 test/smoke/feature/decl_macro.rs create mode 100644 test/smoke/feature/default_field_values.rs create mode 100644 test/smoke/feature/ergonomic_clones.rs create mode 100644 test/smoke/feature/explicit_tail_calls.rs create mode 100644 test/smoke/feature/final_associated_functions.rs create mode 100644 test/smoke/feature/fn_delegation.rs create mode 100644 test/smoke/feature/frontmatter.rs create mode 100644 test/smoke/feature/gen_blocks.rs create mode 100644 test/smoke/feature/generic_const_items.rs create mode 100644 test/smoke/feature/guard_patterns.rs create mode 100644 test/smoke/feature/min_generic_const_args.rs create mode 100644 test/smoke/feature/more_qualified_paths.rs create mode 100644 test/smoke/feature/mut_ref.rs create mode 100644 test/smoke/feature/negative_bounds.rs create mode 100644 test/smoke/feature/negative_impls.rs create mode 100644 test/smoke/feature/never_patterns.rs create mode 100644 test/smoke/feature/pin_ergonomics.rs create mode 100644 test/smoke/feature/postfix_match.rs create mode 100644 test/smoke/feature/return_type_notation.rs create mode 100644 test/smoke/feature/specialization.rs create mode 100644 test/smoke/feature/stmt_expr_attributes.rs create mode 100644 test/smoke/feature/super_let.rs create mode 100644 test/smoke/feature/trait_alias.rs create mode 100644 test/smoke/feature/try_blocks.rs create mode 100644 test/smoke/feature/try_blocks_heterogeneous.rs create mode 100644 test/smoke/feature/unsafe_binders.rs create mode 100644 test/smoke/feature/unsafe_fields.rs create mode 100644 test/smoke/feature/where_clause_attrs.rs create mode 100644 test/smoke/feature/yeet_expr.rs create mode 100644 test/smoke/feature/yield_expr.rs diff --git a/Cargo.toml b/Cargo.toml index 678b62e..4cd2635 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,7 @@ version.workspace = true edition.workspace = true publish = false -autobins = false +autotests = false [lib] path = "src/lib/lib.rs" diff --git a/src/lib/fmter/item.rs b/src/lib/fmter/item.rs index 8579c3c..8e6fd71 100644 --- a/src/lib/fmter/item.rs +++ b/src/lib/fmter/item.rs @@ -375,9 +375,6 @@ impl Fmt for ast::Contract<'_> { if let Some(requires) = requires { fmt!(cx, " contract_requires "); requires.fmt(cx); - if ensures.is_some() { - fmt!(cx, " "); - } } if let Some(ensures) = ensures { fmt!(cx, " contract_ensures "); diff --git a/test/README.md b/test/README.md new file mode 100644 index 0000000..eac0434 --- /dev/null +++ b/test/README.md @@ -0,0 +1,25 @@ +# Tests + +## Unit Tests + +They are located in `src/lib/parser/test.rs`, not here in `test/`. + +* they are mostly for edge cases for now but that'll slowly change +* they consist of positive and negative behavior test cases +* they work with the AST nodes and error 'codes' + +## Per-Feature Smoke Tests + +The test cases are located in `test/smoke/feature/`. + +* the directory is meant to be fed to `etc/check.rs` +* that script compares the exit status of `rasur` and `rustc` per file +* the default edition is Rust 2015; pass `-e, --edition ` to override; + `--edition all` or `-eall` makes the script test each file under all editions +* the test cases do contain a custom test directive / parameter / configuration + language (prefixed by `//:`) for setting edition-aware test expectations; + however, these annotations aren't interpreted yet by the script +* they mainly consist of positive behavior tests +* they allow us to detect the removal of unstable syntax; + such removals often implies test removals in r-l/r, so we wouldn't be able to + if that happened when running rasur against r-l/r's test suite diff --git a/test/smoke/feature/async_for_loop-lookalike-2015.rs b/test/smoke/feature/async_for_loop-lookalike-2015.rs new file mode 100644 index 0000000..bcf2ff4 --- /dev/null +++ b/test/smoke/feature/async_for_loop-lookalike-2015.rs @@ -0,0 +1,7 @@ +// In Rust 2015, the `await (x)` is just tuple struct pattern. +//: (2015) accept (2018->) reject + +fn func() { + for await (x) in [] {} + struct await(i32); +} diff --git a/test/smoke/feature/async_for_loop.rs b/test/smoke/feature/async_for_loop.rs new file mode 100644 index 0000000..b7fda1f --- /dev/null +++ b/test/smoke/feature/async_for_loop.rs @@ -0,0 +1,11 @@ +// issue: +//: (2018->) accept (2015) reject +#![rustfmt::skip] + +fn func() { + for await x in xs {} + for await _ in xs.await {} + for await () in xs {} + for await! in xs {} + for await[0] in xs {} +} diff --git a/test/smoke/feature/async_trait_bounds.rs b/test/smoke/feature/async_trait_bounds.rs new file mode 100644 index 0000000..2584272 --- /dev/null +++ b/test/smoke/feature/async_trait_bounds.rs @@ -0,0 +1,11 @@ +// issue: +//: (2018->) accept (2015) reject +#![rustfmt::skip] + +fn func(_: dyn async Trait) -> impl async Trait +where + T: async Trait, + (): const async Trait, + for<> async Trait(): for<> async Trait() -> (), +{ +} diff --git a/test/smoke/feature/auto_traits.rs b/test/smoke/feature/auto_traits.rs new file mode 100644 index 0000000..fc6a6d7 --- /dev/null +++ b/test/smoke/feature/auto_traits.rs @@ -0,0 +1,6 @@ +// issue: +//: accept + +auto trait Trait {} +unsafe auto trait Trait {} +const auto trait Trait {} diff --git a/test/smoke/feature/box_patterns.rs b/test/smoke/feature/box_patterns.rs new file mode 100644 index 0000000..e0d98e9 --- /dev/null +++ b/test/smoke/feature/box_patterns.rs @@ -0,0 +1,19 @@ +// issue: +//: accept +#![rustfmt::skip] + +fn func(box (): Ty) { + let box _; + let box x; + let box ref x; + let box mut ref x; + let box []; + let Ty { x: box _ }; + let Ty { box x }; + let Ty { box ref x }; + let Ty { box mut ref x }; + + match () { + |box 0| box 1 => |box 0| 1, + } +} diff --git a/test/smoke/feature/builtin_syntax.rs b/test/smoke/feature/builtin_syntax.rs new file mode 100644 index 0000000..201f21a --- /dev/null +++ b/test/smoke/feature/builtin_syntax.rs @@ -0,0 +1,12 @@ +// issue: +//: accept + +fn func() { + let builtin # deref(0); + let builtin # deref(x | y); + let _ = builtin # type_ascribe(!0, !); + let _ = builtin # offset_of(Ty, x.0.1.y.z.2); + let _ = builtin # wrap_binder(0 * 1); + let _ = builtin # unwrap_binder(*&()); + let _: builtin # field_of((), 0); +} diff --git a/test/smoke/feature/closure_lifetime_binder.rs b/test/smoke/feature/closure_lifetime_binder.rs new file mode 100644 index 0000000..2f6cb86 --- /dev/null +++ b/test/smoke/feature/closure_lifetime_binder.rs @@ -0,0 +1,18 @@ +// issue: +//: accept +#![rustfmt::skip] + +fn func() { + for<> || (); + let _ = for<'a> |_| {}; + let _ = for |_| {}; + let _ = for |_| {}; + let _ = for<#[a] T> |_| {}; + let _ = for<#[a] const N: usize> |_| {}; + for<'a: 'static, 'b, T, U = (), T = (),> |_| {}; + + // "lookalikes" (extended paths): + for::Ty in .. {} + for<() as Trait>::Ty in .. {} + for<(T)>::Ty in .. {} +} diff --git a/test/smoke/feature/const_block_items.rs b/test/smoke/feature/const_block_items.rs new file mode 100644 index 0000000..f5c4511 --- /dev/null +++ b/test/smoke/feature/const_block_items.rs @@ -0,0 +1,14 @@ +// issue: +//: accept + +const {} + +const { + scope(); + loop {} +} + +#[cfg(false)] +const { "..." } + +const fn func() {} diff --git a/test/smoke/feature/const_closures.rs b/test/smoke/feature/const_closures.rs new file mode 100644 index 0000000..9fd5ad5 --- /dev/null +++ b/test/smoke/feature/const_closures.rs @@ -0,0 +1,12 @@ +// issue: +//: accept +#![rustfmt::skip] + +fn func() { + let _ = const || {}; + let _ = const |_| (); + let _ = for<> const || {}; + let _ = const move || {}; + let _ = const use || {}; + const | | {}; +} diff --git a/test/smoke/feature/const_trait_impl.rs b/test/smoke/feature/const_trait_impl.rs new file mode 100644 index 0000000..2c85efd --- /dev/null +++ b/test/smoke/feature/const_trait_impl.rs @@ -0,0 +1,25 @@ +// issue: +//: accept +#![rustfmt::skip] + +const trait Trait {} +const unsafe trait Trait {} +const auto trait Trait {} +const unsafe auto trait Trait {} + +impl const Trait for () {} +impl const !Trait for () {} +impl const () {} +impl const impl Trait {} + +const impl Trait for () {} +const impl !Trait for () {} +const impl () {} +const impl impl Trait {} + +fn func() +where + (): const Trait + [const] Trait + ~const Trait, + for<> const Trait: for<> const Trait() -> (), + for<> ~const Trait: for<> ~const Trait() -> (), +{} diff --git a/test/smoke/feature/contracts_internals.rs b/test/smoke/feature/contracts_internals.rs new file mode 100644 index 0000000..20c6ad4 --- /dev/null +++ b/test/smoke/feature/contracts_internals.rs @@ -0,0 +1,16 @@ +// issue: +//: accept +#![rustfmt::skip] + +fn func() contract_requires {} {} +fn func() contract_ensures () {} +fn func() contract_ensures {}; +fn func() contract_requires { 0 } contract_ensures 0 {} +fn func() -> () contract_requires { 0 } contract_ensures 0 {} +fn func() +contract_requires { fn func(); } +contract_ensures 1 + 2 * 3; + +// "lookalikes" (paths): +fn func() -> contract_requires { 0 } +fn func() -> contract_ensures { 0 } diff --git a/test/smoke/feature/coroutines.rs b/test/smoke/feature/coroutines.rs new file mode 100644 index 0000000..e69de29 diff --git a/test/smoke/feature/decl_macro.rs b/test/smoke/feature/decl_macro.rs new file mode 100644 index 0000000..2c9b544 --- /dev/null +++ b/test/smoke/feature/decl_macro.rs @@ -0,0 +1,6 @@ +// issue: +//: accept + +macro makro {} +pub macro makro { @ @ @ } +macro makro() { @ @ @ } diff --git a/test/smoke/feature/default_field_values.rs b/test/smoke/feature/default_field_values.rs new file mode 100644 index 0000000..1c67b72 --- /dev/null +++ b/test/smoke/feature/default_field_values.rs @@ -0,0 +1,18 @@ +// issue: +//: accept + +struct Type { + x: i32 = 0, + pub x: i32 = { 1 + 2 }, + unsafe x: i32 = unsafe { 0 }, + #[a] x: Trait() -> Trait += (), +} + +struct Type(i32 = 0, pub i32 = {}, #[a] [[[_]]] = ..); + +fn func() { + // This was already syntactically legal before the introduction of DFVs. + // Still, I'm listing it here because it's related. + _ = Type { .. }; + _ = Type { x, x: x, .. }; +} diff --git a/test/smoke/feature/ergonomic_clones.rs b/test/smoke/feature/ergonomic_clones.rs new file mode 100644 index 0000000..e69de29 diff --git a/test/smoke/feature/explicit_tail_calls.rs b/test/smoke/feature/explicit_tail_calls.rs new file mode 100644 index 0000000..e69de29 diff --git a/test/smoke/feature/final_associated_functions.rs b/test/smoke/feature/final_associated_functions.rs new file mode 100644 index 0000000..e69de29 diff --git a/test/smoke/feature/fn_delegation.rs b/test/smoke/feature/fn_delegation.rs new file mode 100644 index 0000000..e69de29 diff --git a/test/smoke/feature/frontmatter.rs b/test/smoke/feature/frontmatter.rs new file mode 100644 index 0000000..e69de29 diff --git a/test/smoke/feature/gen_blocks.rs b/test/smoke/feature/gen_blocks.rs new file mode 100644 index 0000000..e69de29 diff --git a/test/smoke/feature/generic_const_items.rs b/test/smoke/feature/generic_const_items.rs new file mode 100644 index 0000000..e69de29 diff --git a/test/smoke/feature/guard_patterns.rs b/test/smoke/feature/guard_patterns.rs new file mode 100644 index 0000000..e69de29 diff --git a/test/smoke/feature/min_generic_const_args.rs b/test/smoke/feature/min_generic_const_args.rs new file mode 100644 index 0000000..e69de29 diff --git a/test/smoke/feature/more_qualified_paths.rs b/test/smoke/feature/more_qualified_paths.rs new file mode 100644 index 0000000..e69de29 diff --git a/test/smoke/feature/mut_ref.rs b/test/smoke/feature/mut_ref.rs new file mode 100644 index 0000000..e69de29 diff --git a/test/smoke/feature/negative_bounds.rs b/test/smoke/feature/negative_bounds.rs new file mode 100644 index 0000000..e69de29 diff --git a/test/smoke/feature/negative_impls.rs b/test/smoke/feature/negative_impls.rs new file mode 100644 index 0000000..e69de29 diff --git a/test/smoke/feature/never_patterns.rs b/test/smoke/feature/never_patterns.rs new file mode 100644 index 0000000..e69de29 diff --git a/test/smoke/feature/pin_ergonomics.rs b/test/smoke/feature/pin_ergonomics.rs new file mode 100644 index 0000000..e69de29 diff --git a/test/smoke/feature/postfix_match.rs b/test/smoke/feature/postfix_match.rs new file mode 100644 index 0000000..e69de29 diff --git a/test/smoke/feature/return_type_notation.rs b/test/smoke/feature/return_type_notation.rs new file mode 100644 index 0000000..e69de29 diff --git a/test/smoke/feature/specialization.rs b/test/smoke/feature/specialization.rs new file mode 100644 index 0000000..e69de29 diff --git a/test/smoke/feature/stmt_expr_attributes.rs b/test/smoke/feature/stmt_expr_attributes.rs new file mode 100644 index 0000000..e69de29 diff --git a/test/smoke/feature/super_let.rs b/test/smoke/feature/super_let.rs new file mode 100644 index 0000000..e69de29 diff --git a/test/smoke/feature/trait_alias.rs b/test/smoke/feature/trait_alias.rs new file mode 100644 index 0000000..e69de29 diff --git a/test/smoke/feature/try_blocks.rs b/test/smoke/feature/try_blocks.rs new file mode 100644 index 0000000..e69de29 diff --git a/test/smoke/feature/try_blocks_heterogeneous.rs b/test/smoke/feature/try_blocks_heterogeneous.rs new file mode 100644 index 0000000..e69de29 diff --git a/test/smoke/feature/unsafe_binders.rs b/test/smoke/feature/unsafe_binders.rs new file mode 100644 index 0000000..e69de29 diff --git a/test/smoke/feature/unsafe_fields.rs b/test/smoke/feature/unsafe_fields.rs new file mode 100644 index 0000000..e69de29 diff --git a/test/smoke/feature/where_clause_attrs.rs b/test/smoke/feature/where_clause_attrs.rs new file mode 100644 index 0000000..e69de29 diff --git a/test/smoke/feature/yeet_expr.rs b/test/smoke/feature/yeet_expr.rs new file mode 100644 index 0000000..e69de29 diff --git a/test/smoke/feature/yield_expr.rs b/test/smoke/feature/yield_expr.rs new file mode 100644 index 0000000..e69de29