Skip to main content

Module

Struct Module 

Source
pub struct Module {
    pub name: ModuleName,
    pub exports: Exports,
    pub exposing_span: NodeSpan,
    pub infixes: HashMap<Name, Infix>,
    pub types: HashMap<Name, UnionType>,
    pub classes: HashMap<Name, Class>,
    pub instances: Vec<Instance>,
    pub imported_instances: Vec<PublishedInstance>,
    pub values: HashMap<Name, Value>,
    pub broken: Vec<Broken>,
    pub binding_foreign: bool,
    pub incomplete: bool,
}
Expand description

A resolved module

Fields§

§name: ModuleName§exports: Exports§exposing_span: NodeSpan

Where the header’s exposing (...) was written — parser::Module::exposing_span, carried through. A diagnostic about what the module exposes as a whole points here.

§infixes: HashMap<Name, Infix>

Operator name to infix details

§types: HashMap<Name, UnionType>§classes: HashMap<Name, Class>

Every class declaration that canonicalized, by name. A member is not in values: it has a signature and no body, and the class carries it.

§instances: Vec<Instance>

Every instance declaration that passed every check, in source order.

§imported_instances: Vec<PublishedInstance>

Every instance this module’s imports brought into scope, each once. to_interface publishes them beside the module’s own, which is what carries an instance to every module that can reach its declaring one.

§values: HashMap<Name, Value>§broken: Vec<Broken>

The value declarations that were written and have no canonical form, sorted by name.

A declaration is here when its annotation or its body did not canonicalize, or, in a facade, when its signature was rejected by the per-declaration checks; an error beside the module says which. It is also here when a declaration chunk that failed to parse names it ([parser::Module::failed]), whatever else of it parsed; the syntax error says why, and only its annotation, when one parsed, is checked. The checks that run on the whole signature list before those (FacadeConstrained and a facade’s malformed context, UnsafeOutsideFacade) report an error and leave the declaration where the per-declaration checks put it. Outside a facade, a context is part of its annotation, and a declaration whose context does not resolve is here with no type. Every other value declaration is in values, and no name is in both. What survives of one is its annotation, when that canonicalized: to_interface exposes it and the typer declares it, so a caller of a broken declaration is checked against the type it was written with.

§binding_foreign: bool

True when this module is a module foreign facade. Such modules have synthetic placeholder bodies and must not be type-checked.

§incomplete: bool

Whether a name could be missing from this module for a reason already reported.

Set when the module’s scope ended incomplete: an import did not resolve, an import resolved to an Interface whose own incomplete is set, a type, infix, class or instance declaration failed, or a declaration chunk that names nothing failed to parse. Also set when a value declaration was written with an annotation that did not canonicalize, or is named by a chunk that failed to parse and has no type, since its annotation may be that chunk: those are the two ways a name goes missing from to_interface while the module’s own scope is whole. to_interface copies it to Interface::incomplete.

Implementations§

Source§

impl Module

Source

pub fn to_interface(&self, file: Option<SourceFileId>) -> Interface

Build the trimmed-down view of this module other modules import against.

file is the SourceFileId this module was read from, which is what lets a later module’s diagnostic point back into this module’s source — see Interface::file. It is a parameter rather than something this method could work out because a canonical::Module does not know it: only driver code does, and the sole caller (dependencies::ModuleWalker::check_in_order) is driver code that has the map from module name to file in hand. A caller with nothing to give — every test that hand-builds an interface — passes None, and Interface::source_span then declines to build a cross-module label rather than building one at the wrong place.

§What the exposing (...) header removes here

This is the only place a module’s own Exports is read, and reading it here is what makes a declaration left out of the header private (BUG-9). self.values, self.types and self.infixes stay complete — the typer, exhaustiveness and every later phase run against the whole Module, because a private declaration is still callable from inside the module that wrote it. Only this external view is trimmed, and only by three rules:

  • a value reaches the interface when the header exposes its name as ExportType::Value, on top of the requirement that it carry a type annotation (Value::TypedValue). do_exports reports an exposed, unannotated declaration (SPEC-5), and the declaration is left out here. A Broken declaration the header exposes reaches the interface the same way when its annotation canonicalized, with that annotation as its type, so an importer is checked against it;
  • an infix reaches it when the header exposes the operator;
  • a union type reaches it when the header names it either way, but a Size entry (ExportType::UnionPrivate) hands over the declaration with its variants emptied, and records its name in Interface::opaque_unions. That is the opaque type: importers still get the name and its type variables — Interface::unions is where process_import’s Privacy::Private arm reads the arity from — and no constructor to build or match one with.

A class reaches it, with every member and the derivations it carries, when the header names it (ExportType::Class).

Exports::Everything — a exposing (..) header — exposes every declaration with every constructor, so nothing is dropped in that case.

§What the header does not remove

Every instance reaches the interface: the module’s own, and every one its imports brought into scope (imported_instances). An instance has no name for a header to list, and it has to be in scope in every module that can reach the module declaring it, through however many imports, so each module passes on what it received (Type classes).

An exposed infix whose backing function is not itself separately exposed — infix left 6 (+) = add with (+) in the header and add not, which is every operator std/core declares — still needs add’s type reachable, or an importer that brings (+) into scope has no type to give a use of it. Interface::infix_functions carries exactly that, kept out of values itself so add stays unreachable under its own name.

Source

pub fn emitted_arity(&self, value: &Value) -> usize

How many parameters value, one of this module’s declarations, is emitted with: the count a call has to supply to be a direct call.

For a declaration with a body that is Value::arity, the parameters it was written with. A module foreign facade’s declaration is a signature with no parameters to count, and its forwarding function takes one parameter per arrow in the signature (Type::arrow_count), the plain parameter list its companion’s export takes.

to_interface records it for each exported value, so that an importer’s call site is saturated at the same count this module’s own call sites are.

Trait Implementations§

Source§

impl Checked for Module

Source§

fn name(&self) -> &ModuleName

The module’s own name, package included.
Source§

fn to_interface(&self, file: Option<SourceFileId>) -> Interface

The trimmed-down view the modules that import this one are checked against. Read more
Source§

impl Debug for Module

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.