Skip to content
Merged
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
50 changes: 46 additions & 4 deletions .github/workflows/check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:
# Use the same components in every step for caching
components: cargo,clippy,rustfmt
- name: Build each Rust crate
run: cargo build --workspace --all-targets --all-features
run: cargo build --all-targets --all-features

test-rust:
name: 2. Test Rust crates
Expand All @@ -39,7 +39,9 @@ jobs:
toolchain: nightly
components: cargo,clippy,rustfmt
- name: Test each Rust crate
run: cargo test --workspace --all-targets --all-features
run: |
cargo test --all-targets --all-features
cargo test --doc --all-features

run:
name: 3. Run Rust example binaries
Expand Down Expand Up @@ -69,7 +71,7 @@ jobs:
toolchain: nightly
components: cargo,clippy,rustfmt
- name: Run clippy on Rust crates
run: cargo clippy --workspace --all-targets --all-features -- --deny warnings
run: cargo clippy --all-targets --all-features -- --deny warnings

doc-rust:
name: 5. Doc lints on Rust crates
Expand All @@ -81,7 +83,7 @@ jobs:
toolchain: nightly
components: cargo,clippy,rustfmt
- name: Run doc checks on Rust crates
run: cargo doc --workspace --all-features
run: cargo doc --all-features

fmt-rust:
name: 6. Code format on Rust crates
Expand All @@ -107,6 +109,44 @@ jobs:
- name: Dry run publishing
run: cargo publish --dry-run

diagnostics-rust:
name: 8. Diagnostics tests on Rust crates
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: actions-rust-lang/setup-rust-toolchain@166cdcfd11aee3cb47222f9ddb555ce30ddb9659 # v1.17.0
with:
toolchain: nightly
# Use the same components in every step for caching
components: cargo,clippy,rustfmt
- name: Build each Rust crate
# To bless (update the expected diagnostics), change '/tmp' to 'splat-overload-diagnostics/src/bin',
# and disable color output.
# FIXME: turn this into a script so we can run it locally.
run: |
export CARGO_TERM_COLOR=never
set -o pipefail
TEST_NAMES=$(find splat-overload-diagnostics/src/bin -name "*.rs" | \
sed 's|.*/\([^/]*\).rs|\1|g' )
echo "testing: $TEST_NAMES"
for test_name in $TEST_NAMES; do
echo "testing: $test_name"
# We expect cargo to fail, so don't exit the shell when it does
set +e
# Ignore build progress, if it's cached then the built crates change
cargo build --all-features --package splat-overload-diagnostics --bin "$test_name" 2>&1 | \
grep --invert-match -e 'Updating .* index' -e 'Compiling [^ ]* .*' \
> "/tmp/$test_name.stderr"
CARGO_EXIT_CODE=$?
set -e
if [[ $CARGO_EXIT_CODE -ne 101 ]]; then
echo "error: $test_name compilation unexpectedly returned exit code $CARGO_EXIT_CODE rather than 101"
exit 1
fi
echo "comparing diagnostics for: $test_name"
diff --unified=5 "splat-overload-diagnostics/src/bin/$test_name.stderr" /tmp/"$test_name.stderr"
done

all:
name: All checks
# Always run this job, even if earlier steps were skipped (or failed):
Expand All @@ -121,6 +161,7 @@ jobs:
- doc-rust
- fmt-rust
- publish-dry-run
- diagnostics-rust
steps:
- name: Fail if any other job failed
# Every job status needs to be checked here, because `always()` stops failures from propagating automatically
Expand All @@ -133,3 +174,4 @@ jobs:
[[ "${{ needs.doc-rust.result }}" == "success" ]] || exit 1
[[ "${{ needs.fmt-rust.result }}" == "success" ]] || exit 1
[[ "${{ needs.publish-dry-run.result }}" == "success" ]] || exit 1
[[ "${{ needs.diagnostics-rust.result }}" == "success" ]] || exit 1
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 8 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@
resolver = "3"
members = [
"splat-overload",
"splat-overload-test"
"splat-overload-test",
"splat-overload-diagnostics",
]
default-members = [
"splat-overload",
"splat-overload-test"
"splat-overload-test",
# Excluded from default members because it deliberately fails compilation
#"splat-overload-diagnostics",
]

[workspace.package]
Expand All @@ -23,11 +26,11 @@
"interop",
]
license = "MIT OR APACHE-2.0"
readme = "README.md"

Check warning on line 29 in Cargo.toml

View workflow job for this annotation

GitHub Actions / 7. Dry run publishing

