Allow borrows in associated function &self

This commit is contained in:
Sofia 2025-07-27 22:45:34 +03:00
parent 676554b6a0
commit a6a903a45d
5 changed files with 69 additions and 14 deletions

View File

@ -7,8 +7,8 @@ struct Otus {
}
impl Otus {
fn test(self) -> u32 {
self.field
fn test(&self) -> u32 {
*self.field
}
}

View File

@ -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 {

View File

@ -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| {

View File

@ -171,18 +171,27 @@ impl<Data: Clone + Default> Scope<Data> {
}
pub fn get_associated_function(&mut self, key: &AssociatedFunctionKey) -> Option<ScopeFunction> {
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
}

View File

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