@@ -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 } ;
2020use crate :: cfg:: { ControlFlowGraph , CfgBuilder } ;
2121use crate :: ssa:: { SsaBuilder , SsaForm } ;
2222use 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
384467impl 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