Skip to main content

lean_rs/module/
loaded.rs

1//! Handle to a Lean module whose initializer has succeeded.
2//!
3//! [`LeanModule`] is the typed proof that
4//! [`crate::module::LeanLibrary::initialize_module`] ran the module's
5//! initializer to `IO.ok(())`. The only constructor is
6//! `pub(super) fn new`, invoked at the end of `initialize_module`;
7//! therefore a value of this type cannot exist unless the corresponding
8//! module is live in the Lean runtime.
9//!
10//! Typed exported-function handles attach to this type via
11//! [`LeanModule::exported`], which returns a
12//! [`crate::module::LeanExported`] parameterised by the argument tuple
13//! and return-type marker.
14
15use super::initializer::InitializerName;
16use super::library::LeanLibrary;
17
18/// A Lean module that has been linked and initialized successfully.
19///
20/// Holds a borrow of its source [`LeanLibrary`]; the `'lib` lifetime
21/// keeps the dylib loaded while any `LeanModule` referring to it is
22/// alive. The `'lean` lifetime is inherited from the library, which
23/// inherits it from the [`crate::LeanRuntime`] borrow that anchored the
24/// whole chain. Neither [`Send`] nor [`Sync`] (inherited from the
25/// `&LeanLibrary` field).
26pub struct LeanModule<'lean, 'lib> {
27    library: &'lib LeanLibrary<'lean>,
28    initializer: InitializerName,
29}
30
31impl<'lean, 'lib> LeanModule<'lean, 'lib> {
32    /// Build the typed handle.
33    ///
34    /// `pub(super)` so only `LeanLibrary::initialize_module` can produce
35    /// one — the construction site is the proof that initialization
36    /// succeeded.
37    pub(super) fn new(library: &'lib LeanLibrary<'lean>, initializer: InitializerName) -> Self {
38        Self { library, initializer }
39    }
40
41    /// Human-readable `package::Module.Path` form for diagnostics.
42    ///
43    /// The format matches what
44    /// [`crate::module::LeanLibrary::initialize_module`] accepted, so
45    /// log messages and test assertions can round-trip the name a
46    /// caller used.
47    #[must_use]
48    pub fn module_name(&self) -> &str {
49        self.initializer.display()
50    }
51
52    /// Borrowed reference to the owning library.
53    ///
54    /// `pub(crate)` so the typed [`crate::module::exported`] machinery
55    /// can resolve exported-function symbols against the same library
56    /// this module was initialized from.
57    pub(crate) fn library(&self) -> &'lib LeanLibrary<'lean> {
58        self.library
59    }
60
61    /// Initializer name in its mangled C form.
62    ///
63    /// `pub(crate)` so internal symbol-derivation code can reach the
64    /// canonical Lake mangling without re-running the validator.
65    #[allow(dead_code, reason = "reserved for symbol-derivation helpers in later prompts")]
66    pub(crate) fn initializer(&self) -> &InitializerName {
67        &self.initializer
68    }
69}
70
71impl std::fmt::Debug for LeanModule<'_, '_> {
72    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
73        f.debug_struct("LeanModule")
74            .field("module", &self.initializer.display())
75            .finish()
76    }
77}