Perform type inference for array and indexing expressions
This commit is contained in:
		
							parent
							
								
									64f07002b4
								
							
						
					
					
						commit
						4f8153643b
					
				| @ -40,6 +40,8 @@ pub enum ErrorKind { | ||||
|     TypeNotInferrable(TypeKind), | ||||
|     #[error("Expected branch type to be {0}, found {1} instead")] | ||||
|     BranchTypesDiffer(TypeKind, TypeKind), | ||||
|     #[error("Attempted to index a non-array type of {0}")] | ||||
|     TriedIndexingNonArray(TypeKind), | ||||
| } | ||||
| 
 | ||||
| /// Struct used to implement a type-checking pass that can be performed on the
 | ||||
|  | ||||
| @ -4,7 +4,9 @@ | ||||
| //! must then be passed through TypeCheck with the same [`TypeRefs`] in order to
 | ||||
| //! place the correct types from the IDs and check that there are no issues.
 | ||||
| 
 | ||||
| use std::iter; | ||||
| use std::{convert::Infallible, iter}; | ||||
| 
 | ||||
| use crate::util::try_all; | ||||
| 
 | ||||
| use super::{ | ||||
|     pass::{Pass, PassState, ScopeVariable}, | ||||
| @ -261,8 +263,47 @@ impl Expression { | ||||
|                     ReturnKind::Soft => Ok(block_ref.1), | ||||
|                 } | ||||
|             } | ||||
|             ExprKind::Index(expression, _) => todo!("type inference for index expression"), | ||||
|             ExprKind::Array(expressions) => todo!("type inference for array expression"), | ||||
|             ExprKind::Index(expression, _) => { | ||||
|                 let expr_ty = expression.infer_types(state, type_refs)?; | ||||
|                 let kind = unsafe { expr_ty.resolve_type() }; | ||||
|                 match kind { | ||||
|                     Array(type_kind, _) => Ok(type_refs.from_type(&type_kind).unwrap()), | ||||
|                     _ => Err(ErrorKind::TriedIndexingNonArray(kind)), | ||||
|                 } | ||||
|             } | ||||
|             ExprKind::Array(expressions) => { | ||||
|                 let mut expr_types_result = try_all( | ||||
|                     expressions | ||||
|                         .iter_mut() | ||||
|                         .map(|e| (*e).infer_types(state, type_refs)) | ||||
|                         .collect(), | ||||
|                 ); | ||||
|                 match &mut expr_types_result { | ||||
|                     Ok(expr_types) => { | ||||
|                         let mut iter = expr_types.iter_mut(); | ||||
|                         if let Some(first) = iter.next() { | ||||
|                             while let Some(other) = iter.next() { | ||||
|                                 first.narrow(other); | ||||
|                             } | ||||
| 
 | ||||
|                             Ok(type_refs | ||||
|                                 .from_type(&Array( | ||||
|                                     Box::new(first.as_type()), | ||||
|                                     expressions.len() as u64, | ||||
|                                 )) | ||||
|                                 .unwrap()) | ||||
|                         } else { | ||||
|                             todo!(); | ||||
|                         } | ||||
|                     } | ||||
|                     Err(errors) => { | ||||
|                         for error in errors { | ||||
|                             state.ok::<_, Infallible>(Err(error.clone()), self.1); | ||||
|                         } | ||||
|                         todo!(); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -140,6 +140,11 @@ impl<'outer> ScopeTypeRefs<'outer> { | ||||
|                 self.types.type_refs.borrow().get(inner_idx).cloned()? | ||||
|             } | ||||
|             TypeKind::Vague(_) => self.types.new(ty), | ||||
|             TypeKind::Array(elem_ty, length) => { | ||||
|                 let elem_ty = self.from_type(elem_ty)?; | ||||
|                 self.types | ||||
|                     .new(&TypeKind::Array(Box::new(elem_ty.as_type()), *length)) | ||||
|             } | ||||
|             _ => { | ||||
|                 if let Some(ty_ref) = self.types.find(ty) { | ||||
|                     ty_ref | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user