feat: update passes to use PassScope where non-breaking#2836
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #2836 +/- ##
==========================================
- Coverage 83.83% 83.78% -0.05%
==========================================
Files 269 269
Lines 54021 54206 +185
Branches 47974 48159 +185
==========================================
+ Hits 45286 45414 +128
- Misses 6320 6378 +58
+ Partials 2415 2414 -1
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
05cf563 to
dfe5791
Compare
dfe5791 to
aa264fc
Compare
This reverts commit 89088135b6ccfd1fad058f6011aa45dc53ece95a.
aa264fc to
d7eca10
Compare
hugr-passes/src/untuple.rs
Outdated
| /// Create a new untuple pass with the given configuration | ||
| #[must_use] | ||
| pub fn new_scoped(scope: PassScope) -> Self { | ||
| Self { | ||
| scope: Either::Left(scope), | ||
| } | ||
| } |
There was a problem hiding this comment.
Do we need this? It's the same as
UntuplePass::default().with_scope(...)
There was a problem hiding this comment.
Yeah, indeed. I think it's "nice" to have everywhere, but maybe inconsistent to have it here and not everywhere else. I'll remove it here?
hugr-passes/src/replace_types.rs
Outdated
| /// Sets the scope within which the pass will operate. Note that this pass respects | ||
| /// neither [PassScope::preserve_interface] nor [PassScope::recursive] as the former | ||
| /// would be contrary to the goals of the pass and non-recursion generally leads to | ||
| /// invalid Hugrs. Hence, really only the [PassScope::root] affects the pass. |
There was a problem hiding this comment.
This makes sense, but does it mean we need to adjust the PassScope definition somehow?
There was a problem hiding this comment.
PassScope specifically says recursive==False is only a hint (recursive==True is a requirement, and we do that). So I think we're ok (within bounds of the contract), and it's merely good practice to note what we do here.
preserve_interface does mention that it only really applies to optimization passes I think, and this is not one. Have a look, perhaps it's not strong enough?
There was a problem hiding this comment.
Yes, for recursive I see no issue.
preserve_interface is a bit iffy, but I think it works if it's only for optimizations.
I'd add a note in the scope definitions making that explicit.
There was a problem hiding this comment.
See here:
hugr/hugr-passes/src/composable/scope.rs
Lines 54 to 59 in d657835
But I'll add a couple more notes
Co-authored-by: Agustín Borgna <121866228+aborgna-q@users.noreply.github.com>
|
|
||
| use super::{ComposablePass, IfThen, ValidatePassError, ValidatingPass, validate_if_test}; | ||
|
|
||
| pub(crate) fn run_validating<P: ComposablePass<H>, H: HugrMut>( |
There was a problem hiding this comment.
I mean, this could be outside test, even public; it's a simple-enough utility function
hugr-passes/src/lib.rs
Outdated
There was a problem hiding this comment.
| #[expect(deprecated)] | |
| pub use monomorphize::{MonomorphizePass, mangle_name, monomorphize}; |
## 🤖 New release * `hugr-model`: 0.25.6 -> 0.25.7 (✓ API compatible changes) * `hugr-core`: 0.25.6 -> 0.25.7 (✓ API compatible changes) * `hugr-llvm`: 0.25.6 -> 0.25.7 (✓ API compatible changes) * `hugr-passes`: 0.25.6 -> 0.25.7 (✓ API compatible changes) * `hugr-persistent`: 0.4.6 -> 0.4.7 (✓ API compatible changes) * `hugr`: 0.25.6 -> 0.25.7 (✓ API compatible changes) * `hugr-cli`: 0.25.6 -> 0.25.7 (✓ API compatible changes) <details><summary><i><b>Changelog</b></i></summary><p> ## `hugr-model` <blockquote> ## [0.25.6](hugr-model-v0.25.5...hugr-model-v0.25.6) - 2026-02-20 ### New Features - Remove size limitation for binary envelopes ([#2880](#2880)) </blockquote> ## `hugr-core` <blockquote> ## [0.25.7](hugr-core-v0.25.6...hugr-core-v0.25.7) - 2026-03-06 ### Documentation - added examples in docs srtring ([#2920](#2920)) </blockquote> ## `hugr-llvm` <blockquote> ## [0.25.6](hugr-llvm-v0.25.5...hugr-llvm-v0.25.6) - 2026-02-20 ### New Features - Add error context when lowering hugrs to LLVM ([#2869](#2869)) </blockquote> ## `hugr-passes` <blockquote> ## [0.25.7](hugr-passes-v0.25.6...hugr-passes-v0.25.7) - 2026-03-06 ### Documentation - added examples in docs srtring ([#2920](#2920)) ### New Features - Define pass application scopes ([#2772](#2772)) - Modify dead code elimination pass to remove unreachable basic blocks ([#2884](#2884)) - Add non-generic `with_scope` method for composable passes ([#2910](#2910)) - update passes to use PassScope where non-breaking ([#2836](#2836)) </blockquote> ## `hugr-persistent` <blockquote> ## [0.4.0](hugr-persistent-v0.3.4...hugr-persistent-v0.4.0) - 2025-12-22 ### New Features - [**breaking**] Remove `RootCheckable` ([#2704](#2704)) - [**breaking**] Bump MSRV to Rust 1.89 ([#2747](#2747)) - [**breaking**] Type-safe access for node metadata ([#2755](#2755)) ### Refactor - [**breaking**] Remove multiple deprecated definitions ([#2751](#2751)) </blockquote> ## `hugr` <blockquote> ## [0.25.7](hugr-v0.25.6...hugr-v0.25.7) - 2026-03-06 ### Documentation - added examples in docs srtring ([#2920](#2920)) ### New Features - Define pass application scopes ([#2772](#2772)) - Modify dead code elimination pass to remove unreachable basic blocks ([#2884](#2884)) - Add non-generic `with_scope` method for composable passes ([#2910](#2910)) - update passes to use PassScope where non-breaking ([#2836](#2836)) </blockquote> ## `hugr-cli` <blockquote> ## [0.25.6](hugr-cli-v0.25.5...hugr-cli-v0.25.6) - 2026-02-20 ### New Features - Add s expression format to envelope formats ([#2864](#2864)) </blockquote> </p></details> --- This PR was generated with [release-plz](https://github.com/release-plz/release-plz/).
…_scope (#2871) Following #2836, the remaining passes, where breakage was inevitable - mostly passes that were an empty struct (without any previous config). Non-local-edges stuff needed some API changes where I did some deprecation, but we could just break. RedundantOrderEdgesPass I've removed the old config methods - we should perhaps deprecate first, but some breakage seems inevitable as the empty struct derived Copy. LocalizeEdges I've deprecated+moved top-level `ensure_no_nonlocal_edges` into a struct method `check_no_nonlocal_edges`, as IIUC it's used, but I've removed top-level `nonlocal_edges` altogether, it doesn't seem to be used. Also remove the default impl for `ComposablePass::with_scope_internal`, to check we got 'em all. BREAKING CHANGE: InlineDFGsPass, LocalizeEdgesPass, MonomorphizePass, RedundantOrderEdgesPass must be constructed via ::default(); remove RedundantOrderEdgesPass::recursive and don't derive Copy; ComposablePass::with_scope_internal requires impl; remove toplevel `fn nonlocal_edges`
Adds support for `PassScope`s in the pass definitions. See Quantinuum/hugr#2772. ~Requires a hugr release with the `PassScope` definition and Quantinuum/hugr#2910 ~Many of these also call other passes from `hugr_passes`. While we pass the scope config along, proper support requires Quantinuum/hugr#2836 and Quantinuum/hugr#2871 This is a rust-only change, the python interface will follow up. BREAKING CHANGE: Multiple unit-like pass structs must now be constructed using a `::default()` call instead. BREAKING CHANGE: `QSystemPass` is now a `ComposablePass`. Import the trait to call `run`. BREAKING CHANGE: `QSystemPass` no longer implements `Copy`. BREAKING CHANGE: Renamed `tket_qsystem::extension::qsystem::lower_tket_op` to `lower_tket_ops`.
Follow-up to #2772 with non-breaking updates to ConstFoldPass, DeadCodeElimPass, NormalizeCFGsPass, RedundantOrderEdgesPass, RemoveDeadFuncsPass, ReplaceTypes, UntuplePass. (Breaking updates to follow in #2871.)
Generally this means keeping pre-existing pass configurating methods but deprecating, and storing such config in an
Either<PassScope, old-config>, so we can drop the old config in time.Also deprecated toplevel functions
constant_fold_pass,remove_dead_funcsandmonomorphize.