Skip to content

feat(ptr)!: support linear values with explicit pointer ownership - #3282

Open
doug-q wants to merge 6 commits into
mainfrom
doug/linear-pointers
Open

doug-q wants to merge 6 commits into
mainfrom
doug/linear-pointers

Conversation

@doug-q

@doug-q doug-q commented Sep 30, 2026 •

Copy link
Copy Markdown
Collaborator

Make ptr<T> a linear handle to shared mutable storage, including storage of linear values. Read and Write require copyable values and return the pointer; Swap, Dup, Free, and row-polymorphic Map preserve explicit ownership. The last Free returns the stored value.

Add Eq<T>: (ptr<T>, ptr<T>) -> (ptr<T>, ptr<T>, bool). It compares cell identity, returns both linear handles in input order, and neither reads nor compares the stored values. Both inputs have the same element type, which may be linear.

Provide concrete Rust operations and builders for all eight operations, document ownership and pointer dependency ordering, and regenerate both Rust/Python declaration copies as ptr 0.2.0. Runtime implementations must implement the new operation contract.

Latest local validation: 718 core unit tests passed (4 ignored), including signatures, extension round trips, mixed-type rejection, and rejection of copied/dropped Eq outputs; 4 Python pointer tests passed; all-target core Clippy, all-feature core rustdoc with warnings denied, workspace formatting, locked Ruff 0.6.9, and extension-version checks passed. The pinned Nix shell and lockfiles were unchanged. Remote CI supplies the broader cross-language and semver checks.

BREAKING CHANGE: ptr<T> is now linear. Thread the pointer returned by Read/Write, use Dup for shared handles, and release every handle with Free, handling its optional value. Rust callers must consume the updated builder results and construct operations with PtrOpDef::with_type or PtrOp::map instead of the old two-field PtrOp literal. Runtime implementations must support the ptr 0.2.0 signatures and operations.

@codecov

codecov Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 96.86520% with 10 lines in your changes missing coverage. Please review.
✅ Project coverage is 82.17%. Comparing base (0202557) to head (523ac61).

Files with missing lines Patch % Lines
hugr-core/src/std_extensions/ptr.rs 96.86% 1 Missing and 9 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3282      +/-   ##
==========================================
+ Coverage   82.05%   82.17%   +0.11%     
==========================================
  Files         245      245              
  Lines       47553    47847     +294     
  Branches    41144    41438     +294     