explicit `package.readme` can be inferred
repository = "https://github.com/rustfoundation/overloading-macros"
# Requires #[rustc_splat] which was renamed in nightly-2026-07-31 (rust-lang/rust#159817)
# FIXME: we can't specify nightly dates or the latest nightly here, update to 1.100 once 1.99 beta branches (20 August 2026)
rust-version = "1.99"
# Requires nightly `#[rustc_splat]` which was renamed in nightly-2026-07-31 (rust-lang/rust#159817)
# We can't specify nightly here, because version suffixes aren't supported.
rust-version = "1.100"

[workspace.dependencies]
syn = { version = "2.0.119", features = ["full"] }
Expand Down
16 changes: 16 additions & 0 deletions splat-overload-diagnostics/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[package]
name = "splat-overload-diagnostics"
description = "Diagnostics test crate for the experimental splat-overload proc-macro"
publish = false
version.workspace = true
authors.workspace = true
edition.workspace = true
homepage.workspace = true
keywords.workspace = true
license.workspace = true
readme.workspace = true
repository.workspace = true
rust-version.workspace = true

[dependencies]
splat-overload = { path = "../splat-overload" }
2 changes: 2 additions & 0 deletions splat-overload-diagnostics/rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[toolchain]
channel = "nightly"
2 changes: 2 additions & 0 deletions splat-overload-diagnostics/src/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
These example binaries are automatically run in CI, they are expected to fail, with output in the
corresponding `.stderr` file.
21 changes: 21 additions & 0 deletions splat-overload-diagnostics/src/bin/diag-function-return-values.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#![feature(splat)]
#![feature(tuple_trait)]
#![allow(incomplete_features)]
#![allow(unused_braces)]

use splat_overload::overload;

overload! {
fn foo(x: i32) -> i32 { x }
fn foo(x: f64) -> f64 { x }
}

fn main() {
// Empty argument list
foo();
foo("wrong type");
// Wrong number of arguments
foo(1_i32, 2, 3);
// Wrong return type
let a: i32 = foo(1.0_f64);
}
171 changes: 171 additions & 0 deletions splat-overload-diagnostics/src/bin/diag-function-return-values.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
error[E0277]: missing overload for arguments `()`
--> splat-overload-diagnostics/src/bin/diag-function-return-values.rs:15:5
|
15 | foo();
| ^^^ the argument types `()` do not match any overload
|
= help: the trait `FooArgs` is not implemented for `()`
= note: check for missing or extra arguments, and check argument types
= note: consider adding a new overload in the overload! { ... } block
help: the following other types implement trait `FooArgs`
--> splat-overload-diagnostics/src/bin/diag-function-return-values.rs:8:1
|
8 | / overload! {
9 | | fn foo(x: i32) -> i32 { x }
10 | | fn foo(x: f64) -> f64 { x }
11 | | }
| | ^
| | |
| |_`(f64,)`
| `(i32,)`
note: required by a bound in `foo`
--> splat-overload-diagnostics/src/bin/diag-function-return-values.rs:8:1
|
8 | / overload! {
9 | | fn foo(x: i32) -> i32 { x }
10 | | fn foo(x: f64) -> f64 { x }
11 | | }
| |_^ required by this bound in `foo`
= note: this error originates in the macro `overload` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: missing overload for arguments `(&str,)`
--> splat-overload-diagnostics/src/bin/diag-function-return-values.rs:16:9
|
16 | foo("wrong type");
| --- ^^^^^^^^^^^^ the argument types `(&str,)` do not match any overload
| |
| required by a bound introduced by this call
|
= help: the trait `FooArgs` is not implemented for `(&str,)`
= note: check for missing or extra arguments, and check argument types
= note: consider adding a new overload in the overload! { ... } block
help: the following other types implement trait `FooArgs`
--> splat-overload-diagnostics/src/bin/diag-function-return-values.rs:8:1
|
8 | / overload! {
9 | | fn foo(x: i32) -> i32 { x }
10 | | fn foo(x: f64) -> f64 { x }
11 | | }
| | ^
| | |
| |_`(f64,)`
| `(i32,)`
note: required by a bound in `foo`
--> splat-overload-diagnostics/src/bin/diag-function-return-values.rs:8:1
|
8 | / overload! {
9 | | fn foo(x: i32) -> i32 { x }
10 | | fn foo(x: f64) -> f64 { x }
11 | | }
| |_^ required by this bound in `foo`
= note: this error originates in the macro `overload` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: missing overload for arguments `(_, _, _)`
--> splat-overload-diagnostics/src/bin/diag-function-return-values.rs:18:9
|
18 | foo(1_i32, 2, 3);
| --- ^^^^^ the argument types `(_, _, _)` do not match any overload
| |
| required by a bound introduced by this call
|
= help: the trait `FooArgs` is not implemented for `(_, _, _)`
= note: check for missing or extra arguments, and check argument types
= note: consider adding a new overload in the overload! { ... } block
help: the following other types implement trait `FooArgs`
--> splat-overload-diagnostics/src/bin/diag-function-return-values.rs:8:1
|
8 | / overload! {
9 | | fn foo(x: i32) -> i32 { x }
10 | | fn foo(x: f64) -> f64 { x }
11 | | }
| | ^
| | |
| |_`(f64,)`
| `(i32,)`
note: required by a bound in `foo`
--> splat-overload-diagnostics/src/bin/diag-function-return-values.rs:8:1
|
8 | / overload! {
9 | | fn foo(x: i32) -> i32 { x }
10 | | fn foo(x: f64) -> f64 { x }
11 | | }
| |_^ required by this bound in `foo`
= note: this error originates in the macro `overload` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0308]: mismatched types
--> splat-overload-diagnostics/src/bin/diag-function-return-values.rs:20:18
|
20 | let a: i32 = foo(1.0_f64);
| --- ^^^^^^^^^^^^ expected `i32`, found `f64`
| |
| expected due to this

