pub fn type_check_func(interner: &mut NodeInterner, func_id: FuncId) -> Result<(), TypeCheckError> {
    // First fetch the metadata and add the types for parameters
    // Note that we do not look for the defining Identifier for a parameter,
    // since we know that it is the parameter itself
    let meta = interner.function_meta(&func_id);
    let declared_return_type = &meta.return_type;
    let can_ignore_ret = meta.can_ignore_return_type();

    for param in meta.parameters.into_iter() {
        interner.push_ident_type(&param.0, param.1);
    }

    // Fetch the HirFunction and iterate all of it's statements
    let hir_func = interner.function(&func_id);
    let func_as_expr = hir_func.as_expr();

    // Convert the function to a block expression and then type check the block expr
    type_check_expression(interner, func_as_expr)?;

    // Check declared return type and actual return type
    let function_last_type = interner.id_type(func_as_expr);

    if !can_ignore_ret && (&function_last_type != declared_return_type) {
        let func_span = interner.id_span(func_as_expr); // XXX: We could be more specific and return the span of the last stmt, however stmts do not have spans yet
        return Err(TypeCheckError::TypeMismatch {
            expected_typ: declared_return_type.to_string(),
            expr_typ: function_last_type.to_string(),
            expr_span: func_span,
        });
    }

    // Return type cannot be public
    if declared_return_type.is_public() {
        return Err(TypeCheckError::PublicReturnType {
            typ: declared_return_type.clone(),
            span: interner.id_span(func_as_expr),
        });
    }

    Ok(())
}
/// Type checks a function and assigns the
/// appropriate types to expressions in a side table
Type checks a function and assigns the
appropriate types to expressions in a side table
Type checks a function and assigns the appropriate types to expressions in a side table
pub fn type_check_func(interner: &mut NodeInterner, func_id: FuncId) -> Result<(), TypeCheckError> {
    // First fetch the metadata and add the types for parameters
    // Note that we do not look for the defining Identifier for a parameter,
    // since we know that it is the parameter itself
    let meta = interner.function_meta(&func_id);
    let declared_return_type = &meta.return_type;
    let can_ignore_ret = meta.can_ignore_return_type();
    for param in meta.parameters.into_iter() {
        interner.push_ident_type(&param.0, param.1);
    }
    // Fetch the HirFunction and iterate all of it's statements
    let hir_func = interner.function(&func_id);
    let func_as_expr = hir_func.as_expr();
    // Convert the function to a block expression and then type check the block expr
    type_check_expression(interner, func_as_expr)?;
    // Check declared return type and actual return type
    let function_last_type = interner.id_type(func_as_expr);
    if !can_ignore_ret && (&function_last_type != declared_return_type) {
        let func_span = interner.id_span(func_as_expr); // XXX: We could be more specific and return the span of the last stmt, however stmts do not have spans yet
        return Err(TypeCheckError::TypeMismatch {
            expected_typ: declared_return_type.to_string(),
            expr_typ: function_last_type.to_string(),
            expr_span: func_span,
        });
    }
    // Return type cannot be public
    if declared_return_type.is_public() {
        return Err(TypeCheckError::PublicReturnType {
            typ: declared_return_type.clone(),
            span: interner.id_span(func_as_expr),
        });
    }
    Ok(())
}
pub fn type_check_func ( interner : & mut NodeInterner , func_id : FuncId ) -> Result < ( ) , TypeCheckError > { // First fetch the metadata and add the types for parameters // Note that we do not look for the defining Identifier for a parameter, // since we know that it is the parameter itself let meta = interner . function_meta ( & func_id ) ; let declared_return_type = & meta . return_type ; let can_ignore_ret = meta . can_ignore_return_type ( ) ; for param in meta . parameters . into_iter ( ) { interner . push_ident_type ( & param . 0 , param . 1 ) ; } // Fetch the HirFunction and iterate all of it's statements let hir_func = interner . function ( & func_id ) ; let func_as_expr = hir_func . as_expr ( ) ; // Convert the function to a block expression and then type check the block expr type_check_expression ( interner , func_as_expr ) ? ; // Check declared return type and actual return type let function_last_type = interner . id_type ( func_as_expr ) ; if ! can_ignore_ret && ( & function_last_type != declared_return_type ) { let func_span = interner . id_span ( func_as_expr ) ; // XXX: We could be more specific and return the span of the last stmt, however stmts do not have spans yet return Err ( TypeCheckError :: TypeMismatch { expected_typ : declared_return_type . to_string ( ) , expr_typ : function_last_type . to_string ( ) , expr_span : func_span , } ) ; } // Return type cannot be public if declared_return_type . is_public ( ) { return Err ( TypeCheckError :: PublicReturnType { typ : declared_return_type . clone ( ) , span : interner . id_span ( func_as_expr ) , } ) ; } Ok ( ( ) ) }
Type checks a function and assigns the
appropriate types to expressions in a side table
Type checks a function and assigns the appropriate types to expressions in a side table
interner
&mut NodeInterner
func_id
FuncId
interner
&mut NodeInterner
func_id
FuncId