Skip to content

Commit de38c8f

Browse files
committed
chore: remove any locking concerns from the module system
1 parent 08995b1 commit de38c8f

4 files changed

Lines changed: 47 additions & 62 deletions

File tree

libs/@local/hashql/core/src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@
3939
sync_nonpoison,
4040
try_trait_v2,
4141
variant_count,
42-
iter_collect_into
42+
iter_collect_into,
43+
maybe_uninit_fill
4344
)]
4445

4546
extern crate alloc;

libs/@local/hashql/core/src/module/item.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ pub struct Item<'heap> {
7676
}
7777

7878
impl<'heap> Item<'heap> {
79+
#[must_use]
7980
pub fn ancestors(
8081
&self,
8182
registry: &ModuleRegistry<'heap>,

libs/@local/hashql/core/src/module/mod.rs

Lines changed: 3 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ use crate::{
2525
collections::{FastHashMap, fast_hash_map_in},
2626
heap::{BumpAllocator as _, Heap},
2727
id::{HasId, Id as _, IdSlice, IdVec, bit_vec::DenseBitSet, newtype},
28-
intern::{Decompose, InternSet, Interned},
2928
symbol::Symbol,
3029
r#type::environment::Environment,
3130
};
@@ -40,17 +39,17 @@ impl ModuleId {
4039
}
4140

4241
pub struct PartialModuleRegistry<'heap, S: Allocator> {
42+
heap: &'heap Heap,
4343
modules: IdVec<ModuleId, Option<Module<'heap>>, S>,
44-
items: InternSet<'heap, [Item<'heap>]>,
4544

4645
root: FastHashMap<Symbol<'heap>, ModuleId, &'heap Heap>,
4746
}
4847

4948
impl<'heap, S: Allocator> PartialModuleRegistry<'heap, S> {
5049
pub fn new_in(heap: &'heap Heap, scratch: S) -> Self {
5150
Self {
51+
heap,
5252
modules: IdVec::new_in(scratch),
53-
items: InternSet::new(heap),
5453
root: fast_hash_map_in(heap),
5554
}
5655
}
@@ -89,11 +88,6 @@ impl<'heap, S: Allocator> PartialModuleRegistry<'heap, S> {
8988
debug_assert!(value.is_none());
9089
}
9190

92-
/// Interns a slice of items into the registry.
93-
pub fn intern_items(&self, items: &[Item<'heap>]) -> Interned<'heap, [Item<'heap>]> {
94-
self.items.intern_slice(items)
95-
}
96-
9791
/// Register a new module in the root namespace.
9892
///
9993
/// # Panics
@@ -363,7 +357,7 @@ pub struct Module<'heap> {
363357
pub parent: ModuleId,
364358
pub depth: NonZero<u32>,
365359

366-
pub items: Interned<'heap, [Item<'heap>]>,
360+
pub items: &'heap [Item<'heap>],
367361
}
368362

369363
impl<'heap> Module<'heap> {
@@ -388,28 +382,6 @@ impl<'heap> Module<'heap> {
388382
}
389383
}
390384

391-
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
392-
pub struct PartialModule<'heap> {
393-
name: Symbol<'heap>,
394-
parent: ModuleId,
395-
depth: NonZero<u32>,
396-
items: Interned<'heap, [Item<'heap>]>,
397-
}
398-
399-
impl<'heap> Decompose<'heap> for Module<'heap> {
400-
type Partial = PartialModule<'heap>;
401-
402-
fn from_parts(id: Self::Id, partial: Interned<'heap, Self::Partial>) -> Self {
403-
Self {
404-
id,
405-
name: partial.name,
406-
parent: partial.parent,
407-
depth: partial.depth,
408-
items: partial.items,
409-
}
410-
}
411-
}
412-
413385
impl HasId for Module<'_> {
414386
type Id = ModuleId;
415387

libs/@local/hashql/core/src/module/std_lib/mod.rs

Lines changed: 41 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use ::core::{alloc::Allocator, iter, mem, mem::MaybeUninit, num::NonZero};
66

77
use super::{Module, ModuleId, PartialModuleRegistry, item::IntrinsicItem, locals::TypeDef};
88
use crate::{
9+
heap::BumpAllocator as _,
910
id::{Id as _, bit_vec::FiniteBitSet},
1011
module::item::{ConstructorItem, Item, ItemKind},
1112
symbol::Symbol,
@@ -249,66 +250,76 @@ impl<'heap, S: Allocator> ModuleCache<'heap, S> {
249250
T: StandardLibraryModule<'heap>,
250251
S: Clone,
251252
{
252-
let module = context.registry.provision_module();
253-
let emitted = self.request::<T>(context).emitted_len;
254-
255-
let mut output =
256-
Vec::with_capacity_in(emitted + T::Children::LENGTH, context.alloc.clone());
257-
258-
T::Children::names()
259-
.into_iter()
260-
.zip(T::Children::modules(
261-
context,
262-
self,
263-
depth.saturating_add(1),
264-
module,
265-
))
266-
.map(|(name, child)| Item {
267-
module,
268-
name,
269-
kind: ItemKind::Module(child),
270-
})
271-
.collect_into(&mut output);
253+
let id = context.registry.provision_module();
272254

273255
let def = self.request::<T>(context);
274256

257+
let heap = context.registry.heap;
258+
let output = heap.allocate_slice_uninit(def.emitted_len + T::Children::LENGTH);
259+
260+
let mut cursor = 0;
275261
for &ModuleEntry { name, def } in &def.entries {
276262
match def {
277263
ItemDef::Intrinsic(intrinsic) => {
278-
output.push(Item {
279-
module,
264+
output[cursor].write(Item {
265+
module: id,
280266
name,
281267
kind: ItemKind::Intrinsic(intrinsic),
282268
});
269+
cursor += 1;
283270
}
284271
ItemDef::Type(typedef) => {
285-
output.push(Item {
286-
module,
272+
output[cursor].write(Item {
273+
module: id,
287274
name,
288275
kind: ItemKind::Type(typedef),
289276
});
277+
cursor += 1;
290278
}
291279
ItemDef::Newtype(typedef) => {
292-
output.push(Item {
293-
module,
280+
output[cursor].write(Item {
281+
module: id,
294282
name,
295283
kind: ItemKind::Constructor(ConstructorItem { r#type: typedef }),
296284
});
297-
output.push(Item {
298-
module,
285+
cursor += 1;
286+
287+
output[cursor].write(Item {
288+
module: id,
299289
name,
300290
kind: ItemKind::Type(typedef),
301291
});
292+
cursor += 1;
302293
}
303294
}
304295
}
305296

297+
let remaining = &mut output[cursor..];
298+
let (_, remaining) = remaining.write_iter(
299+
T::Children::names()
300+
.into_iter()
301+
.zip(T::Children::modules(
302+
context,
303+
self,
304+
depth.saturating_add(1),
305+
id,
306+
))
307+
.map(|(name, child)| Item {
308+
module: id,
309+
name,
310+
kind: ItemKind::Module(child),
311+
}),
312+
);
313+
314+
assert!(remaining.is_empty());
315+
306316
let module = Module {
307-
id: module,
317+
id,
308318
name: T::name(),
309319
parent,
310320
depth,
311-
items: context.registry.intern_items(&output),
321+
// SAFETY: assertion ensures that the output buffer is fully initialized before reading.
322+
items: unsafe { output.assume_init_ref() },
312323
};
313324

314325
context.registry.insert_module(module);

0 commit comments

Comments
 (0)