Check borrow mutability against variable mutability
This commit is contained in:
		
							parent
							
								
									1fadaa60f2
								
							
						
					
					
						commit
						5763df948f
					
				| @ -61,6 +61,8 @@ pub enum ErrorKind { | ||||
|     AttemptedDerefNonBorrow(String), | ||||
|     #[error("Types {0} and {1} differ in mutability")] | ||||
|     TypesDifferMutability(TypeKind, TypeKind), | ||||
|     #[error("Cannot mutably borrow variable {0}, which is not declared as mutable")] | ||||
|     ImpossibleMutableBorrow(String), | ||||
| } | ||||
| 
 | ||||
| /// Struct used to implement a type-checking pass that can be performed on the
 | ||||
| @ -633,20 +635,25 @@ impl Expression { | ||||
|                 Ok(TypeKind::CustomType(struct_name.clone())) | ||||
|             } | ||||
|             ExprKind::Borrow(var_ref, mutable) => { | ||||
|                 let scope_var = state.scope.variables.get(&var_ref.1).cloned(); | ||||
| 
 | ||||
|                 let existing = state | ||||
|                     .or_else( | ||||
|                         state | ||||
|                             .scope | ||||
|                             .variables | ||||
|                             .get(&var_ref.1) | ||||
|                             .map(|var| &var.ty) | ||||
|                             .cloned() | ||||
|                         scope_var | ||||
|                             .clone() | ||||
|                             .map(|var| var.ty) | ||||
|                             .ok_or(ErrorKind::VariableNotDefined(var_ref.1.clone())), | ||||
|                         TypeKind::Vague(Vague::Unknown), | ||||
|                         var_ref.2, | ||||
|                     ) | ||||
|                     .resolve_ref(typerefs); | ||||
| 
 | ||||
|                 if let Some(scope_var) = scope_var { | ||||
|                     if !scope_var.mutable && *mutable { | ||||
|                         return Err(ErrorKind::ImpossibleMutableBorrow(var_ref.1.clone())); | ||||
|                     } | ||||
|                 } | ||||
| 
 | ||||
|                 // Update typing to be more accurate
 | ||||
|                 var_ref.0 = state.or_else( | ||||
|                     var_ref.0.resolve_ref(typerefs).collapse_into(&existing), | ||||
|  | ||||
| @ -7,7 +7,7 @@ fn changer(param: &mut u32) { | ||||
| fn main() -> u32 { | ||||
|   let value = 6; | ||||
| 
 | ||||
|   changer(&mut value); | ||||
|   changer(&value); | ||||
| 
 | ||||
|   return value; | ||||
| } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user