Use FunctionDefinitionKind for binops
This commit is contained in:
		
							parent
							
								
									7c6de93b31
								
							
						
					
					
						commit
						a7795f83db
					
				| @ -111,7 +111,10 @@ impl ast::Module { | ||||
|                         op: op.mir(), | ||||
|                         rhs: (rhs.0.clone(), rhs.1 .0.into_mir(module_id)), | ||||
|                         return_ty: return_ty.0.into_mir(module_id), | ||||
|                         block: block.into_mir(module_id), | ||||
|                         fn_kind: mir::FunctionDefinitionKind::Local( | ||||
|                             block.into_mir(module_id), | ||||
|                             block.2.as_meta(module_id), | ||||
|                         ), | ||||
|                         meta: signature_range.as_meta(module_id), | ||||
|                     }); | ||||
|                 } | ||||
|  | ||||
| @ -66,7 +66,7 @@ impl Display for BinopDefinition { | ||||
|             "impl binop ({}: {:#}) {} ({}: {:#}) -> {:#} ", | ||||
|             self.lhs.0, self.lhs.1, self.op, self.rhs.0, self.rhs.1, self.return_ty | ||||
|         )?; | ||||
|         Display::fmt(&self.block, f) | ||||
|         Display::fmt(&self.fn_kind, f) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -371,13 +371,17 @@ pub struct BinopDefinition { | ||||
|     pub op: BinaryOperator, | ||||
|     pub rhs: (String, TypeKind), | ||||
|     pub return_ty: TypeKind, | ||||
|     pub block: Block, | ||||
|     pub fn_kind: FunctionDefinitionKind, | ||||
|     pub meta: Metadata, | ||||
| } | ||||
| 
 | ||||