==========================================
+ Hits        39020    39316     +296     
+ Misses       6629     6620       -9     
- Partials     1904     1911       +7     
Flag Coverage Δ
python 89.57% <ø> (+0.04%) ⬆️
rust 81.02% <96.86%> (+0.13%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@hugrbot

hugrbot commented Sep 30, 2026 •

Copy link
Copy Markdown
Collaborator

This PR contains breaking changes to the public Rust API.

cargo-semver-checks summary
    Building hugr v0.30.3 (current)
     Built [  35.352s] (current)
   Parsing hugr v0.30.3 (current)
    Parsed [   0.002s] (current)
  Building hugr v0.30.3 (baseline)
     Built [  35.754s] (baseline)
   Parsing hugr v0.30.3 (baseline)
    Parsed [   0.002s] (baseline)
  Checking hugr v0.30.3 -> v0.30.3 (assume minor change)
   Checked [   0.014s] 202 checks: 202 pass, 58 skip
   Summary no semver update required
  Finished [  72.715s] hugr
  Building hugr-cli v0.30.3 (current)
     Built [  29.727s] (current)
   Parsing hugr-cli v0.30.3 (current)
    Parsed [   0.005s] (current)
  Building hugr-cli v0.30.3 (baseline)
     Built [  29.616s] (baseline)
   Parsing hugr-cli v0.30.3 (baseline)
    Parsed [   0.004s] (baseline)
  Checking hugr-cli v0.30.3 -> v0.30.3 (assume minor change)
   Checked [   0.018s] 202 checks: 202 pass, 58 skip
   Summary no semver update required
  Finished [  60.198s] hugr-cli
  Building hugr-core v0.30.3 (current)
     Built [  25.762s] (current)
   Parsing hugr-core v0.30.3 (current)
    Parsed [   0.097s] (current)
  Building hugr-core v0.30.3 (baseline)
     Built [  25.598s] (baseline)
   Parsing hugr-core v0.30.3 (baseline)
    Parsed [   0.088s] (baseline)
  Checking hugr-core v0.30.3 -> v0.30.3 (assume minor change)
   Checked [   0.278s] 202 checks: 201 pass, 1 fail, 0 warn, 58 skip

--- failure constructible_struct_adds_field: struct exhaustively constructible through public API adds field ---

Description:
A pub struct that could be exhaustively constructed with a literal using only public API has a new pub field, breaking existing exhaustive literals.
      ref: https://doc.rust-lang.org/reference/expressions/struct-expr.html
     impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.51.0/src/lints/constructible_struct_adds_field.ron

Failed in:
field PtrOp.map_signature in /home/runner/work/hugr/hugr/PR_BRANCH/hugr-core/src/std_extensions/ptr.rs:227

   Summary semver requires new major version: 1 major and 0 minor checks failed
  Finished [  52.715s] hugr-core
  Building hugr-llvm v0.30.3 (current)
     Built [  29.438s] (current)
   Parsing hugr-llvm v0.30.3 (current)
    Parsed [   0.011s] (current)
  Building hugr-llvm v0.30.3 (baseline)
     Built [  29.294s] (baseline)
   Parsing hugr-llvm v0.30.3 (baseline)
    Parsed [   0.011s] (baseline)
  Checking hugr-llvm v0.30.3 -> v0.30.3 (assume minor change)
   Checked [   0.045s] 202 checks: 202 pass, 58 skip
   Summary no semver update required
  Finished [  59.523s] hugr-llvm
  Building hugr-model v0.30.3 (current)
     Built [  10.329s] (current)
   Parsing hugr-model v0.30.3 (current)
    Parsed [   0.016s] (current)
  Building hugr-model v0.30.3 (baseline)
     Built [  10.333s] (baseline)
   Parsing hugr-model v0.30.3 (baseline)
    Parsed [   0.016s] (baseline)
  Checking hugr-model v0.30.3 -> v0.30.3 (assume minor change)
   Checked [   0.033s] 202 checks: 202 pass, 58 skip
   Summary no semver update required
  Finished [  21.154s] hugr-model
  Building hugr-persistent v0.7.12 (current)
     Built [  22.003s] (current)
   Parsing hugr-persistent v0.7.12 (current)
    Parsed [   0.007s] (current)
  Building hugr-persistent v0.7.12 (baseline)
     Built [  21.895s] (baseline)
   Parsing hugr-persistent v0.7.12 (baseline)
    Parsed [   0.007s] (baseline)
  Checking hugr-persistent v0.7.12 -> v0.7.12 (assume minor change)
   Checked [   0.015s] 202 checks: 202 pass, 58 skip
   Summary no semver update required
  Finished [  44.498s] hugr-persistent

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟢 Approval recommended

The ownership contract, generated declarations, builders, documentation, and tests are internally consistent.

Review effort: Balanced
Findings: None

What changed in this PR

Makes ptr<T> a linear handle with explicit ownership and support for linear stored values.

Changes:

  • Adds Swap, Dup, Free, and row-polymorphic Map.
  • Updates Rust builders, signatures, ownership documentation, and tests.
  • Regenerates Rust/Python declarations as ptr 0.2.0.
File Description
specification/​stdlib.md Documents pointer ownership and operation semantics.
resources/​std_extensions/​ptr.json Defines the 0.2.0 extension schema.
hugr-py/​tests/​test_ptr.py Tests linear bounds and operation availability.
hugr-py/​src/​hugr/​std/​ptr.py Updates pointer documentation.
hugr-py/​src/​hugr/​std/​_json_defs/​ptr.json Updates Python’s bundled extension definition.
hugr-core/​src/​std_extensions/​ptr.rs Implements operations, builders, signatures, and tests.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

//! passing the pointer returned by one operation into the next makes the next
//! operation wait for the first to finish. After [`PtrOpDef::Dup`], operations on
//! the separate handles have unspecified order unless another dependency orders
//! them. Sharing a cell does not itself establish an execution order.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this last sentence just repeating the previous sentence or is it saying something different?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's just repeating the previous sentance. for "clarity". Better to remove?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I think it's better to remove, to keep the docs succinct.

Comment on lines +8 to +10
//! Pointer handles are threaded through operations to establish their order:
//! passing the pointer returned by one operation into the next makes the next
//! operation wait for the first to finish. After [`PtrOpDef::Dup`], operations on

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this different from the sematics of value edges in general, i.e. are we putting stricter requirements on the ordering of operations involving Ptr<T> than we are on other operations? If so, how will we enforce this?

I remember some discussion with @acl-cqc about whether operations with child graphs were always atomic, but I don't remember where we landed.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No it's not different from value edges in general. This just states the hugr semantics specialised to this extension.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again I would say remove this explanation then, since it is just general hugr semantics.

@codspeed

codspeed Bot commented Oct 1, 2026 •

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 45 untouched benchmarks


Comparing doug/linear-pointers (523ac61) with main (0202557)

Open in CodSpeed

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants