Wado

WEP: Re-export Syntax (pub use)

Context

Wado needs a way to re-export symbols from other modules. This is a common pattern in module systems where a library wants to expose items from its dependencies or internal modules as part of its public API.

Terminology

Wado distinguishes between two kinds of "public":

Keyword Term Meaning
pub module public Visible to other Wado modules that import this module
export world export Exposed at the Component Model boundary (WASI world conformance)

The pub use syntax combines module public visibility with import, creating a re-export.

Motivation

Without re-export, users must import from the original source:

// math/internal/trig.wado
pub fn sin(x: f64) -> f64 { ... }
pub fn cos(x: f64) -> f64 { ... }

// math/internal/exp.wado
pub fn exp(x: f64) -> f64 { ... }
pub fn log(x: f64) -> f64 { ... }

// User must know internal structure
use {sin, cos} from "math/internal/trig.wado";
use {exp, log} from "math/internal/exp.wado";

With re-export, the library can provide a unified API:

// math/mod.wado
pub use {sin, cos} from "./internal/trig.wado";
pub use {exp, log} from "./internal/exp.wado";

// User imports from the public API
use {sin, cos, exp, log} from "math";

Decision

Syntax

Re-export uses pub use followed by the standard import syntax:

// Re-export specific items
pub use {foo, bar} from "./internal.wado";

// Re-export with rename
pub use {internal_name as public_name} from "./internal.wado";

// Re-export from core/wasi modules
pub use {Option, Result} from "core:prelude";
pub use {Stdout} from "wasi:cli";

Semantics

  1. pub use makes imported symbols available to modules that import this module
  2. The re-exported symbol behaves identically to the original
  3. Re-exports are resolved at compile time (no runtime cost)
  4. Circular re-exports are prohibited

Visibility Levels

Declaration Within module Other Wado modules CM world boundary
fn foo() Yes No No
pub fn foo() Yes Yes No
export fn foo() Yes Yes Yes
use {x} from "..." Yes No -
pub use {x} from "..." Yes Yes -

Restrictions

  1. A re-export names only an item the module can import, and gives it no more reach than the item has.
  2. export use is a compile error. A re-export stays at module level and never reaches the CM boundary.
  3. A namespace cannot be re-exported, so pub use utils from … and internal use utils from … are compile errors. use utils from "./utils.wado" names a module, not an item. Re-export the members by name instead: pub use { helper } from "./utils.wado".
  4. A wildcard cannot be re-exported, so pub use _ from … and internal use _ from … are compile errors. use _ from binds no name.

Consequences

Positive

Negative

Implementation Notes

  1. Parser: Extend use statement to accept optional pub prefix
  2. Symbol table: Track re-export relationships
  3. Name resolution: Follow re-export chains during lookup
  4. Error reporting: Include re-export path in "symbol not found" errors

Implementation Status

Implemented. Key components:

First use case: i128/u128 types are defined in core:prelude/int128 and re-exported from core:prelude.