| impl BinopDefinition { | ||||
|     pub fn block_meta(&self) -> Metadata { | ||||
|         self.block.meta | ||||
|     pub fn block_meta(&self) -> Option<Metadata> { | ||||
|         match &self.fn_kind { | ||||
|             FunctionDefinitionKind::Local(block, _) => Some(block.meta), | ||||
|             FunctionDefinitionKind::Extern(_) => None, | ||||
|             FunctionDefinitionKind::Intrinsic(_) => None, | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     pub fn signature(&self) -> Metadata { | ||||
|  | ||||
| @ -136,7 +136,7 @@ impl<'t> Pass for TypeCheck<'t> { | ||||
| 
 | ||||
|         for binop in &mut module.binop_defs { | ||||
|             let res = binop.typecheck(&self.refs, &mut state.inner()); | ||||
|             state.ok(res, binop.block_meta()); | ||||
|             state.ok(res, binop.block_meta().unwrap_or(binop.signature())); | ||||
|         } | ||||
| 
 | ||||
|         for function in &mut module.functions { | ||||
| @ -206,15 +206,19 @@ impl BinopDefinition { | ||||
|         let return_type = self.return_ty.clone().assert_known(typerefs, state)?; | ||||
| 
 | ||||
|         state.scope.return_type_hint = Some(self.return_ty.clone()); | ||||
|         let inferred = self | ||||
|             .block | ||||
|             .typecheck(&mut state.inner(), &typerefs, Some(&return_type)); | ||||
|         let inferred = | ||||
|             self.fn_kind | ||||
|                 .typecheck(&typerefs, &mut state.inner(), Some(return_type.clone())); | ||||
| 
 | ||||
|         match inferred { | ||||
|             Ok(t) => return_type | ||||
|                 .collapse_into(&t.1) | ||||
|                 .or(Err(ErrorKind::ReturnTypeMismatch(return_type, t.1))), | ||||
|             Err(e) => Ok(state.or_else(Err(e), return_type, self.block_meta())), | ||||
|             Err(e) => Ok(state.or_else( | ||||
|                 Err(e), | ||||
|                 return_type, | ||||
|                 self.block_meta().unwrap_or(self.signature()), | ||||
|             )), | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -246,10 +250,30 @@ impl FunctionDefinition { | ||||
|         } | ||||
| 
 | ||||
|         let return_type = self.return_type.clone().assert_known(typerefs, state)?; | ||||
|         let inferred = match &mut self.kind { | ||||
|         let inferred = self | ||||
|             .kind | ||||
|             .typecheck(typerefs, state, Some(self.return_type.clone())); | ||||
| 
 | ||||
|         match inferred { | ||||
|             Ok(t) => return_type | ||||
|                 .collapse_into(&t.1) | ||||
|                 .or(Err(ErrorKind::ReturnTypeMismatch(return_type, t.1))), | ||||
|             Err(e) => Ok(state.or_else(Err(e), return_type, self.block_meta())), | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl FunctionDefinitionKind { | ||||
|     fn typecheck( | ||||
|         &mut self, | ||||
|         typerefs: &TypeRefs, | ||||
|         state: &mut TypecheckPassState, | ||||
|         hint: Option<TypeKind>, | ||||
|     ) -> Result<(ReturnKind, TypeKind), ErrorKind> { | ||||
|         match self { | ||||
|             FunctionDefinitionKind::Local(block, _) => { | ||||
|                 state.scope.return_type_hint = Some(self.return_type.clone()); | ||||
|                 block.typecheck(&mut state.inner(), &typerefs, Some(&return_type)) | ||||
|                 state.scope.return_type_hint = hint.clone(); | ||||
|                 block.typecheck(&mut state.inner(), &typerefs, hint.as_ref()) | ||||
|             } | ||||
|             FunctionDefinitionKind::Extern(_) => { | ||||
|                 Ok((ReturnKind::Soft, TypeKind::Vague(Vague::Unknown))) | ||||
| @ -257,13 +281,6 @@ impl FunctionDefinition { | ||||
|             FunctionDefinitionKind::Intrinsic(..) => { | ||||
|                 Ok((ReturnKind::Soft, TypeKind::Vague(Vague::Unknown))) | ||||
|             } | ||||
|         }; | ||||
| 
 | ||||
|         match inferred { | ||||
|             Ok(t) => return_type | ||||
|                 .collapse_into(&t.1) | ||||
|                 .or(Err(ErrorKind::ReturnTypeMismatch(return_type, t.1))), | ||||
|             Err(e) => Ok(state.or_else(Err(e), return_type, self.block_meta())), | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -80,7 +80,7 @@ impl<'t> Pass for TypeInference<'t> { | ||||
| 
 | ||||
|         for binop in &mut module.binop_defs { | ||||
|             let res = binop.infer_types(&self.refs, &mut state.inner()); | ||||
|             state.ok(res, binop.block_meta()); | ||||
|             state.ok(res, binop.block_meta().unwrap_or(binop.signature())); | ||||
|         } | ||||
| 
 | ||||
|         for function in &mut module.functions { | ||||
| @ -124,18 +124,12 @@ impl BinopDefinition { | ||||
|             self.signature(), | ||||
|         ); | ||||
| 
 | ||||
|         state.scope.return_type_hint = Some(self.return_ty.clone()); | ||||
|         let ret_res = self.block.infer_types(state, &scope_hints); | ||||
|         let (_, mut ret_ty) = state.or_else( | ||||
|             ret_res, | ||||
|             ( | ||||
|                 ReturnKind::Soft, | ||||
|                 scope_hints.from_type(&Vague(Unknown)).unwrap(), | ||||
|             ), | ||||
|             self.block_meta(), | ||||
|         ); | ||||
| 
 | ||||
|         let ret_ty = self | ||||
|             .fn_kind | ||||
|             .infer_types(state, &scope_hints, Some(self.return_ty.clone()))?; | ||||
|         if let Some(mut ret_ty) = ret_ty { | ||||
|             ret_ty.narrow(&scope_hints.from_type(&self.return_ty).unwrap()); | ||||
|         } | ||||
| 
 | ||||
|         Ok(()) | ||||
|     } | ||||
| @ -147,10 +141,10 @@ impl FunctionDefinition { | ||||
|         type_refs: &TypeRefs, | ||||
|         state: &mut TypeInferencePassState, | ||||
|     ) -> Result<(), ErrorKind> { | ||||
|         let scope_hints = ScopeTypeRefs::from(type_refs); | ||||
|         let scope_refs = ScopeTypeRefs::from(type_refs); | ||||
|         for param in &self.parameters { | ||||
|             let param_t = state.or_else(param.1.assert_unvague(), Vague(Unknown), self.signature()); | ||||
|             let res = scope_hints | ||||
|             let res = scope_refs | ||||
|                 .new_var(param.0.clone(), false, ¶m_t) | ||||
|                 .or(Err(ErrorKind::VariableAlreadyDefined(param.0.clone()))); | ||||
|             state.ok(res, self.signature()); | ||||
| @ -161,21 +155,51 @@ impl FunctionDefinition { | ||||
|                 state.scope.return_type_hint = Some(self.return_type.clone()); | ||||
| 
 | ||||
|                 // Infer block return type
 | ||||
|                 let ret_res = block.infer_types(state, &scope_hints); | ||||
|                 let ret_res = block.infer_types(state, &scope_refs); | ||||
| 
 | ||||
|                 // Narrow block type to declared function type
 | ||||
|                 if let Some(mut ret_ty) = state.ok(ret_res.map(|(_, ty)| ty), self.block_meta()) { | ||||
|                     ret_ty.narrow(&scope_hints.from_type(&self.return_type).unwrap()); | ||||
|                     ret_ty.narrow(&scope_refs.from_type(&self.return_type).unwrap()); | ||||
|                 } | ||||
|             } | ||||
|             FunctionDefinitionKind::Extern(_) => {} | ||||
|             FunctionDefinitionKind::Intrinsic(_) => {} | ||||
|         }; | ||||
|         let return_ty = self | ||||
|             .kind | ||||
|             .infer_types(state, &scope_refs, Some(self.return_type.clone())); | ||||
| 
 | ||||
|         if let Some(Some(mut ret_ty)) = state.ok(return_ty, self.block_meta()) { | ||||
|             ret_ty.narrow(&scope_refs.from_type(&self.return_type).unwrap()); | ||||
|         } | ||||
| 
 | ||||
|         Ok(()) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl FunctionDefinitionKind { | ||||
|     fn infer_types<'s>( | ||||
|         &mut self, | ||||
|         state: &mut TypeInferencePassState, | ||||
|         scope_refs: &'s ScopeTypeRefs, | ||||
|         hint: Option<TypeKind>, | ||||
|     ) -> Result<Option<TypeRef<'s>>, ErrorKind> { | ||||
|         Ok(match self { | ||||
|             FunctionDefinitionKind::Local(block, _) => { | ||||
|                 state.scope.return_type_hint = hint; | ||||
| 
 | ||||
|                 // Infer block return type
 | ||||
|                 let ret_res = block.infer_types(state, &scope_refs); | ||||
| 
 | ||||
|                 // Narrow block type to declared function type
 | ||||
|                 Some(ret_res.map(|(_, ty)| ty)?) | ||||
|             } | ||||
|             FunctionDefinitionKind::Extern(_) => None, | ||||
|             FunctionDefinitionKind::Intrinsic(_) => None, | ||||
|         }) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl Block { | ||||
|     fn infer_types<'s>( | ||||
|         &mut self, | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user