diff --git a/dust-lang/src/abstract_tree/built_in_function.rs b/dust-lang/src/abstract_tree/built_in_function.rs index 96962a9..0badd5f 100644 --- a/dust-lang/src/abstract_tree/built_in_function.rs +++ b/dust-lang/src/abstract_tree/built_in_function.rs @@ -195,7 +195,6 @@ where manage_memory: bool, ) -> Result, RuntimeError> { self.context.set_parent(context.clone())?; - self.function.call(&self.context, manage_memory) } diff --git a/dust-lang/src/abstract_tree/function_call.rs b/dust-lang/src/abstract_tree/function_call.rs index 362fcd1..34e0a3a 100644 --- a/dust-lang/src/abstract_tree/function_call.rs +++ b/dust-lang/src/abstract_tree/function_call.rs @@ -116,7 +116,7 @@ impl AbstractNode for FunctionCall { )); }; - let function_context = Context::new(None); + let function_context = Context::new(Some(context.clone())); if let Some(type_parameters) = function.type_parameters() { for identifier in type_parameters { diff --git a/dust-lang/src/abstract_tree/if_else.rs b/dust-lang/src/abstract_tree/if_else.rs index 3c0d4b8..acd8db5 100644 --- a/dust-lang/src/abstract_tree/if_else.rs +++ b/dust-lang/src/abstract_tree/if_else.rs @@ -62,36 +62,7 @@ impl AbstractNode for IfElse { self.if_expression.position(), )); }; - let expected_type = if let Some(r#type) = self.if_block.node.expected_type(context)? { - r#type - } else { - return Err(ValidationError::ExpectedExpression(self.if_block.position)); - }; - - if let Type::Boolean = if_expression_type { - if let Some(else_block) = &self.else_block { - else_block.node.validate(context, manage_memory)?; - - let actual_type = if let Some(r#type) = else_block.node.expected_type(context)? { - r#type - } else { - return Err(ValidationError::ExpectedExpression(else_block.position)); - }; - - expected_type.check(&actual_type).map_err(|conflict| { - ValidationError::TypeCheck { - conflict, - actual_position: else_block.node.last_statement().position(), - expected_position: Some(self.if_block.node.first_statement().position()), - } - })?; - } - } else { - return Err(ValidationError::ExpectedBoolean { - actual: if_expression_type, - position: self.if_expression.position(), - }); - } + let if_block_type = self.if_block.node.expected_type(context)?; if let Some(else_ifs) = &self.else_ifs { for (expression, block) in else_ifs { @@ -100,19 +71,17 @@ impl AbstractNode for IfElse { if let Some(Type::Boolean) = expression_type { block.node.validate(context, manage_memory)?; - let actual_type = if let Some(r#type) = block.node.expected_type(context)? { - r#type - } else { - return Err(ValidationError::ExpectedExpression(block.position)); - }; + let else_if_block_type = block.node.expected_type(context)?; - expected_type.check(&actual_type).map_err(|conflict| { - ValidationError::TypeCheck { - conflict, - actual_position: self.if_block.node.last_statement().position(), - expected_position: Some(self.if_expression.position()), - } - })?; + if let (Some(expected), Some(actual)) = (&if_block_type, else_if_block_type) { + expected + .check(&actual) + .map_err(|conflict| ValidationError::TypeCheck { + conflict, + actual_position: self.if_block.node.last_statement().position(), + expected_position: Some(self.if_expression.position()), + })?; + } } else { return Err(ValidationError::ExpectedBoolean { actual: if_expression_type, @@ -122,6 +91,22 @@ impl AbstractNode for IfElse { } } + if let Some(block) = &self.else_block { + block.node.validate(context, manage_memory)?; + + let else_if_block_type = block.node.expected_type(context)?; + + if let (Some(expected), Some(actual)) = (if_block_type, else_if_block_type) { + expected + .check(&actual) + .map_err(|conflict| ValidationError::TypeCheck { + conflict, + actual_position: self.if_block.node.last_statement().position(), + expected_position: Some(self.if_expression.position()), + })?; + } + } + Ok(()) } diff --git a/dust-lang/src/abstract_tree/value_node.rs b/dust-lang/src/abstract_tree/value_node.rs index 2a9c53d..1ef51b8 100644 --- a/dust-lang/src/abstract_tree/value_node.rs +++ b/dust-lang/src/abstract_tree/value_node.rs @@ -83,6 +83,8 @@ impl AbstractNode for ValueNode { context_template, .. }) => { + context_template.set_parent(outer_context.clone())?; + if let Some(type_parameters) = type_parameters { for identifier in type_parameters { context_template.set_type(