error[E0277]: missing overload for arguments `()`
--> splat-overload-diagnostics/src/bin/diag-function-return-values.rs:15:5
|
15 | foo();
| ^^^^^ the argument types `()` do not match any overload
|
= help: the trait `FooArgs` is not implemented for `()`
= note: check for missing or extra arguments, and check argument types
= note: consider adding a new overload in the overload! { ... } block
help: the following other types implement trait `FooArgs`
--> splat-overload-diagnostics/src/bin/diag-function-return-values.rs:8:1
|
8 | / overload! {
9 | | fn foo(x: i32) -> i32 { x }
10 | | fn foo(x: f64) -> f64 { x }
11 | | }
| | ^
| | |
| |_`(f64,)`
| `(i32,)`
= note: this error originates in the macro `overload` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: missing overload for arguments `(&str,)`
--> splat-overload-diagnostics/src/bin/diag-function-return-values.rs:16:5
|
16 | foo("wrong type");
| ^^^^^^^^^^^^^^^^^ the argument types `(&str,)` do not match any overload
|
= help: the trait `FooArgs` is not implemented for `(&str,)`
= note: check for missing or extra arguments, and check argument types
= note: consider adding a new overload in the overload! { ... } block
help: the following other types implement trait `FooArgs`
--> splat-overload-diagnostics/src/bin/diag-function-return-values.rs:8:1
|
8 | / overload! {
9 | | fn foo(x: i32) -> i32 { x }
10 | | fn foo(x: f64) -> f64 { x }
11 | | }
| | ^
| | |
| |_`(f64,)`
| `(i32,)`
= note: this error originates in the macro `overload` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: missing overload for arguments `(i32, {integer}, {integer})`
--> splat-overload-diagnostics/src/bin/diag-function-return-values.rs:18:5
|
18 | foo(1_i32, 2, 3);
| ^^^^^^^^^^^^^^^^ the argument types `(i32, {integer}, {integer})` do not match any overload
|
= help: the trait `FooArgs` is not implemented for `(i32, {integer}, {integer})`
= note: check for missing or extra arguments, and check argument types
= note: consider adding a new overload in the overload! { ... } block
help: the following other types implement trait `FooArgs`
--> splat-overload-diagnostics/src/bin/diag-function-return-values.rs:8:1
|
8 | / overload! {
9 | | fn foo(x: i32) -> i32 { x }
10 | | fn foo(x: f64) -> f64 { x }
11 | | }
| | ^
| | |
| |_`(f64,)`
| `(i32,)`
= note: this error originates in the macro `overload` (in Nightly builds, run with -Z macro-backtrace for more info)

Some errors have detailed explanations: E0277, E0308.
For more information about an error, try `rustc --explain E0277`.
error: could not compile `splat-overload-diagnostics` (bin "diag-function-return-values") due to 7 previous errors
19 changes: 19 additions & 0 deletions splat-overload-diagnostics/src/bin/diag-functions.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#![feature(splat)]
#![feature(tuple_trait)]
#![allow(incomplete_features, clippy::approx_constant)]

use splat_overload::overload;

overload! {
fn foo(_x: i32, _y: f64) {}
fn foo(_x: bool, _y: i32, _z: f64) {}
fn foo(_a: i32, _b: f64, _c: bool, _d: u8) {}
}

fn main() {
// Empty argument list
foo();
foo("one wrong type", 2.0_f64);
// Wrong number of arguments
foo(1_i32, 2_f64, true, 4_u8, 5);
}
Loading