Fix type updating for associated function calls

This commit is contained in:
Sofia 2025-07-27 23:12:40 +03:00
parent 9d5a20e76a
commit 5104555890
5 changed files with 79 additions and 22 deletions

View File

@ -1,6 +1,5 @@
import std::print;
import std::from_str;
import std::String;
struct Otus {
field: u32,

View File

@ -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();

View File

@ -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)
}
_ => {}
}
}

View File

@ -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(())
}
}

View File

@ -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();
}
}
}