From 5a5a486d8735ce95b7beeb1550da2d8dc9be5a82 Mon Sep 17 00:00:00 2001 From: Rain Date: Sat, 21 Dec 2024 23:39:55 -0800 Subject: [PATCH] [ci] enable non_exhaustive_omitted_patterns lint with a nightly check (#358) This lint is useful to detect missed match statements. Also add a Justfile to make this easy to run. --- .cargo/nightly-config.toml | 18 ++++++++++++++++++ .github/workflows/ci.yml | 6 +++++- Cargo.toml | 2 +- Justfile | 13 +++++++++++++ guppy/tests/graph-tests/graph_tests.rs | 17 ++++++++++------- guppy/tests/graph-tests/invalid_tests.rs | 16 ++++++++++------ tools/cargo-hakari/src/command.rs | 9 ++++++++- tools/hakari/Cargo.toml | 3 +++ tools/hakari/src/cli_ops/initialize.rs | 1 + 9 files changed, 69 insertions(+), 16 deletions(-) create mode 100644 .cargo/nightly-config.toml create mode 100644 Justfile diff --git a/.cargo/nightly-config.toml b/.cargo/nightly-config.toml new file mode 100644 index 00000000000..c991758af4b --- /dev/null +++ b/.cargo/nightly-config.toml @@ -0,0 +1,18 @@ +# Extra configuration for nightly Rust. +# +# Use manually by passing this path into `--config`, or via the Justfile: `just +# nightly check` or `just bootstrap check`. + +[build] +# Detect if non-exhaustive patterns are missing: +# https://github.com/rust-lang/rust/issues/89554 +# +# To allow this lint for some statements, use +# `#[cfg_attr(guppy_nightly, expect(non_exhaustive_omitted_patterns))]`. +rustflags = [ + "--warn", + "non_exhaustive_omitted_patterns", + "-Zcrate-attr=feature(non_exhaustive_omitted_patterns_lint)", + "--cfg", + "guppy_nightly", +] diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e189f90cc7a..bfb15f71bf4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,8 +20,12 @@ jobs: with: components: rustfmt, clippy - uses: Swatinem/rust-cache@82a92a6e8fbeee089604da2575dc567ae9ddeaab # v2 + - name: Install just + uses: taiki-e/install-action@just - name: Lint (clippy) - run: cargo clippy --all-features --all-targets + run: just bootstrap clippy + env: + RUSTC_BOOTSTRAP: 1 - name: Install cargo-hack uses: taiki-e/install-action@cargo-hack - name: Lint (rustfmt) diff --git a/Cargo.toml b/Cargo.toml index 842f01d2afd..2b25a320fec 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,7 +29,7 @@ miette = "7.2.0" rust-version = "1.78" [workspace.lints.rust] -unexpected_cfgs = { level = "warn", check-cfg = ['cfg(doc_cfg)'] } +unexpected_cfgs = { level = "warn", check-cfg = ['cfg(doc_cfg)', 'cfg(guppy_nightly)'] } [patch.crates-io.guppy-workspace-hack] path = "workspace-hack" diff --git a/Justfile b/Justfile new file mode 100644 index 00000000000..546c3ff81df --- /dev/null +++ b/Justfile @@ -0,0 +1,13 @@ +# Note: help messages should be 1 line long as required by just. + +# Print a help message. +help: + just --list + +# Run the nightly check command: `just nightly check` or `just nightly clippy --fix` +nightly arg1 *args: + cargo +nightly {{arg1}} {{args}} --all-features --all-targets --config .cargo/nightly-config.toml + +# Run with nightly features enabled: `just bootstrap check`, `just bootstrap +beta clippy` +bootstrap arg1 *args: + RUSTC_BOOTSTRAP=1 cargo {{arg1}} {{args}} --all-features --all-targets --config .cargo/nightly-config.toml diff --git a/guppy/tests/graph-tests/graph_tests.rs b/guppy/tests/graph-tests/graph_tests.rs index e8d7a48ccf2..02a62d00fd2 100644 --- a/guppy/tests/graph-tests/graph_tests.rs +++ b/guppy/tests/graph-tests/graph_tests.rs @@ -331,13 +331,16 @@ mod small { .metadata(&package_id(json::METADATA_PROC_MACRO1_MACRO)) .expect("valid package ID"); assert!(package.is_proc_macro(), "is proc macro"); - assert!(matches!( - package - .build_target(&BuildTargetId::Library) - .expect("library package is present") - .kind(), - BuildTargetKind::ProcMacro - )); + + let build_target_kind = package + .build_target(&BuildTargetId::Library) + .expect("library package is present") + .kind(); + assert_eq!( + build_target_kind, + BuildTargetKind::ProcMacro, + "build target kind matches" + ); } // No need for proptests because this is a really simple test. diff --git a/guppy/tests/graph-tests/invalid_tests.rs b/guppy/tests/graph-tests/invalid_tests.rs index 1b423455ee3..17d07d8eb48 100644 --- a/guppy/tests/graph-tests/invalid_tests.rs +++ b/guppy/tests/graph-tests/invalid_tests.rs @@ -109,12 +109,16 @@ fn proc_macro_mixed_kinds() { fn assert_invalid(json: &str, search_str: &str) { let err = PackageGraph::from_json(json).expect_err("expected error for invalid metadata"); + let Error::PackageGraphConstructError(s) = err else { + panic!( + "expected PackageGraphConstructError, got: {} ({:?}", + err, err + ); + }; assert!( - matches!( - err, - Error::PackageGraphConstructError(ref s) if s.contains(search_str), - ), - "actual error is: {}", - err, + s.contains(search_str), + "expected error to contain '{}', got: {}", + search_str, + s ); } diff --git a/tools/cargo-hakari/src/command.rs b/tools/cargo-hakari/src/command.rs index a9ec3f83e08..e587956742b 100644 --- a/tools/cargo-hakari/src/command.rs +++ b/tools/cargo-hakari/src/command.rs @@ -306,7 +306,14 @@ impl CommandWithBuilder { // 102 is picked pretty arbitrarily because regular errors exit with 101. return Ok(102); } - Err(err) => Err(err).with_context(|| "error generating new hakari.toml")?, + Err( + err @ TomlOutError::Platform(_) + | err @ TomlOutError::Toml { .. } + | err @ TomlOutError::FmtWrite(_) + | err @ TomlOutError::UnrecognizedExternal { .. } + | err @ TomlOutError::PathWithoutHakari { .. } + | err, + ) => Err(err).with_context(|| "error generating new hakari.toml")?, }; let existing_toml = hakari diff --git a/tools/hakari/Cargo.toml b/tools/hakari/Cargo.toml index 1090d8137dd..99bc4887a59 100644 --- a/tools/hakari/Cargo.toml +++ b/tools/hakari/Cargo.toml @@ -21,6 +21,9 @@ rust-version.workspace = true all-features = true rustdoc-args = ["--cfg=doc_cfg"] +[lints] +workspace = true + [dependencies] ahash = "0.8.11" atomicwrites = "0.4.4" diff --git a/tools/hakari/src/cli_ops/initialize.rs b/tools/hakari/src/cli_ops/initialize.rs index 61dc36884a6..2df8019de6d 100644 --- a/tools/hakari/src/cli_ops/initialize.rs +++ b/tools/hakari/src/cli_ops/initialize.rs @@ -60,6 +60,7 @@ impl<'g, 'a> HakariInit<'g, 'a> { // The path exists. return Err(InitError::WorkspacePathExists { abs_path }); } + #[cfg_attr(guppy_nightly, expect(non_exhaustive_omitted_patterns))] Err(err) => match err.kind() { io::ErrorKind::NotFound => {} _ => {