Allow borrows in associated function &self
This commit is contained in:
		
							parent
							
								
									676554b6a0
								
							
						
					
					
						commit
						a6a903a45d
					
				| @ -7,8 +7,8 @@ struct Otus { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl Otus { | impl Otus { | ||||||
|     fn test(self) -> u32 { |     fn test(&self) -> u32 { | ||||||
|         self.field |         *self.field | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -415,7 +415,13 @@ impl ast::Expression { | |||||||
|             ), |             ), | ||||||
|             ast::ExpressionKind::AccessCall(expression, fn_call_expr) => { |             ast::ExpressionKind::AccessCall(expression, fn_call_expr) => { | ||||||
|                 let mut params: Vec<_> = fn_call_expr.1.iter().map(|e| e.process(module_id)).collect(); |                 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::ExprKind::AssociatedFunctionCall( | ||||||
|                     mir::TypeKind::Vague(mir::VagueType::Unknown), |                     mir::TypeKind::Vague(mir::VagueType::Unknown), | ||||||
|                     mir::FunctionCall { |                     mir::FunctionCall { | ||||||
|  | |||||||
| @ -1292,6 +1292,9 @@ fn codegen_function_call<'ctx, 'a>( | |||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     let val = if let Some(ty) = associated_type { |     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 assoc_key = AssociatedFunctionKey(ty.clone(), call.name.clone()); | ||||||
|         let intrinsic_def = get_intrinsic_assoc_func(&ty, &call.name); |         let intrinsic_def = get_intrinsic_assoc_func(&ty, &call.name); | ||||||
|         let intrinsic = intrinsic_def.map(|func_def| { |         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> { |     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 { |         if let Some(func) = func { | ||||||
|             Some(func.clone()) |             Some(func.clone()) | ||||||
|         } else if let Some(func) = get_intrinsic_assoc_func(&key.0, &key.1) { |         } else if let Some(func) = get_intrinsic_assoc_func(&key.0, &key.1) { | ||||||
|             self.associated_functions.set( |             self.associated_functions | ||||||
|  |                 .set( | ||||||
|                     key.clone(), |                     key.clone(), | ||||||
|                     ScopeFunction { |                     ScopeFunction { | ||||||
|                         ret: func.return_type, |                         ret: func.return_type, | ||||||
|                         params: func.parameters.iter().map(|(_, p)| p.clone()).collect(), |                         params: func.parameters.iter().map(|(_, p)| p.clone()).collect(), | ||||||
|                     }, |                     }, | ||||||
|             ); |                 ) | ||||||
|             self.associated_functions.get(key).cloned() |                 .unwrap(); | ||||||
|  |             self.associated_functions.get(&key).cloned() | ||||||
|         } else { |         } else { | ||||||
|             None |             None | ||||||
|         } |         } | ||||||
|  | |||||||
| @ -12,8 +12,9 @@ use std::{ | |||||||
| 
 | 
 | ||||||
| use crate::{ | use crate::{ | ||||||
|     mir::{ |     mir::{ | ||||||
|         pass::AssociatedFunctionKey, BinopDefinition, Block, CustomTypeKey, ExprKind, Expression, FunctionDefinition, |         pass::{AssociatedFunctionKey, ScopeVariable}, | ||||||
|         FunctionDefinitionKind, IfExpression, Module, ReturnKind, StmtKind, TypeKind, WhileStatement, |         BinopDefinition, Block, CustomTypeKey, ExprKind, Expression, FunctionDefinition, FunctionDefinitionKind, | ||||||
|  |         IfExpression, Module, ReturnKind, StmtKind, TypeKind, WhileStatement, | ||||||
|     }, |     }, | ||||||
|     util::try_all, |     util::try_all, | ||||||
| }; | }; | ||||||
| @ -249,6 +250,18 @@ impl Block { | |||||||
|                         var.0 = var_ref.as_type(); |                         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
 |                     // Infer hints for the expression itself
 | ||||||
|                     let inferred = expr.infer_types(&mut state, &inner_refs); |                     let inferred = expr.infer_types(&mut state, &inner_refs); | ||||||
|                     let mut expr_ty_ref = state.ok(inferred, expr.1); |                     let mut expr_ty_ref = state.ok(inferred, expr.1); | ||||||
| @ -592,6 +605,13 @@ impl Expression { | |||||||
|                         Void, |                         Void, | ||||||
|                         first_param.1, |                         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
 |                 // 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