Improve deref parsing
This commit is contained in:
		
							parent
							
								
									cc367a38e7
								
							
						
					
					
						commit
						676554b6a0
					
				| @ -12,4 +12,4 @@ fn main() -> u32 { | |||||||
| fn mutate(value: &mut [u32; 3]) { | fn mutate(value: &mut [u32; 3]) { | ||||||
|     // Dereference the borrow to mutate it |     // Dereference the borrow to mutate it | ||||||
|     *value[1] = 17; |     *value[1] = 17; | ||||||
| } | } | ||||||
|  | |||||||
| @ -80,8 +80,8 @@ pub struct Expression(pub ExpressionKind, pub TokenRange); | |||||||
| #[derive(Debug, Clone)] | #[derive(Debug, Clone)] | ||||||
| pub enum ExpressionKind { | pub enum ExpressionKind { | ||||||
|     VariableName(String), |     VariableName(String), | ||||||
|     Borrow(String, bool), |     Borrow(Box<Expression>, bool), | ||||||
|     Deref(String), |     Deref(Box<Expression>), | ||||||
|     Literal(Literal), |     Literal(Literal), | ||||||
|     Array(Vec<Expression>), |     Array(Vec<Expression>), | ||||||
|     ArrayShort(Box<Expression>, u64), |     ArrayShort(Box<Expression>, u64), | ||||||
|  | |||||||
| @ -179,6 +179,36 @@ impl Parse for AssociatedFunctionCall { | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | fn apply_inner<T>(expr: PrimaryExpression, fun: T) -> Expression | ||||||
|  | where | ||||||
|  |     T: FnOnce(PrimaryExpression) -> Expression, | ||||||
|  | { | ||||||
|  |     match &expr.0 .0 { | ||||||
|  |         ExpressionKind::Indexed(value_expr, index_expr) => Expression( | ||||||
|  |             ExpressionKind::Indexed( | ||||||
|  |                 Box::new(apply_inner(PrimaryExpression(*value_expr.clone()), fun)), | ||||||
|  |                 index_expr.clone(), | ||||||
|  |             ), | ||||||
|  |             expr.0 .1, | ||||||
|  |         ), | ||||||
|  |         ExpressionKind::Accessed(value_expr, index_name) => Expression( | ||||||
|  |             ExpressionKind::Accessed( | ||||||
|  |                 Box::new(apply_inner(PrimaryExpression(*value_expr.clone()), fun)), | ||||||
|  |                 index_name.clone(), | ||||||
|  |             ), | ||||||
|  |             expr.0 .1, | ||||||
|  |         ), | ||||||
|  |         ExpressionKind::AccessCall(value_expr, fn_call) => Expression( | ||||||
|  |             ExpressionKind::AccessCall( | ||||||
|  |                 Box::new(apply_inner(PrimaryExpression(*value_expr.clone()), fun)), | ||||||
|  |                 fn_call.clone(), | ||||||
|  |             ), | ||||||
|  |             expr.0 .1, | ||||||
|  |         ), | ||||||
|  |         _ => fun(expr), | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| #[derive(Debug)] | #[derive(Debug)] | ||||||
| pub struct PrimaryExpression(Expression); | pub struct PrimaryExpression(Expression); | ||||||
| 
 | 
 | ||||||
| @ -195,18 +225,21 @@ impl Parse for PrimaryExpression { | |||||||
|         } else if let (Some(Token::Et), Some(Token::MutKeyword)) = (stream.peek(), stream.peek2()) { |         } else if let (Some(Token::Et), Some(Token::MutKeyword)) = (stream.peek(), stream.peek2()) { | ||||||
|             stream.next(); // Consume Et
 |             stream.next(); // Consume Et
 | ||||||
|             stream.next(); // Consume mut
 |             stream.next(); // Consume mut
 | ||||||
|             let Some(Token::Identifier(name)) = stream.next() else { |             Expression( | ||||||
|                 return Err(stream.expected_err("identifier")?); |                 Kind::Borrow(Box::new(stream.parse()?), true), | ||||||
|             }; |                 stream.get_range().unwrap(), | ||||||
|             Expression(Kind::Borrow(name, true), stream.get_range().unwrap()) |             ) | ||||||
|         } else if let (Some(Token::Et), Some(Token::Identifier(name))) = (stream.peek(), stream.peek2()) { |         } else if let Some(Token::Et) = stream.peek() { | ||||||
|             stream.next(); // Consume Et
 |             stream.next(); // Consume Et
 | ||||||
|             stream.next(); // Consume identifier
 |             Expression( | ||||||
|             Expression(Kind::Borrow(name, false), stream.get_range().unwrap()) |                 Kind::Borrow(Box::new(stream.parse()?), false), | ||||||
|         } else if let (Some(Token::Star), Some(Token::Identifier(name))) = (stream.peek(), stream.peek2()) { |                 stream.get_range().unwrap(), | ||||||
|  |             ) | ||||||
|  |         } else if let Some(Token::Star) = stream.peek() { | ||||||
|             stream.next(); // Consume Et
 |             stream.next(); // Consume Et
 | ||||||
|             stream.next(); // Consume identifier
 |             apply_inner(stream.parse()?, |e| { | ||||||
|             Expression(Kind::Deref(name), stream.get_range().unwrap()) |                 Expression(Kind::Deref(Box::new(e.0)), stream.get_range().unwrap()) | ||||||
|  |             }) | ||||||
|         } else if let Ok(unary) = stream.parse() { |         } else if let Ok(unary) = stream.parse() { | ||||||
|             Expression( |             Expression( | ||||||
|                 Kind::UnaryOperation(unary, Box::new(stream.parse()?)), |                 Kind::UnaryOperation(unary, Box::new(stream.parse()?)), | ||||||
|  | |||||||
| @ -361,19 +361,10 @@ impl ast::Expression { | |||||||
|                 mir::TypeKind::Vague(mir::VagueType::Unknown), |                 mir::TypeKind::Vague(mir::VagueType::Unknown), | ||||||
|                 name.clone(), |                 name.clone(), | ||||||
|             ), |             ), | ||||||
|             ast::ExpressionKind::Borrow(name, mutable) => mir::ExprKind::Borrow( |             ast::ExpressionKind::Borrow(expr, mutable) => { | ||||||
|                 NamedVariableRef( |                 mir::ExprKind::Borrow(Box::new(expr.process(module_id)), *mutable) | ||||||
|                     mir::TypeKind::Vague(mir::VagueType::Unknown), |             } | ||||||
|                     name.clone(), |             ast::ExpressionKind::Deref(expr) => mir::ExprKind::Deref(Box::new(expr.process(module_id))), | ||||||
|                     self.1.as_meta(module_id), |  | ||||||
|                 ), |  | ||||||
|                 *mutable, |  | ||||||
|             ), |  | ||||||
|             ast::ExpressionKind::Deref(name) => mir::ExprKind::Deref(NamedVariableRef( |  | ||||||
|                 mir::TypeKind::Vague(mir::VagueType::Unknown), |  | ||||||
|                 name.clone(), |  | ||||||
|                 self.1.as_meta(module_id), |  | ||||||
|             )), |  | ||||||
|             ast::ExpressionKind::UnaryOperation(unary_operator, expr) => match unary_operator { |             ast::ExpressionKind::UnaryOperation(unary_operator, expr) => match unary_operator { | ||||||
|                 ast::UnaryOperator::Plus => mir::ExprKind::BinOp( |                 ast::UnaryOperator::Plus => mir::ExprKind::BinOp( | ||||||
|                     mir::BinaryOperator::Add, |                     mir::BinaryOperator::Add, | ||||||
|  | |||||||
| @ -1144,12 +1144,8 @@ impl mir::Expression { | |||||||
|                     TypeKind::CustomType(type_key), |                     TypeKind::CustomType(type_key), | ||||||
|                 )) |                 )) | ||||||
|             } |             } | ||||||
|             mir::ExprKind::Borrow(varref, mutable) => { |             mir::ExprKind::Borrow(expr, mutable) => { | ||||||
|                 varref.0.known().expect("variable type unknown"); |                 let v = expr.codegen(scope, &state.load(false))?.unwrap(); | ||||||
|                 let v = scope |  | ||||||
|                     .stack_values |  | ||||||
|                     .get(&varref.1) |  | ||||||
|                     .expect("Variable reference not found?!"); |  | ||||||
| 
 | 
 | ||||||
|                 let TypeKind::CodegenPtr(ptr_inner) = &v.1 else { |                 let TypeKind::CodegenPtr(ptr_inner) = &v.1 else { | ||||||
|                     panic!(); |                     panic!(); | ||||||
| @ -1160,12 +1156,8 @@ impl mir::Expression { | |||||||
|                     TypeKind::Borrow(Box::new(*ptr_inner.clone()), *mutable), |                     TypeKind::Borrow(Box::new(*ptr_inner.clone()), *mutable), | ||||||
|                 )) |                 )) | ||||||
|             } |             } | ||||||
|             mir::ExprKind::Deref(varref) => { |             mir::ExprKind::Deref(expr) => { | ||||||
|                 varref.0.known().expect("variable type unknown"); |                 let v = expr.codegen(scope, &state.load(false))?.unwrap(); | ||||||
|                 let v = scope |  | ||||||
|                     .stack_values |  | ||||||
|                     .get(&varref.1) |  | ||||||
|                     .expect("Variable reference not found?!"); |  | ||||||
| 
 | 
 | ||||||
|                 let TypeKind::CodegenPtr(ptr_inner) = &v.1 else { |                 let TypeKind::CodegenPtr(ptr_inner) = &v.1 else { | ||||||
|                     panic!(); |                     panic!(); | ||||||
| @ -1174,7 +1166,7 @@ impl mir::Expression { | |||||||
|                 let var_ptr_instr = scope |                 let var_ptr_instr = scope | ||||||
|                     .block |                     .block | ||||||
|                     .build_named( |                     .build_named( | ||||||
|                         format!("{}.deref", varref.1), |                         format!("{}.deref", expr.backing_var().unwrap().1), | ||||||
|                         Instr::Load(v.0.instr(), ptr_inner.get_type(scope.type_values)), |                         Instr::Load(v.0.instr(), ptr_inner.get_type(scope.type_values)), | ||||||
|                     ) |                     ) | ||||||
|                     .unwrap(); |                     .unwrap(); | ||||||
| @ -1187,7 +1179,7 @@ impl mir::Expression { | |||||||
|                                     scope |                                     scope | ||||||
|                                         .block |                                         .block | ||||||
|                                         .build_named( |                                         .build_named( | ||||||
|                                             format!("{}.deref.inner", varref.1), |                                             format!("{}.deref.inner", expr.backing_var().unwrap().1), | ||||||
|                                             Instr::Load(var_ptr_instr, inner.get_type(scope.type_values)), |                                             Instr::Load(var_ptr_instr, inner.get_type(scope.type_values)), | ||||||
|                                         ) |                                         ) | ||||||
|                                         .unwrap(), |                                         .unwrap(), | ||||||
|  | |||||||
| @ -425,15 +425,15 @@ impl Expression { | |||||||
|                 ReturnKind::Soft, |                 ReturnKind::Soft, | ||||||
|                 TypeKind::CustomType(CustomTypeKey(name.clone(), mod_id)), |                 TypeKind::CustomType(CustomTypeKey(name.clone(), mod_id)), | ||||||
|             )), |             )), | ||||||
|             Borrow(var, mutable) => { |             Borrow(expr, mutable) => { | ||||||
|                 let ret_type = var.return_type()?; |                 let ret_type = expr.return_type(refs, mod_id)?; | ||||||
|                 Ok((ret_type.0, TypeKind::Borrow(Box::new(ret_type.1), *mutable))) |                 Ok((ret_type.0, TypeKind::Borrow(Box::new(ret_type.1), *mutable))) | ||||||
|             } |             } | ||||||
|             Deref(var) => { |             Deref(expr) => { | ||||||
|                 let (kind, ret_type) = var.return_type()?; |                 let (kind, ret_type) = expr.return_type(refs, mod_id)?; | ||||||
|                 match ret_type.resolve_weak(refs) { |                 match ret_type.resolve_weak(refs) { | ||||||
|                     TypeKind::Borrow(type_kind, _) => Ok((kind, *type_kind)), |                     TypeKind::Borrow(type_kind, _) => Ok((kind, *type_kind)), | ||||||
|                     _ => Err(ReturnTypeOther::DerefNonBorrow(var.2)), |                     _ => Err(ReturnTypeOther::DerefNonBorrow(expr.1)), | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             CastTo(expr, type_kind) => match expr.return_type(refs, mod_id) { |             CastTo(expr, type_kind) => match expr.return_type(refs, mod_id) { | ||||||
| @ -452,8 +452,8 @@ impl Expression { | |||||||
|             ExprKind::Variable(var_ref) => Some(var_ref), |             ExprKind::Variable(var_ref) => Some(var_ref), | ||||||
|             ExprKind::Indexed(lhs, _, _) => lhs.backing_var(), |             ExprKind::Indexed(lhs, _, _) => lhs.backing_var(), | ||||||
|             ExprKind::Accessed(lhs, _, _) => lhs.backing_var(), |             ExprKind::Accessed(lhs, _, _) => lhs.backing_var(), | ||||||
|             ExprKind::Borrow(var, _) => Some(var), |             ExprKind::Borrow(expr, _) => expr.backing_var(), | ||||||
|             ExprKind::Deref(var) => Some(var), |             ExprKind::Deref(expr) => expr.backing_var(), | ||||||
|             ExprKind::Block(block) => block.backing_var(), |             ExprKind::Block(block) => block.backing_var(), | ||||||
|             ExprKind::Array(_) => None, |             ExprKind::Array(_) => None, | ||||||
|             ExprKind::Struct(_, _) => None, |             ExprKind::Struct(_, _) => None, | ||||||
|  | |||||||
| @ -401,12 +401,8 @@ impl<'map> Pass for LinkerPass<'map> { | |||||||
|                 } |                 } | ||||||
|                 super::ExprKind::BinOp(.., type_kind) => *type_kind = type_kind.update_imported(extern_types, mod_id), |                 super::ExprKind::BinOp(.., type_kind) => *type_kind = type_kind.update_imported(extern_types, mod_id), | ||||||
| 
 | 
 | ||||||
|                 super::ExprKind::Borrow(var_ref, _) => { |                 super::ExprKind::Borrow(expr, _) => {} | ||||||
|                     var_ref.0 = var_ref.0.update_imported(extern_types, mod_id); |                 super::ExprKind::Deref(expr) => {} | ||||||
|                 } |  | ||||||
|                 super::ExprKind::Deref(var_ref) => { |  | ||||||
|                     var_ref.0 = var_ref.0.update_imported(extern_types, mod_id); |  | ||||||
|                 } |  | ||||||
|                 super::ExprKind::CastTo(_, type_kind) => *type_kind = type_kind.update_imported(extern_types, mod_id), |                 super::ExprKind::CastTo(_, type_kind) => *type_kind = type_kind.update_imported(extern_types, mod_id), | ||||||
|                 _ => {} |                 _ => {} | ||||||
|             } |             } | ||||||
|  | |||||||
| @ -261,8 +261,8 @@ pub enum ExprKind { | |||||||
|     AssociatedFunctionCall(TypeKind, FunctionCall), |     AssociatedFunctionCall(TypeKind, FunctionCall), | ||||||
|     If(IfExpression), |     If(IfExpression), | ||||||
|     Block(Block), |     Block(Block), | ||||||
|     Borrow(NamedVariableRef, bool), |     Borrow(Box<Expression>, bool), | ||||||
|     Deref(NamedVariableRef), |     Deref(Box<Expression>), | ||||||
|     CastTo(Box<Expression>, TypeKind), |     CastTo(Box<Expression>, TypeKind), | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -65,7 +65,9 @@ pub enum ErrorKind { | |||||||
|     #[error("This type of expression can not be used for assignment")] |     #[error("This type of expression can not be used for assignment")] | ||||||
|     InvalidSetExpression, |     InvalidSetExpression, | ||||||
|     #[error("Can not deref {0}, as it is not a borrow")] |     #[error("Can not deref {0}, as it is not a borrow")] | ||||||
|     AttemptedDerefNonBorrow(String), |     AttemptedDerefNonBorrow(TypeKind), | ||||||
|  |     #[error("Can not borrow this kind of expression")] | ||||||
|  |     ImpossibleBorrow, | ||||||
|     #[error("Types {0} and {1} differ in mutability")] |     #[error("Types {0} and {1} differ in mutability")] | ||||||
|     TypesDifferMutability(TypeKind, TypeKind), |     TypesDifferMutability(TypeKind, TypeKind), | ||||||
|     #[error("Cannot mutably borrow variable {0}, which is not declared as mutable")] |     #[error("Cannot mutably borrow variable {0}, which is not declared as mutable")] | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| //! This module contains code relevant to doing a type checking pass on the MIR.
 | //! This module contains code relevant to doing a type checking pass on the MIR.
 | ||||||
| //! During typechecking relevant types are also coerced if possible.
 | //! During typechecking relevant types are also coerced if possible.
 | ||||||
| use std::{collections::HashSet, convert::Infallible, iter}; | use std::{collections::HashSet, convert::Infallible, hint, iter}; | ||||||
| 
 | 
 | ||||||
| use crate::{mir::*, util::try_all}; | use crate::{mir::*, util::try_all}; | ||||||
| use VagueType as Vague; | use VagueType as Vague; | ||||||
| @ -668,60 +668,49 @@ impl Expression { | |||||||
| 
 | 
 | ||||||
|                 Ok(TypeKind::CustomType(type_key)) |                 Ok(TypeKind::CustomType(type_key)) | ||||||
|             } |             } | ||||||
|             ExprKind::Borrow(var_ref, mutable) => { |             ExprKind::Borrow(expr, mutable) => { | ||||||
|                 let scope_var = state.scope.variables.get(&var_ref.1).cloned(); |                 let hint_t = if let HintKind::Coerce(hint_t) = hint_t { | ||||||
| 
 |                     if let TypeKind::Borrow(inner, _) = hint_t { | ||||||
|                 let existing = state |                         HintKind::Coerce(*inner) | ||||||
|                     .or_else( |                     } else { | ||||||
|                         scope_var |                         return Err(ErrorKind::TypesIncompatible( | ||||||
|                             .clone() |                             hint_t, | ||||||
|                             .map(|var| var.ty) |                             TypeKind::Borrow(Box::new(TypeKind::Vague(VagueType::Unknown)), *mutable), | ||||||
|                             .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())); |  | ||||||
|                     } |                     } | ||||||
|                 } |                 } else { | ||||||
| 
 |                     hint_t | ||||||
|                 // Update typing to be more accurate
 |  | ||||||
|                 var_ref.0 = state.or_else( |  | ||||||
|                     var_ref.0.resolve_ref(typerefs).narrow_into(&existing), |  | ||||||
|                     TypeKind::Vague(Vague::Unknown), |  | ||||||
|                     var_ref.2, |  | ||||||
|                 ); |  | ||||||
| 
 |  | ||||||
|                 Ok(TypeKind::Borrow(Box::new(var_ref.0.clone()), *mutable)) |  | ||||||
|             } |  | ||||||
|             ExprKind::Deref(var_ref) => { |  | ||||||
|                 let existing = state |  | ||||||
|                     .or_else( |  | ||||||
|                         state |  | ||||||
|                             .scope |  | ||||||
|                             .variables |  | ||||||
|                             .get(&var_ref.1) |  | ||||||
|                             .map(|var| &var.ty) |  | ||||||
|                             .cloned() |  | ||||||
|                             .ok_or(ErrorKind::VariableNotDefined(var_ref.1.clone())), |  | ||||||
|                         TypeKind::Vague(Vague::Unknown), |  | ||||||
|                         var_ref.2, |  | ||||||
|                     ) |  | ||||||
|                     .resolve_ref(typerefs); |  | ||||||
| 
 |  | ||||||
|                 // Update typing to be more accurate
 |  | ||||||
|                 let TypeKind::Borrow(inner, mutable) = state.or_else( |  | ||||||
|                     var_ref.0.resolve_ref(typerefs).narrow_into(&existing), |  | ||||||
|                     TypeKind::Vague(Vague::Unknown), |  | ||||||
|                     var_ref.2, |  | ||||||
|                 ) else { |  | ||||||
|                     return Err(ErrorKind::AttemptedDerefNonBorrow(var_ref.1.clone())); |  | ||||||
|                 }; |                 }; | ||||||
| 
 | 
 | ||||||
|                 var_ref.0 = TypeKind::Borrow(inner.clone(), mutable); |                 let expr_ty = expr.typecheck(state, typerefs, hint_t)?.resolve_ref(typerefs); | ||||||
|  | 
 | ||||||
|  |                 if let Some(backing_var) = expr.backing_var() { | ||||||
|  |                     if let Some(scope_var) = state.scope.variables.get(&backing_var.1) { | ||||||
|  |                         if !scope_var.mutable && *mutable { | ||||||
|  |                             return Err(ErrorKind::ImpossibleMutableBorrow(backing_var.1.clone())); | ||||||
|  |                         } | ||||||
|  |                     } else { | ||||||
|  |                         return Err(ErrorKind::VariableNotDefined(backing_var.1.clone())); | ||||||
|  |                     } | ||||||
|  |                 } else { | ||||||
|  |                     return Err(ErrorKind::ImpossibleBorrow); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 Ok(TypeKind::Borrow(Box::new(expr_ty.clone()), *mutable)) | ||||||
|  |             } | ||||||
|  |             ExprKind::Deref(expr) => { | ||||||
|  |                 let hint_t = if let HintKind::Coerce(hint_t) = hint_t { | ||||||
|  |                     HintKind::Coerce(TypeKind::Borrow(Box::new(hint_t), false)) | ||||||
|  |                 } else { | ||||||
|  |                     hint_t | ||||||
|  |                 }; | ||||||
|  | 
 | ||||||
|  |                 let expr_ty = expr.typecheck(state, typerefs, hint_t)?.resolve_ref(typerefs); | ||||||
|  | 
 | ||||||
|  |                 // Update typing to be more accurate
 | ||||||
|  |                 let TypeKind::Borrow(inner, _) = expr_ty else { | ||||||
|  |                     return Err(ErrorKind::AttemptedDerefNonBorrow(expr_ty.clone())); | ||||||
|  |                 }; | ||||||
| 
 | 
 | ||||||
|                 Ok(*inner) |                 Ok(*inner) | ||||||
|             } |             } | ||||||
|  | |||||||
| @ -557,37 +557,23 @@ impl Expression { | |||||||
|                 } |                 } | ||||||
|                 Ok(type_refs.from_type(&TypeKind::CustomType(type_key.clone())).unwrap()) |                 Ok(type_refs.from_type(&TypeKind::CustomType(type_key.clone())).unwrap()) | ||||||
|             } |             } | ||||||
|             ExprKind::Borrow(var, mutable) => { |             ExprKind::Borrow(expr, mutable) => { | ||||||
|                 // Find variable type
 |                 // Find variable type
 | ||||||
|                 let type_ref = type_refs |                 let type_ref = expr.infer_types(state, type_refs)?; | ||||||
|                     .find_var(&var.1) |  | ||||||
|                     .map(|(_, hint)| hint) |  | ||||||
|                     .ok_or(ErrorKind::VariableNotDefined(var.1.clone())); |  | ||||||
| 
 |  | ||||||
|                 // Update MIR type to TypeRef if found
 |  | ||||||
|                 if let Ok(hint) = &type_ref { |  | ||||||
|                     var.0 = hint.as_type(); |  | ||||||
|                 } |  | ||||||
| 
 | 
 | ||||||
|                 Ok(type_refs |                 Ok(type_refs | ||||||
|                     .from_type(&TypeKind::Borrow(Box::new(var.0.clone()), *mutable)) |                     .from_type(&TypeKind::Borrow(Box::new(type_ref.as_type()), *mutable)) | ||||||
|                     .unwrap()) |                     .unwrap()) | ||||||
|             } |             } | ||||||
|             ExprKind::Deref(var) => { |             ExprKind::Deref(expr) => { | ||||||
|                 // Find variable type
 |                 // Find variable type
 | ||||||
|                 let type_ref = type_refs |                 let type_ref = expr.infer_types(state, type_refs)?; | ||||||
|                     .find_var(&var.1) |  | ||||||
|                     .map(|(_, hint)| hint) |  | ||||||
|                     .ok_or(ErrorKind::VariableNotDefined(var.1.clone())); |  | ||||||
| 
 | 
 | ||||||
|                 // Update MIR type to TypeRef if found
 |                 // Update typing to be more accurate
 | ||||||
|                 if let Ok(hint) = &type_ref { |  | ||||||
|                     var.0 = hint.as_type(); |  | ||||||
|                 } |  | ||||||
| 
 | 
 | ||||||
|                 match &var.0.resolve_weak(type_refs.types) { |                 match type_ref.resolve_weak().unwrap() { | ||||||
|                     Borrow(type_kind, _) => Ok(type_refs.from_type(&type_kind).unwrap()), |                     Borrow(inner, _) => Ok(type_refs.from_type(&inner).unwrap()), | ||||||
|                     _ => Err(ErrorKind::AttemptedDerefNonBorrow(var.1.clone())), |                     _ => Err(ErrorKind::AttemptedDerefNonBorrow(type_ref.resolve_deep().unwrap())), | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             ExprKind::CastTo(expression, type_kind) => { |             ExprKind::CastTo(expression, type_kind) => { | ||||||
|  | |||||||
| @ -27,6 +27,10 @@ impl<'scope> TypeRef<'scope> { | |||||||
|                 let resolved_elem_ty = self.1.from_type(&elem_ty).unwrap().resolve_weak()?; |                 let resolved_elem_ty = self.1.from_type(&elem_ty).unwrap().resolve_weak()?; | ||||||
|                 Some(TypeKind::Array(Box::new(resolved_elem_ty), len)) |                 Some(TypeKind::Array(Box::new(resolved_elem_ty), len)) | ||||||
|             } |             } | ||||||
|  |             TypeKind::Borrow(inner_ty, mutable) => { | ||||||
|  |                 let resolved_elem_ty = self.1.from_type(&inner_ty).unwrap().resolve_weak()?; | ||||||
|  |                 Some(TypeKind::Borrow(Box::new(resolved_elem_ty), mutable)) | ||||||
|  |             } | ||||||
|             _ => Some(resolved), |             _ => Some(resolved), | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user