- It gets parsed and becomes a
qsc_ast::Namespace
.- A namespace is an AST node, so it has a Node ID, as well as a span, the namespace name, and the contained items within.
qsc_frontend::compile::resolve_all
produces anIndexMap
of globals callednames
, which contains all knownNodeId
s and their resolutions (Res
s), including Namespaces. (compile.rs line 357). Namespaces are now contained in the globals.- During resolution, both the AST and the HIR exist simultaneously, and AST NodeIds are mapped to HIR LocalItemIds.
- The namespace gets lowered (frontend/lower.rs
fn lower_namespace
). The namespace's HIR ItemId already exists, as it was mapped in step 2.- All items within the namespace are lowered, and their parent is set to the current namespace being lowered.
- The ident for the namespace name itself is lowered into an
hir::Ident
. - A new
hir::Item
is created for the namespace and inserted intoWith.lowerer.items
, and all of its lowered items are contained in thehir::ItemKind
. Notably, this is the second copy of the namespace, as its unlowered variant is already contained inWith.names
.
- Passes don't do anything to namespaces.
- In FIR (lowering happens in
qsc_eval
, notqsc_fir
), namespaces are lowered infn lower_item
. They are not flattened, rather, their items are just converted into FIR items and the namespace is preserved.
HIR has a PackageIter
, which iterates over the public API of a package. Any top-level namespaces without parents are included in this list. FIR has a copy/pasted implementation of this.
In HIR and FIR, types and terms are stored with respect to their top-level namespace. If we are able to flatten namespaces before we get to HIR and FIR, the impact of this change on the compiler pipeline will be significantly reduced.
Opens are handled in resolve.rs
, in fn resolve()
, where symbols are looked up within open statements according to shadowing rules.
I think we can leverage existing compiler infra to accomplish this. In HIR, Namespace
items (in HIR's ItemKind
) contain a vector of LocalItemId
s. LocalItemId
s are mapped to Item
s in qsc_hir/hir.rs
-- the struct Package
contains it in its field items
. Item
s contain an ItemKind
, which can be another namespace. So, we can already support nested namespaces in some ways. However, these nested namespaces are not accessible via any sort of open
mechanism, because the only two ways to access content from namespaces today is to open a global namespace or reference an item as fully-qualified. So, we need to add resolution logic to make these namespaces accessible in resolve.rs
(probably in fn resolve()
, where symbols are looked up according to shadowing logic), add appropriate parsing logic to understand nested names, and construct them as such in the HIR. Typeck et al operate on HIR, so this should "Just Work".