Visibility and re-exports
pub
A declaration without pub is private to its file. Put pub in front to
let other files import it:
pub const WIDTH = 8
pub macro nop() { ... }
pub struct Point { ... }
pub enum Endian { ... }
pub type Reg = bits<5>
pub start: # a label
Struct fields have their own pub. See Struct fields.
pub const PUBLIC = 1
const PRIVATE = 2
from .lib import PRIVATE
has no `PRIVATE`
Re-exporting with pub from
pub from ... import imports names and exports them again, as if this
file had declared them. That’s how a dialect presents an instruction set
plus its own syntax as one module:
std.riscv.nativedoespub from .impl import *, and adds conventional syntax.std.x86_64.nasmre-exportsstd.x86_64.intel, which re-exportsstd.x86_64.impl.
A program then imports just the dialect.
pub const BASE = 100
pub macro show(value: int) {
@emit value
}
pub from .base import *
pub const EXTRA = 5
from .extended import *
show BASE + EXTRA
105
When names collide
Your own declarations win. A file’s own declaration hides an imported
one with the same name. So adding a new pub name to a library can’t break
a file that already uses that name.
from .base import show
const BASE = 7
show BASE
7
Two imports of one name are ambiguous, but only if you use it. If two
modules both export BASE, and a file imports both with *, using BASE is
an error that names both modules:
pub const BASE = 200
from .base import *
from .other import *
show BASE
`BASE` is imported from more than one module
Importing by name picks one. A name imported by name takes precedence
over one brought in by *:
from .base import *
from .other import BASE
show BASE
200
Macros are the exception. Same-named macros from different modules don’t collide. Their overloads merge into one set, and each call picks the overload that fits. See Overloading.