Skip to main content

ModuleWalker

Struct ModuleWalker 

Source
pub struct ModuleWalker<'a> { /* private fields */ }

Implementations§

Source§

impl<'a> ModuleWalker<'a>

Source

pub fn new( modules: &'a [Module], module_files: &HashMap<Name, SourceFileId>, package: &PackageName, ) -> Result<ModuleWalker<'a>, Error>

module_files is how a cycle’s edges learn which file each import was written in (CycleEdge::file) — this is driver code, the same as check_in_order below, so it is handed the map compile_package already built while parsing rather than trying to discover it itself. Every test in this module passes an empty map: their modules are hand-built, with no file on disk to name, and CycleEdge::file degrades to None for them exactly as documented there.

Source

pub fn new_for_root( modules: &'a [Module], module_files: &HashMap<Name, SourceFileId>, package: &PackageName, ) -> Result<ModuleWalker<'a>, Error>

A walker over the modules of one of a package’s two source roots.

A package has a src/ and a tests/, and each is walked and checked on its own, but whether package is exempt from the default imports (PackageName::is_core) does not depend on which root — or which modules — either one happens to hold, so the two roots of one package always get the same answer without either walker having to be told the other’s modules.

The import graph is built from modules alone either way. An import naming a module of the other root resolves through an Interface or not at all, the same as an import naming another package’s module.

Source

pub fn check_in_order<M: Checked, E>( &self, package: &PackageName, interfaces: &mut HashMap<Name, Interface>, module_files: &HashMap<Name, SourceFileId>, check: fn(package: &PackageName, interfaces: &HashMap<Name, Interface>, source: &Module) -> Outcome<M, E>, ) -> Vec<Outcome<M, E>>

Given a package name, a set of existing interfaces and a checker function, check each module in its dependencies order.

Every module is checked regardless of whether an earlier one failed, and each comes back as one Outcome, in the order it was checked (BUG-2). Every module the checker hands back has its Interface inserted into interfaces as it goes, whether or not it came back with errors, so later modules keep resolving against earlier ones: an importer of a module with an error in one declaration is checked against the interface that module has, and reports nothing about the import (DEC-23 decision 1). Only an Outcome::Failed module is absent from what follows it.

module_files is how a checked module’s Interface learns the file it was read from (Interface::file, ERR-5) — check itself is a phase-orchestrating function and, like every phase, never knows it. This method is driver code rather than a phase, the same as compile_package, so it is the one that can look the id up and stamp it on before the interface goes into the shared map. A module missing from module_files — there is none in the real pipeline, since only a module that already parsed reaches here — simply leaves that interface’s file as None, same as a hand-built one.

check takes package and nothing beyond it to say whether this build is exempt from the default imports — PackageName::is_core is a function of package alone, so a checker derives its own answer from the same package this walker was built from rather than being handed one separately.

Trait Implementations§

Source§

impl<'a> Debug for ModuleWalker<'a>

Source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<'a> Freeze for ModuleWalker<'a>

§

impl<'a> RefUnwindSafe for ModuleWalker<'a>

§

impl<'a> Send for ModuleWalker<'a>

§

impl<'a> Sync for ModuleWalker<'a>

§

impl<'a> Unpin for ModuleWalker<'a>

§

impl<'a> UnsafeUnpin for ModuleWalker<'a>

§

impl<'a> UnwindSafe for ModuleWalker<'a>

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.