Skip to content

feat(ffi): export another crate's items where the API re-exports them - #72

Closed
kixelated wants to merge 1 commit into
quest/m1/ffi-exportfrom
ffi-export/reexports
Closed

kixelated wants to merge 1 commit into
quest/m1/ffi-exportfrom
ffi-export/reexports

Conversation

@kixelated

Copy link
Copy Markdown
Collaborator

Stacked on kixelated/rust2#71 (the moq pin bump), for quest/m1/ffi-export.md's "Several crates" bullet.

Problem

"Foreign type" is the census's largest refusal on moq-net. moq-net re-exports moq-pattern's Pattern, Patterns, InvalidPattern, Segment, and Specificity, and moq-clock's Instant, and names them in its API: origin::Producer::scope and allowed, auth::Grant's fields, stats::Config::exclude, server::Handshake::with_deadline, frame::Frame::arrived. The exporter refused every re-export of another crate's item, and so every signature naming one. moq-ffi uses scope and Grant today.

Approach

  • A re-exported item of another crate is walked like a local one, at its re-export path. rustc's queries (ADT shape, inherent impls, visibility, docs) work across crates, and the glue already reaches moq-net from outside, so the glue needed no change.
  • A signature naming another crate's type maps when the API re-exports it, and stays a foreign type refusal otherwise.
  • A re-exported module of another crate (pub use kio;, pub use bytes;) stays refused, now as re-export of another crate's module: its API is that crate's own export.
  • Tests: a dep fixture crate whose record and object the api fixture re-exports and names. The C transcript drives them and must match the native one. The reject fixture refuses pub use dep;. moq/moq.c now scopes an origin with moq-pattern's patterns, so root and absolute show a real root.

moq-net census at the pinned revision:

Before After
Types exported 136 142
Methods and fields exported 532 575
Constants exported 5 7
foreign type refusals 24 18
exclude entries 97 88

The new excludes are the moq-pattern and moq-clock methods that do not map (Pattern::new's generic, Patterns::iter, Instant::from_std, ...).

Decisions needed

  1. Whose names re-exported types take in C. moq-pattern's types are now moq_pattern/moq_patterns, and moq-clock's Instant is moq_time_instant, all through moq-net's export.
    • A: export at the re-export path (this PR, recommended). Unblocks moq-net's scoping and auth API now. It also holds later: once several crates export into one library, a re-export of an item that another export owns becomes a name for that type, and items no export owns keep exporting here.
    • B: each crate is its own export, as the quest bullet sketched: moq-pattern and moq-clock get their own ffi.toml and census, and moq-net's re-exports name their types. This needs the several-crates machinery first (IR shared between rustc invocations, one glue crate), which is an L on its own. Until then, these refusals stay.
    • C: A only for types a signature needs, leaving unused re-exports refused. This saves some header lines, but a re-export is public API, so it adds an inclusion rule for no consumer.

Impact

  • rust2-ffi: another crate's item that the API re-exports is now exported. The re-export of another crate's item refusal is now re-export of another crate's module, for modules only. Documented in ffi/README.md.

Checks

  • just check, just test: pass.
  • just ffi moq and just ffi census at the pinned moq: pass.

Alternatives

  • Treat a re-export like a type alias, exporting nothing. Every signature naming the type would still be refused.

Follow-ups

  • A re-export of a type the rules already map, such as pub use bytes::Bytes, would also export it as an object. No moq crate does this; if one does, its methods fail loud in the census.
  • The quest bullet now says what remains: exporting moq-tokio and the media crates into one library.

(written by Opus 5.5)

🤖 Generated with Claude Code

https://claude.ai/code/session_0115AT2ue6x9cT5e5J9SZtCn

moq-net re-exports moq-pattern's Pattern and Patterns and moq-clock's
Instant, and names them in scope, allowed, Grant, and with_deadline.
The census refused all of them as foreign types. A re-exported item now
exports at its re-export path, and a signature naming it resolves to
that export. A re-exported module of another crate stays refused.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0115AT2ue6x9cT5e5J9SZtCn
@kixelated

Copy link
Copy Markdown
Collaborator Author

Closing: the maintainer chose option B. moq-pattern and moq-clock become their own exports, and moq-net's signatures name their types across crates, instead of exporting them at moq-net's re-export path. That work continues under quest/m1/ffi-export.md's "Several crates" bullet.

(written by Opus 5.5)

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.

1 participant