From 51045558900984f0702a477dee824b704a71b5df Mon Sep 17 00:00:00 2001 From: sofia Date: Sun, 27 Jul 2025 23:12:40 +0300 Subject: [PATCH] Fix type updating for associated function calls --- examples/associated_functions_shorthand.reid | 1 - examples/hello_world_harder.reid | 4 +- reid/src/mir/linker.rs | 9 +++- reid/src/mir/pass.rs | 49 +++++++++++++++++++- reid/src/mir/typecheck/typeinference.rs | 38 ++++++++------- 5 files changed, 79 insertions(+), 22 deletions(-) diff --git a/examples/associated_functions_shorthand.reid b/examples/associated_functions_shorthand.reid index a3b402d..db78842 100644 --- a/examples/associated_functions_shorthand.reid +++ b/examples/associated_functions_shorthand.reid @@ -1,6 +1,5 @@ import std::print; import std::from_str; -import std::String; struct Otus { field: u32, diff --git a/examples/hello_world_harder.reid b/examples/hello_world_harder.reid index 22e1681..5913486 100644 --- a/examples/hello_world_harder.reid +++ b/examples/hello_world_harder.reid @@ -1,10 +1,12 @@ import std::print; +import std::from_str; import std::add_char; import std::set_char; import std::free_string; -import std::new_string; import std::add_num_to_str; import std::concat_strings; +import std::String; + fn main() { let mut test = String::new(); diff --git a/reid/src/mir/linker.rs b/reid/src/mir/linker.rs index dc844de..9e4704b 100644 --- a/reid/src/mir/linker.rs +++ b/reid/src/mir/linker.rs @@ -401,9 +401,14 @@ impl<'map> Pass for LinkerPass<'map> { } super::ExprKind::BinOp(.., type_kind) => *type_kind = type_kind.update_imported(extern_types, mod_id), - super::ExprKind::Borrow(expr, _) => {} - super::ExprKind::Deref(expr) => {} + super::ExprKind::Borrow(..) => {} + super::ExprKind::Deref(..) => {} super::ExprKind::CastTo(_, type_kind) => *type_kind = type_kind.update_imported(extern_types, mod_id), + super::ExprKind::AssociatedFunctionCall(type_kind, _) => { + dbg!(&type_kind); + dbg!(extern_types); + *type_kind = type_kind.update_imported(extern_types, mod_id) + } _ => {} } } diff --git a/reid/src/mir/pass.rs b/reid/src/mir/pass.rs index 79fb5e7..f1e5490 100644 --- a/reid/src/mir/pass.rs +++ b/reid/src/mir/pass.rs @@ -519,7 +519,8 @@ impl Statement { StmtKind::Let(_, _, expression) => { expression.pass(pass, state, scope, mod_id)?; } - StmtKind::Set(_, expression) => { + StmtKind::Set(set_expr, expression) => { + set_expr.pass(pass, state, scope, mod_id)?; expression.pass(pass, state, scope, mod_id)?; } StmtKind::Import(_) => {} @@ -565,6 +566,52 @@ impl Expression { mod_id: SourceModuleId, ) -> PassResult { pass.expr(self, PassState::from(state, scope, Some(mod_id)))?; + match &mut self.0 { + ExprKind::Variable(_) => {} + ExprKind::Indexed(value_expr, _, index_expr) => { + pass.expr(value_expr.as_mut(), PassState::from(state, scope, Some(mod_id)))?; + pass.expr(index_expr.as_mut(), PassState::from(state, scope, Some(mod_id)))?; + } + ExprKind::Accessed(value_expr, ..) => { + pass.expr(value_expr.as_mut(), PassState::from(state, scope, Some(mod_id)))?; + } + ExprKind::Array(expressions) => { + for expr in expressions { + pass.expr(expr, PassState::from(state, scope, Some(mod_id)))?; + } + } + ExprKind::Struct(_, items) => { + for (_, expr) in items { + pass.expr(expr, PassState::from(state, scope, Some(mod_id)))?; + } + } + ExprKind::Literal(_) => {} + ExprKind::BinOp(_, lhs, rhs, _) => { + pass.expr(lhs.as_mut(), PassState::from(state, scope, Some(mod_id)))?; + pass.expr(rhs.as_mut(), PassState::from(state, scope, Some(mod_id)))?; + } + ExprKind::FunctionCall(FunctionCall { parameters, .. }) => { + for expr in parameters { + pass.expr(expr, PassState::from(state, scope, Some(mod_id)))?; + } + } + ExprKind::AssociatedFunctionCall(_, FunctionCall { parameters, .. }) => { + for expr in parameters { + pass.expr(expr, PassState::from(state, scope, Some(mod_id)))?; + } + } + ExprKind::If(IfExpression(cond, lhs, rhs)) => { + pass.expr(cond.as_mut(), PassState::from(state, scope, Some(mod_id)))?; + pass.expr(lhs.as_mut(), PassState::from(state, scope, Some(mod_id)))?; + if let Some(rhs) = rhs.as_mut() { + pass.expr(rhs, PassState::from(state, scope, Some(mod_id)))?; + } + } + ExprKind::Block(block) => pass.block(block, PassState::from(state, scope, Some(mod_id)))?, + ExprKind::Borrow(expression, _) => pass.expr(expression, PassState::from(state, scope, Some(mod_id)))?, + ExprKind::Deref(expression) => pass.expr(expression, PassState::from(state, scope, Some(mod_id)))?, + ExprKind::CastTo(expression, _) => pass.expr(expression, PassState::from(state, scope, Some(mod_id)))?, + } Ok(()) } } diff --git a/reid/src/mir/typecheck/typeinference.rs b/reid/src/mir/typecheck/typeinference.rs index 323ebba..8aee019 100644 --- a/reid/src/mir/typecheck/typeinference.rs +++ b/reid/src/mir/typecheck/typeinference.rs @@ -594,23 +594,27 @@ impl Expression { Ok(type_refs.from_type(type_kind).unwrap()) } ExprKind::AssociatedFunctionCall(type_kind, function_call) => { - if type_kind.is_known(state).is_err() { - let first_param = function_call - .parameters - .get_mut(0) - .expect("Unknown-type associated function NEEDS to always have at least one parameter!"); - let param_ty = first_param.infer_types(state, type_refs).unwrap().resolve_deep(); - *type_kind = state.or_else( - param_ty.ok_or(ErrorKind::CouldNotInferType(format!("{}", first_param))), - 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(); + match type_kind.is_known(state) { + Ok(_) => {} + Err(ErrorKind::NoSuchType(name, mod_id)) => return Err(ErrorKind::NoSuchType(name, mod_id)), + Err(_) => { + let first_param = function_call + .parameters + .get_mut(0) + .expect("Unknown-type associated function NEEDS to always have at least one parameter!"); + let param_ty = first_param.infer_types(state, type_refs).unwrap().resolve_deep(); + *type_kind = state.or_else( + param_ty.ok_or(ErrorKind::CouldNotInferType(format!("{}", first_param))), + 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(); + } } }