#Names
This document defines the currently implemented Masterbelt name binding, scope, visibility, and reference resolution behavior.
The name model is intentionally minimal at this stage. Future namespace, module, import, and reference additions must extend this document before or together with implementation changes.
#Scopes
A scope is a region that can contain bindings.
A source file creates one file scope.
At this stage, file scopes do not have parent scopes.
#Binding Spaces
A binding space is a category of names that are checked for uniqueness together within a scope.
The implemented binding spaces are the value binding space and the type binding space.
A value binding space contains names that refer to runtime values such as constants and, in the future, functions.
A type binding space contains names that refer to types such as type declarations. Built-in type names are not bindings; they are language-level reservations that any type expression position may reference.
A name may be bound in the value binding space and the type binding space of the same scope without conflict.
#Bindings
A binding associates a name with a declaration in a binding space and scope.
The implemented binding forms are const item bindings, type declaration bindings, and import bindings.
Each const item introduces one binding in the value binding space of the containing file scope.
Each type declaration introduces one binding in the type binding space of the containing file scope.
Each named entry of a use or re-export declaration introduces one binding in both the value and the type binding space of the containing file scope under the entry's local name. The binding records the originating module source string and the foreign symbol name so later phases can resolve the reference once the foreign module is available. Whether the symbol exists in the value space, the type space, or both is determined at cross-module resolution; the binding's presence in both spaces lets a reference reach it from either position without re-parsing the import.
A re-exporting declaration adds the public flag to each introduced import binding.
A use * or re-export * declaration does not introduce per-name bindings; it records a wildcard request that later phases expand once the foreign module is loaded. Duplicate-name conflicts caused by wildcard expansion are detected at the cross-module resolution phase, not at file resolution.
const A = 1
const (
B = 2
C = 3
)
type ID = int
use { D, E as F } from "./other.mst"
pub * from "./shared.mst"
This source file introduces the value bindings A, B, C, D, and F and the type bindings ID, D, and F in the file scope, plus a wildcard re-export from ./shared.mst whose contents are expanded by the cross-module loader.
#Duplicate Names
A scope cannot contain more than one binding with the same name in the same binding space.
Duplicate bindings are name resolution errors. The diagnostic is reported on the later binding name.
When duplicate bindings occur in a scope, the first binding is canonical and later duplicates are not exposed for reference resolution.
#Visibility
A binding introduced by a pub declaration is public. Without pub, the binding is private to its file.
For grouped const declarations, the outer visibility applies to every const item binding in the group.
A type declaration may be pub. Public type bindings follow the same visibility model as public value bindings.
A re-export declaration (pub { ... } from "..." or pub * from "...") is public. The imported names become public bindings of the current file scope, available for cross-module lookup under their local names.
A plain use declaration is not public. The imported names are private to the current file even when the foreign symbols are themselves public.
#References
An identifier reference in expression position resolves to a binding in the value binding space of the enclosing scope.
A reference must resolve to a binding that appears earlier in source order than the reference itself. Forward references, including a binding referencing itself, are name resolution errors. This restriction keeps lowering single-pass at the current stage and may be relaxed once topological dependency analysis is implemented.
A reference that does not resolve to any value binding is a name resolution error.
Type-position references to type declarations are resolved separately in the type binding space. The value and type binding spaces are independent.