diff --git a/examples/associated_functions_shorthand.reid b/examples/associated_functions_shorthand.reid index d06e0df..a3b402d 100644 --- a/examples/associated_functions_shorthand.reid +++ b/examples/associated_functions_shorthand.reid @@ -7,8 +7,8 @@ struct Otus { } impl Otus { - fn test(self) -> u32 { - self.field + fn test(&self) -> u32 { + *self.field } } diff --git a/reid/src/ast/process.rs b/reid/src/ast/process.rs index ca0c8ff..76207ea 100644 --- a/reid/src/ast/process.rs +++ b/reid/src/ast/process.rs @@ -415,7 +415,13 @@ impl ast::Expression { ), ast::ExpressionKind::AccessCall(expression, fn_call_expr) => { let mut params: Vec<_> = fn_call_expr.1.iter().map(|e| e.process(module_id)).collect(); - params.insert(0, expression.process(module_id)); + params.insert( + 0, + mir::Expression( + mir::ExprKind::Borrow(Box::new(expression.process(module_id)), true), + expression.1.as_meta(module_id), + ), + ); mir::ExprKind::AssociatedFunctionCall( mir::TypeKind::Vague(mir::VagueType::Unknown), mir::FunctionCall { diff --git a/reid/src/codegen/mod.rs b/reid/src/codegen/mod.rs index 59a61d4..886a0fe 100644 --- a/reid/src/codegen/mod.rs +++ b/reid/src/codegen/mod.rs @@ -1292,6 +1292,9 @@ fn codegen_function_call<'ctx, 'a>( }; let val = if let Some(ty) = associated_type { + // Unwrap type from borrow if it is in a borrow + let ty = if let TypeKind::Borrow(inner, _) = ty { inner } else { ty }; + let assoc_key = AssociatedFunctionKey(ty.clone(), call.name.clone()); let intrinsic_def = get_intrinsic_assoc_func(&ty, &call.name); let intrinsic = intrinsic_def.map(|func_def| { diff --git a/reid/src/mir/pass.rs b/reid/src/mir/pass.rs index ef6a7ab..79fb5e7 100644 --- a/reid/src/mir/pass.rs +++ b/reid/src/mir/pass.rs @@ -171,18 +171,27 @@ impl Scope { } pub fn get_associated_function(&mut self, key: &AssociatedFunctionKey) -> Option { - let func = self.associated_functions.get(key); + let ty = if let TypeKind::Borrow(inner, _) = &key.0 { + *inner.clone() + } else { + key.0.clone() + }; + let key = AssociatedFunctionKey(ty, key.1.clone()); + + let func = self.associated_functions.get(&key); if let Some(func) = func { Some(func.clone()) } else if let Some(func) = get_intrinsic_assoc_func(&key.0, &key.1) { - self.associated_functions.set( - key.clone(), - ScopeFunction { - ret: func.return_type, - params: func.parameters.iter().map(|(_, p)| p.clone()).collect(), - }, - ); - self.associated_functions.get(key).cloned() + self.associated_functions + .set( + key.clone(), + ScopeFunction { + ret: func.return_type, + params: func.parameters.iter().map(|(_, p)| p.clone()).collect(), + }, + ) + .unwrap(); + self.associated_functions.get(&key).cloned() } else { None } diff --git a/reid/src/mir/typecheck/typeinference.rs b/reid/src/mir/typecheck/typeinference.rs index 26b84a4..323ebba 100644 --- a/reid/src/mir/typecheck/typeinference.rs +++ b/reid/src/mir/typecheck/typeinference.rs @@ -12,8 +12,9 @@ use std::{ use crate::{ mir::{ - pass::AssociatedFunctionKey, BinopDefinition, Block, CustomTypeKey, ExprKind, Expression, FunctionDefinition, - FunctionDefinitionKind, IfExpression, Module, ReturnKind, StmtKind, TypeKind, WhileStatement, + pass::{AssociatedFunctionKey, ScopeVariable}, + BinopDefinition, Block, CustomTypeKey, ExprKind, Expression, FunctionDefinition, FunctionDefinitionKind, + IfExpression, Module, ReturnKind, StmtKind, TypeKind, WhileStatement, }, util::try_all, }; @@ -249,6 +250,18 @@ impl Block { var.0 = var_ref.as_type(); } + state + .scope + .variables + .set( + var.1.clone(), + ScopeVariable { + ty: var.0.clone(), + mutable: *mutable, + }, + ) + .ok(); + // Infer hints for the expression itself let inferred = expr.infer_types(&mut state, &inner_refs); let mut expr_ty_ref = state.ok(inferred, expr.1); @@ -592,6 +605,13 @@ impl Expression { Void, first_param.1, ); + let backing_var = first_param.backing_var().expect("todo").1.clone(); + dbg!(&backing_var); + dbg!(&state.scope.variables.get(&backing_var)); + let mutable = state.scope.variables.get(&backing_var).expect("todo").mutable; + if !mutable { + first_param.remove_borrow_mutability(); + } } // Get function definition and types @@ -621,4 +641,21 @@ impl Expression { } } } + + fn remove_borrow_mutability(&mut self) { + match &mut self.0 { + ExprKind::Variable(_) => {} + ExprKind::Indexed(value_expr, ..) => value_expr.remove_borrow_mutability(), + ExprKind::Accessed(value_expr, ..) => value_expr.remove_borrow_mutability(), + ExprKind::Block(block) => { + if let Some((_, Some(ret_expr))) = &mut block.return_expression { + ret_expr.remove_borrow_mutability(); + } + } + ExprKind::Borrow(_, mutable) => { + *mutable = false; + } + _ => {} + } + } }