Skip to content

Commit 0b0e0b4

Browse files
committed
feat: connect OwnershipMode to lowering pipeline
- Add ownership_modes HashMap to LoweringContext for tracking value ownership - Add copy_types HashSet for types that implement Copy trait - Add is_copy_type() to determine if a type can be copied - Add determine_ownership_mode() to choose between Owned/Copied/Borrowed - Add initialize_copy_types() to discover Copy trait implementations - Add create_borrow() helper for creating borrows with ownership tracking
1 parent 1929b01 commit 0b0e0b4

1 file changed

Lines changed: 89 additions & 2 deletions

File tree

crates/compiler/src/lowering.rs

Lines changed: 89 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,11 @@ fn hash_string(s: &str) -> u64 {
1616
s.hash(&mut hasher);
1717
hasher.finish()
1818
}
19-
use crate::hir::{HirModule, HirFunction, HirFunctionSignature, HirParam, HirType, ParamAttributes};
19+
use crate::hir::{HirModule, HirFunction, HirFunctionSignature, HirParam, HirType, ParamAttributes, OwnershipMode, HirId, HirLifetime};
2020
use crate::cfg::{ControlFlowGraph, CfgBuilder};
2121
use crate::ssa::{SsaBuilder, SsaForm};
2222
use crate::CompilerResult;
23+
use std::collections::HashMap;
2324

2425
/// Target data layout information for precise size and alignment calculations
2526
#[derive(Debug, Clone)]
@@ -223,6 +224,10 @@ pub struct LoweringContext {
223224
/// Cache of already-resolved modules (module_path -> resolved imports)
224225
/// This avoids re-resolving the same module multiple times
225226
pub resolved_module_cache: std::collections::HashMap<Vec<String>, Vec<ResolvedImport>>,
227+
/// Ownership modes for values (tracks whether values are owned, borrowed, or copied)
228+
pub ownership_modes: HashMap<HirId, OwnershipMode>,
229+
/// Types that implement Copy trait (for deciding between move and copy semantics)
230+
pub copy_types: std::collections::HashSet<zyntax_typed_ast::TypeId>,
226231
}
227232

228233
/// Symbol table for name resolution
@@ -368,9 +373,87 @@ impl LoweringContext {
368373
import_metadata: Vec::new(),
369374
import_context: ImportContext::default(),
370375
resolved_module_cache: std::collections::HashMap::new(),
376+
ownership_modes: HashMap::new(),
377+
copy_types: std::collections::HashSet::new(),
371378
}
372379
}
373-
380+
381+
/// Set the ownership mode for a value
382+
pub fn set_ownership_mode(&mut self, id: HirId, mode: OwnershipMode) {
383+
self.ownership_modes.insert(id, mode);
384+
}
385+
386+
/// Get the ownership mode for a value
387+
pub fn get_ownership_mode(&self, id: &HirId) -> Option<&OwnershipMode> {
388+
self.ownership_modes.get(id)
389+
}
390+
391+
/// Check if a type implements Copy (can be duplicated without moving)
392+
pub fn is_copy_type(&self, ty: &Type) -> bool {
393+
// Primitive types are always Copy
394+
match ty {
395+
Type::Primitive(_) => true,
396+
Type::Named { id, .. } => self.copy_types.contains(id),
397+
// Tuples are Copy if all elements are Copy
398+
Type::Tuple(elements) => elements.iter().all(|e| self.is_copy_type(e)),
399+
// References are Copy (regardless of mutability)
400+
Type::Reference { .. } => true,
401+
// Function types are Copy
402+
Type::Function { .. } => true,
403+
// Other types are not Copy by default
404+
_ => false,
405+
}
406+
}
407+
408+
/// Determine the ownership mode for using a value based on its type
409+
pub fn determine_ownership_mode(&self, ty: &Type) -> OwnershipMode {
410+
if self.is_copy_type(ty) {
411+
OwnershipMode::Copied
412+
} else {
413+
OwnershipMode::Owned
414+
}
415+
}
416+
417+
/// Initialize the set of Copy types from the type registry
418+
/// This looks for types that implement the Copy trait
419+
fn initialize_copy_types(&mut self) {
420+
// Look for Copy trait in the registry
421+
let copy_trait_name = zyntax_typed_ast::arena::InternedString::new_global("Copy");
422+
423+
if let Some(copy_trait) = self.type_registry.get_trait_by_name(copy_trait_name) {
424+
// Find all implementations of Copy trait
425+
for (trait_id, impls) in self.type_registry.iter_implementations() {
426+
if *trait_id == copy_trait.id {
427+
for impl_def in impls {
428+
// Extract the type that implements Copy
429+
if let Type::Named { id, .. } = &impl_def.for_type {
430+
self.copy_types.insert(*id);
431+
}
432+
}
433+
}
434+
}
435+
}
436+
437+
// TODO: Also check for types with Copy annotation/attribute
438+
eprintln!("[OWNERSHIP] Initialized {} Copy types", self.copy_types.len());
439+
}
440+
441+
/// Create a borrow of a value, returning the borrow's HirId
442+
pub fn create_borrow(&mut self, value_id: HirId, is_mutable: bool) -> HirId {
443+
let borrow_id = HirId::new();
444+
let lifetime = HirLifetime::anonymous();
445+
446+
// Track the borrow in ownership_modes
447+
let mode = if is_mutable {
448+
OwnershipMode::BorrowedMut(lifetime.clone())
449+
} else {
450+
OwnershipMode::Borrowed(lifetime)
451+
};
452+
self.ownership_modes.insert(borrow_id, mode);
453+
454+
borrow_id
455+
}
456+
374457
/// Add a diagnostic
375458
pub fn diagnostic(&mut self, level: DiagnosticLevel, message: String, span: Option<zyntax_typed_ast::Span>) {
376459
self.diagnostics.push(LoweringDiagnostic {
@@ -383,6 +466,10 @@ impl LoweringContext {
383466

384467
impl AstLowering for LoweringContext {
385468
fn lower_program(&mut self, program: &mut TypedProgram) -> CompilerResult<HirModule> {
469+
// Phase -1: Initialize Copy types from the type registry
470+
// Types that implement the Copy trait can be duplicated instead of moved
471+
self.initialize_copy_types();
472+
386473
// Phase 0: Run type checking and inference (Issue 0 Phase 1)
387474
// This validates types and performs type inference, reporting any errors
388475
// Skip type checking if SKIP_TYPE_CHECK env var is set (for debugging)

0 commit comments

Comments
 (0)