enlightware / enlightware/ferlium

Add support for re-exporting symbols (`pub use`)

Open
#105 0 comments 0 reactions 0 assignees View on GitHub
hir parsing
Dominant language
Rust
Stars
14
Forks
2
PR merge metrics
No merged PRs in 30d

Description

## Motivation

Supporting **re-exports** would make it possible to split large modules (notably `std`) into smaller internal modules while keeping a clean, stable public API.

This is especially useful given Ferlium’s **per-module compilation** model: re-exports allow a module to define its public surface explicitly without flattening everything into a single source file.

Rust supports this via `pub use`, and matching this model would be beneficial and familiar.

## Goal (v1)

Add support for **named public re-exports**:

pub use std::math::sqrt;
pub use std::string::{len, concat};

This allows a module to expose symbols defined in other modules as part of its own public interface.

## Non-goals (for v1)

To keep the feature small and manageable:

- No `pub use module::*` (glob re-exports)
- No `as` renaming (see #103)
- No advanced visibility / privacy model beyond “public export”

These can be added later without breaking the design.

## Proposed design (high level)

### 1. Syntax / AST

Reuse the existing `use` syntax, but allow a visibility flag:

pub use path::symbol;

`UseTree` remains structural; visibility is attached at the `use` declaration level.

### 2. Module interface / exports

Extend the compiled module interface with explicit export bindings. To start easy, there could simply be a re-export table in a module.

A re-export is an alias, not a copy.

### 3. Compilation strategy (per-module)

When compiling a module:

1. Collect local exports (functions, types, etc.).
2. Process `pub use` declarations:
- Ensure the target module is available.
- Ensure the target symbol is exported by that module.
- Add a re-export entry to the export table.
- Error on name conflicts (same rules as explicit imports / local defs).

### 4. Import resolution impact

Existing import resolution (`use x::y`) should consult the module’s **export table**:

- Whether `y` is local or re-exported is transparent to the importer.
- Re-export chains may be followed during resolution (with cycle protection).

Callbacks like:
- `import_exists`
- `list_importable_symbols`

should operate on exported names (locals + re-exports).

Contributor guide

Open the contributing guide

Research direction

Start by tracing the existing use syntax and the import_exists and list_importable_symbols callbacks. Define how the module interface records local exports and named pub use bindings, then verify resolution handles exported names, conflicts, re-export chains, and cycle protection as described in the issue.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.