Allow borrows in associated function &self
This commit is contained in:
		
							parent
							
								
									676554b6a0
								
							
						
					
					
						commit
						a6a903a45d
					
				| @ -7,8 +7,8 @@ struct Otus { | ||||
| } | ||||
| 
 | ||||
| impl Otus { | ||||
|     fn test(self) -> u32 { | ||||
|         self.field | ||||
|     fn test(&self) -> u32 { | ||||
|         *self.field | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -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 { | ||||
|  | ||||
| @ -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| { | ||||
|  | ||||
| @ -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 | ||||
|         } | ||||
|  | ||||
| @ -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; | ||||
|             } | ||||
|             _ => {} | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user