From 9e0c0b4db34292256f4ac27a9bb0530a9c0435de Mon Sep 17 00:00:00 2001 From: Jeff Date: Mon, 17 Jun 2024 10:50:06 -0400 Subject: [PATCH] Refine type constructor --- dust-lang/src/abstract_tree/as.rs | 14 +- dust-lang/src/abstract_tree/assignment.rs | 12 +- dust-lang/src/abstract_tree/function_call.rs | 10 +- dust-lang/src/abstract_tree/map_index.rs | 2 +- dust-lang/src/abstract_tree/mod.rs | 2 +- .../src/abstract_tree/structure_definition.rs | 8 +- dust-lang/src/abstract_tree/type_alias.rs | 9 +- .../src/abstract_tree/type_constructor.rs | 51 ++++--- dust-lang/src/abstract_tree/value_node.rs | 29 ++-- dust-lang/src/parser.rs | 130 ++++++++++-------- 10 files changed, 136 insertions(+), 131 deletions(-) diff --git a/dust-lang/src/abstract_tree/as.rs b/dust-lang/src/abstract_tree/as.rs index 2346f05..7cf2558 100644 --- a/dust-lang/src/abstract_tree/as.rs +++ b/dust-lang/src/abstract_tree/as.rs @@ -9,18 +9,16 @@ use crate::{ Value, }; -use super::{ - AbstractNode, Evaluation, ExpectedType, Expression, Type, TypeConstructor, WithPosition, -}; +use super::{AbstractNode, Evaluation, ExpectedType, Expression, Type, TypeConstructor}; #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] pub struct As { expression: Expression, - constructor: WithPosition, + constructor: TypeConstructor, } impl As { - pub fn new(expression: Expression, constructor: WithPosition) -> Self { + pub fn new(expression: Expression, constructor: TypeConstructor) -> Self { Self { expression, constructor, @@ -34,7 +32,7 @@ impl AbstractNode for As { _context: &mut Context, _manage_memory: bool, ) -> Result<(), ValidationError> { - match self.constructor.node { + match self.constructor { TypeConstructor::Type(_) => {} _ => todo!("Create an error for this occurence."), }; @@ -61,7 +59,7 @@ impl AbstractNode for As { ValidationError::InterpreterExpectedReturn(expression_position), )); }; - let r#type = self.constructor.node.construct(&context)?; + let r#type = self.constructor.construct(&context)?; let (from_value, to_type): (&ValueInner, Type) = (value.inner().borrow(), r#type); let converted = match (from_value, to_type) { @@ -76,6 +74,6 @@ impl AbstractNode for As { impl ExpectedType for As { fn expected_type(&self, context: &mut Context) -> Result { - self.constructor.node.clone().construct(&context) + self.constructor.clone().construct(&context) } } diff --git a/dust-lang/src/abstract_tree/assignment.rs b/dust-lang/src/abstract_tree/assignment.rs index 214fd69..8d746df 100644 --- a/dust-lang/src/abstract_tree/assignment.rs +++ b/dust-lang/src/abstract_tree/assignment.rs @@ -12,7 +12,7 @@ use super::{AbstractNode, Evaluation, ExpectedType, Statement, TypeConstructor, #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] pub struct Assignment { identifier: WithPosition, - constructor: Option>, + constructor: Option, operator: AssignmentOperator, statement: Box, } @@ -27,7 +27,7 @@ pub enum AssignmentOperator { impl Assignment { pub fn new( identifier: WithPosition, - constructor: Option>, + constructor: Option, operator: AssignmentOperator, statement: Statement, ) -> Self { @@ -44,11 +44,7 @@ impl AbstractNode for Assignment { fn validate(&self, context: &mut Context, manage_memory: bool) -> Result<(), ValidationError> { let statement_type = self.statement.expected_type(context)?; - if let Some(WithPosition { - node: constructor, - position: expected_position, - }) = &self.constructor - { + if let Some(constructor) = &self.constructor { let r#type = constructor.clone().construct(&context)?; r#type @@ -56,7 +52,7 @@ impl AbstractNode for Assignment { .map_err(|conflict| ValidationError::TypeCheck { conflict, actual_position: self.statement.position(), - expected_position: Some(expected_position.clone()), + expected_position: Some(constructor.position()), })?; context.set_type(self.identifier.node.clone(), r#type.clone())?; diff --git a/dust-lang/src/abstract_tree/function_call.rs b/dust-lang/src/abstract_tree/function_call.rs index 49d918a..20c564d 100644 --- a/dust-lang/src/abstract_tree/function_call.rs +++ b/dust-lang/src/abstract_tree/function_call.rs @@ -6,21 +6,19 @@ use crate::{ value::ValueInner, }; -use super::{ - AbstractNode, Evaluation, ExpectedType, Expression, Type, TypeConstructor, WithPosition, -}; +use super::{AbstractNode, Evaluation, ExpectedType, Expression, Type, TypeConstructor}; #[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] pub struct FunctionCall { function: Box, - type_arguments: Option>>, + type_arguments: Option>, value_arguments: Vec, } impl FunctionCall { pub fn new( function: Expression, - type_arguments: Option>>, + type_arguments: Option>, value_arguments: Vec, ) -> Self { FunctionCall { @@ -115,7 +113,7 @@ impl AbstractNode for FunctionCall { for (parameter, constructor) in type_parameters.into_iter().zip(type_arguments.into_iter()) { - let r#type = constructor.node.construct(context)?; + let r#type = constructor.construct(context)?; function_context.set_type(parameter.clone(), r#type)?; } diff --git a/dust-lang/src/abstract_tree/map_index.rs b/dust-lang/src/abstract_tree/map_index.rs index 9d553c7..440a850 100644 --- a/dust-lang/src/abstract_tree/map_index.rs +++ b/dust-lang/src/abstract_tree/map_index.rs @@ -104,7 +104,7 @@ impl ExpectedType for MapIndex { for (property, constructor_option, expression) in properties { if property == &index.node { return if let Some(constructor) = constructor_option { - let r#type = constructor.node.clone().construct(&context)?; + let r#type = constructor.clone().construct(&context)?; Ok(r#type) } else { diff --git a/dust-lang/src/abstract_tree/mod.rs b/dust-lang/src/abstract_tree/mod.rs index 657feba..8351d06 100644 --- a/dust-lang/src/abstract_tree/mod.rs +++ b/dust-lang/src/abstract_tree/mod.rs @@ -42,7 +42,7 @@ pub use self::{ statement::Statement, structure_definition::StructureDefinition, type_alias::TypeAssignment, - type_constructor::TypeConstructor, + type_constructor::{FunctionTypeConstructor, ListTypeConstructor, TypeConstructor}, value_expression::Expression, value_node::ValueNode, }; diff --git a/dust-lang/src/abstract_tree/structure_definition.rs b/dust-lang/src/abstract_tree/structure_definition.rs index 50f8f82..49de88d 100644 --- a/dust-lang/src/abstract_tree/structure_definition.rs +++ b/dust-lang/src/abstract_tree/structure_definition.rs @@ -6,16 +6,16 @@ use crate::{ identifier::Identifier, }; -use super::{AbstractNode, Evaluation, Type, TypeConstructor, WithPosition}; +use super::{AbstractNode, Evaluation, Type, TypeConstructor}; #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] pub struct StructureDefinition { name: Identifier, - fields: Vec<(Identifier, WithPosition)>, + fields: Vec<(Identifier, TypeConstructor)>, } impl StructureDefinition { - pub fn new(name: Identifier, fields: Vec<(Identifier, WithPosition)>) -> Self { + pub fn new(name: Identifier, fields: Vec<(Identifier, TypeConstructor)>) -> Self { Self { name, fields } } } @@ -37,7 +37,7 @@ impl AbstractNode for StructureDefinition { let mut fields = Vec::with_capacity(self.fields.len()); for (identifier, constructor) in self.fields { - let r#type = constructor.node.construct(&context)?; + let r#type = constructor.construct(&context)?; fields.push((identifier, r#type)); } diff --git a/dust-lang/src/abstract_tree/type_alias.rs b/dust-lang/src/abstract_tree/type_alias.rs index 4c1a682..e1e8785 100644 --- a/dust-lang/src/abstract_tree/type_alias.rs +++ b/dust-lang/src/abstract_tree/type_alias.rs @@ -11,14 +11,11 @@ use super::{AbstractNode, Evaluation, TypeConstructor, WithPosition}; #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] pub struct TypeAssignment { identifier: WithPosition, - constructor: WithPosition, + constructor: TypeConstructor, } impl TypeAssignment { - pub fn new( - identifier: WithPosition, - constructor: WithPosition, - ) -> Self { + pub fn new(identifier: WithPosition, constructor: TypeConstructor) -> Self { Self { identifier, constructor, @@ -40,7 +37,7 @@ impl AbstractNode for TypeAssignment { context: &mut Context, _manage_memory: bool, ) -> Result { - let r#type = self.constructor.node.construct(&context)?; + let r#type = self.constructor.construct(&context)?; context.set_type(self.identifier.node, r#type)?; diff --git a/dust-lang/src/abstract_tree/type_constructor.rs b/dust-lang/src/abstract_tree/type_constructor.rs index 5643437..7a8744b 100644 --- a/dust-lang/src/abstract_tree/type_constructor.rs +++ b/dust-lang/src/abstract_tree/type_constructor.rs @@ -4,25 +4,41 @@ use serde::{Deserialize, Serialize}; use crate::{context::Context, error::ValidationError, identifier::Identifier}; -use super::{ExpectedType, Type, WithPosition}; +use super::{ExpectedType, SourcePosition, Type, WithPosition}; #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] pub enum TypeConstructor { - Function { - type_parameters: Option>>, - value_parameters: Vec<(WithPosition, Box>)>, - return_type: Box>, - }, + Function(WithPosition), Identifier(WithPosition), - List { - length: usize, - item_type: Box>, - }, + List(WithPosition), ListOf(WithPosition>), - Type(Type), + Type(WithPosition), +} + +#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] +pub struct FunctionTypeConstructor { + pub type_parameters: Option>>, + pub value_parameters: Vec<(WithPosition, Box)>, + pub return_type: Box, +} + +#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] +pub struct ListTypeConstructor { + pub length: usize, + pub item_type: Box, } impl TypeConstructor { + pub fn position(&self) -> SourcePosition { + match self { + TypeConstructor::Function(WithPosition { position, .. }) => *position, + TypeConstructor::Identifier(WithPosition { position, .. }) => *position, + TypeConstructor::List(WithPosition { position, .. }) => *position, + TypeConstructor::ListOf(WithPosition { position, .. }) => *position, + TypeConstructor::Type(WithPosition { position, .. }) => *position, + } + } + pub fn validate( &self, _context: &mut Context, @@ -33,11 +49,7 @@ impl TypeConstructor { pub fn construct(self, context: &Context) -> Result { match self { - TypeConstructor::Function { - type_parameters: _, - value_parameters: _, - return_type: _, - } => todo!(), + TypeConstructor::Function(_) => todo!(), TypeConstructor::Identifier(WithPosition { node: identifier, position, @@ -51,15 +63,16 @@ impl TypeConstructor { }) } } - TypeConstructor::List { length, item_type } => { - let constructed_type = item_type.node.construct(context)?; + TypeConstructor::List(positioned_constructor) => { + let ListTypeConstructor { length, item_type } = positioned_constructor.node; + let constructed_type = item_type.construct(context)?; Ok(Type::List { length, item_type: Box::new(constructed_type), }) } - TypeConstructor::Type(r#type) => Ok(r#type), + TypeConstructor::Type(r#type) => Ok(r#type.node), TypeConstructor::ListOf(_) => todo!(), } } diff --git a/dust-lang/src/abstract_tree/value_node.rs b/dust-lang/src/abstract_tree/value_node.rs index 64227ee..d64123b 100644 --- a/dust-lang/src/abstract_tree/value_node.rs +++ b/dust-lang/src/abstract_tree/value_node.rs @@ -19,13 +19,7 @@ pub enum ValueNode { Float(f64), Integer(i64), List(Vec), - Map( - Vec<( - Identifier, - Option>, - Expression, - )>, - ), + Map(Vec<(Identifier, Option, Expression)>), Range(Range), String(String), Structure { @@ -34,8 +28,8 @@ pub enum ValueNode { }, ParsedFunction { type_parameters: Option>>, - value_parameters: Vec<(Identifier, WithPosition)>, - return_type: WithPosition, + value_parameters: Vec<(Identifier, TypeConstructor)>, + return_type: TypeConstructor, body: WithPosition, }, } @@ -48,13 +42,13 @@ impl AbstractNode for ValueNode { if let Some(constructor) = constructor_option { let actual_type = expression.expected_type(context)?; - let exprected_type = constructor.node.clone().construct(&context)?; + let exprected_type = constructor.clone().construct(&context)?; exprected_type.check(&actual_type).map_err(|conflict| { ValidationError::TypeCheck { conflict, actual_position: expression.position(), - expected_position: Some(constructor.position), + expected_position: Some(constructor.position()), } })?; } @@ -73,7 +67,7 @@ impl AbstractNode for ValueNode { let mut function_context = Context::new(Some(&context)); for (identifier, type_constructor) in value_parameters { - let r#type = type_constructor.node.clone().construct(&function_context)?; + let r#type = type_constructor.clone().construct(&function_context)?; function_context.set_type(identifier.clone(), r#type)?; } @@ -83,14 +77,13 @@ impl AbstractNode for ValueNode { let actual_return_type = body.node.expected_type(&mut function_context)?; return_type - .node .clone() .construct(&function_context)? .check(&actual_return_type) .map_err(|conflict| ValidationError::TypeCheck { conflict, actual_position: body.position, - expected_position: Some(return_type.position), + expected_position: Some(return_type.position()), })?; return Ok(()); @@ -197,12 +190,12 @@ impl AbstractNode for ValueNode { let mut value_parameters = Vec::with_capacity(constructors.len()); for (identifier, constructor) in constructors { - let r#type = constructor.node.construct(&context)?; + let r#type = constructor.construct(&context)?; value_parameters.push((identifier, r#type)); } - let return_type = return_type.node.construct(&context)?; + let return_type = return_type.construct(&context)?; Value::function(type_parameters, value_parameters, return_type, body.node) } @@ -353,7 +346,7 @@ impl ExpectedType for ValueNode { let mut value_parameter_types = Vec::with_capacity(value_parameters.len()); for (identifier, type_constructor) in value_parameters { - let r#type = type_constructor.node.clone().construct(&context)?; + let r#type = type_constructor.clone().construct(&context)?; value_parameter_types.push((identifier.clone(), r#type)); } @@ -364,7 +357,7 @@ impl ExpectedType for ValueNode { .map(|identifier| identifier.node.clone()) .collect() }); - let return_type = return_type.node.clone().construct(&context)?; + let return_type = return_type.clone().construct(&context)?; Type::Function { type_parameters, diff --git a/dust-lang/src/parser.rs b/dust-lang/src/parser.rs index 0a2c988..42973d7 100644 --- a/dust-lang/src/parser.rs +++ b/dust-lang/src/parser.rs @@ -65,13 +65,6 @@ pub fn parser<'src>( }; let type_constructor = recursive(|type_constructor| { - let positioned_type_constructor = - type_constructor - .clone() - .map_with(|constructor: TypeConstructor, state| { - constructor.with_position(state.span()) - }); - let primitive_type = choice(( just(Token::Keyword(Keyword::Any)).to(Type::Any), just(Token::Keyword(Keyword::Bool)).to(Type::Boolean), @@ -81,7 +74,7 @@ pub fn parser<'src>( just(Token::Keyword(Keyword::Range)).to(Type::Range), just(Token::Keyword(Keyword::Str)).to(Type::String), )) - .map(|r#type| TypeConstructor::Type(r#type)); + .map_with(|r#type, state| TypeConstructor::Type(r#type.with_position(state.span()))); let function_type = just(Token::Keyword(Keyword::Fn)) .ignore_then( @@ -99,9 +92,11 @@ pub fn parser<'src>( positioned_identifier .clone() .then_ignore(just(Token::Control(Control::Colon))) - .then(type_constructor.clone().map_with(|constructor, state| { - Box::new(constructor.with_position(state.span())) - })) + .then( + type_constructor + .clone() + .map(|constructor| Box::new(constructor)), + ) .separated_by(just(Token::Control(Control::Comma))) .collect() .delimited_by( @@ -110,16 +105,21 @@ pub fn parser<'src>( ), ) .then_ignore(just(Token::Control(Control::SkinnyArrow))) - .then(positioned_type_constructor.clone()) - .map( - |((type_parameters, value_parameters), return_type)| TypeConstructor::Function { - type_parameters, - value_parameters, - return_type: Box::new(return_type), + .then(type_constructor.clone()) + .map_with( + |((type_parameters, value_parameters), return_type), state| { + TypeConstructor::Function( + FunctionTypeConstructor { + type_parameters, + value_parameters, + return_type: Box::new(return_type), + } + .with_position(state.span()), + ) }, ); - let list = positioned_type_constructor + let list = type_constructor .clone() .clone() .then_ignore(just(Token::Control(Control::Semicolon))) @@ -128,9 +128,14 @@ pub fn parser<'src>( just(Token::Control(Control::SquareOpen)), just(Token::Control(Control::SquareClose)), ) - .map(|(item_type, length)| TypeConstructor::List { - length: length as usize, - item_type: Box::new(item_type), + .map_with(|(item_type, length), state| { + TypeConstructor::List( + ListTypeConstructor { + length: length as usize, + item_type: Box::new(item_type), + } + .with_position(state.span()), + ) }); let list_of = just(Token::Keyword(Keyword::List)) @@ -145,12 +150,8 @@ pub fn parser<'src>( choice((function_type, list, list_of, primitive_type)) }); - let positioned_type_constructor = type_constructor - .clone() - .map_with(|constructor: TypeConstructor, state| constructor.with_position(state.span())); - let type_specification = - just(Token::Control(Control::Colon)).ignore_then(positioned_type_constructor.clone()); + just(Token::Control(Control::Colon)).ignore_then(type_constructor.clone()); let statement = recursive(|statement| { let allow_built_ins = allow_built_ins.clone(); @@ -209,7 +210,7 @@ pub fn parser<'src>( .then( identifier .then_ignore(just(Token::Control(Control::Colon))) - .then(positioned_type_constructor.clone()) + .then(type_constructor.clone()) .separated_by(just(Token::Control(Control::Comma))) .collect() .delimited_by( @@ -218,7 +219,7 @@ pub fn parser<'src>( ), ) .then_ignore(just(Token::Control(Control::SkinnyArrow))) - .then(positioned_type_constructor.clone()) + .then(type_constructor.clone()) .then(block.clone()) .map_with( |(((type_parameters, value_parameters), return_type), body), state| { @@ -293,7 +294,7 @@ pub fn parser<'src>( } }); - let turbofish = positioned_type_constructor + let turbofish = type_constructor .clone() .separated_by(just(Token::Control(Control::Comma))) .at_least(1) @@ -470,8 +471,7 @@ pub fn parser<'src>( ), postfix( 2, - just(Token::Keyword(Keyword::As)) - .ignore_then(positioned_type_constructor.clone()), + just(Token::Keyword(Keyword::As)).ignore_then(type_constructor.clone()), |expression, constructor, span| { Expression::As( Box::new(As::new(expression, constructor)).with_position(span), @@ -576,7 +576,7 @@ pub fn parser<'src>( let type_assignment = just(Token::Keyword(Keyword::Type)) .ignore_then(positioned_identifier.clone()) .then_ignore(just(Token::Operator(Operator::Assign))) - .then(positioned_type_constructor.clone()) + .then(type_constructor.clone()) .map_with(|(identifier, constructor), state| { Statement::TypeAssignment( TypeAssignment::new(identifier, constructor).with_position(state.span()), @@ -619,7 +619,7 @@ mod tests { Statement::TypeAssignment( TypeAssignment::new( Identifier::new("MyType").with_position((5, 11)), - TypeConstructor::Type(Type::String).with_position((14, 17)) + TypeConstructor::Type(Type::String.with_position((14, 17))) ) .with_position((0, 17)) ) @@ -633,7 +633,7 @@ mod tests { Statement::ValueExpression(Expression::As( Box::new(As::new( Expression::Value(ValueNode::Integer(1).with_position((0, 1))), - TypeConstructor::Type(Type::String).with_position((5, 8)) + TypeConstructor::Type(Type::String.with_position((5, 8))) )) .with_position((0, 8)) )) @@ -768,11 +768,11 @@ mod tests { vec![ ( Identifier::new("bar"), - TypeConstructor::Type(Type::Integer).with_position((64, 67)) + TypeConstructor::Type(Type::Integer.with_position((64, 67))) ), ( Identifier::new("baz"), - TypeConstructor::Type(Type::String).with_position((99, 102)) + TypeConstructor::Type(Type::String.with_position((99, 102))) ), ] ) @@ -844,7 +844,7 @@ mod tests { Statement::Assignment( Assignment::new( Identifier::new("foobar").with_position((0, 6)), - Some(TypeConstructor::Type(Type::Boolean).with_position((0, 0))), + Some(TypeConstructor::Type(Type::Boolean.with_position((0, 0)))), AssignmentOperator::Assign, Statement::ValueExpression(Expression::Value( ValueNode::Boolean(true).with_position((16, 20)) @@ -862,15 +862,15 @@ mod tests { Statement::Assignment( Assignment::new( Identifier::new("foobar").with_position((0, 6)), - Some( - TypeConstructor::List { + Some(TypeConstructor::List( + ListTypeConstructor { length: 2, - item_type: Box::new( - TypeConstructor::Type(Type::Integer).with_position((0, 0)) - ) + item_type: Box::new(TypeConstructor::Type( + Type::Integer.with_position((0, 0)) + )) } .with_position((8, 12)) - ), + )), AssignmentOperator::Assign, Statement::ValueExpression(Expression::Value( ValueNode::List(vec![]).with_position((15, 17)) @@ -888,7 +888,10 @@ mod tests { Statement::Assignment( Assignment::new( Identifier::new("foobar").with_position((0, 6)), - Some(TypeConstructor::ListOf(Box::new(Type::Boolean)).with_position((9, 19))), + Some(TypeConstructor::ListOf( + Box::new(TypeConstructor::Type(Type::Boolean.with_position((9, 19)))) + .with_position((0, 0)) + )), AssignmentOperator::Assign, Statement::ValueExpression(Expression::Value( ValueNode::List(vec![Expression::Value( @@ -909,14 +912,16 @@ mod tests { Statement::Assignment( Assignment::new( Identifier::new("foobar").with_position((0, 6)), - Some( - TypeConstructor::Function { + Some(TypeConstructor::Function( + FunctionTypeConstructor { type_parameters: None, value_parameters: vec![], - return_type: Box::new(Type::Any), + return_type: Box::new(TypeConstructor::Type( + Type::Any.with_position((0, 0)) + )), } .with_position((9, 20)) - ), + )), AssignmentOperator::Assign, Statement::ValueExpression(Expression::Identifier( Identifier::new("some_function").with_position((23, 36)) @@ -949,9 +954,9 @@ mod tests { Statement::ValueExpression(Expression::FunctionCall( FunctionCall::new( Expression::Identifier(Identifier::new("foobar").with_position((0, 6))), - Some(vec![ - TypeConstructor::Type(Type::String).with_position((9, 12)) - ]), + Some(vec![TypeConstructor::Type( + Type::String.with_position((9, 12)) + )]), vec![Expression::Value( ValueNode::String("hi".to_string()).with_position((16, 20)) )], @@ -980,9 +985,9 @@ mod tests { type_parameters: None, value_parameters: vec![( Identifier::new("x"), - TypeConstructor::Integer.with_position((7, 10)) + TypeConstructor::Type(Type::Integer.with_position((7, 10))) )], - return_type: TypeConstructor::Integer.with_position((12, 15)), + return_type: TypeConstructor::Type(Type::Integer.with_position((12, 15))), body: Block::new(vec![Statement::ValueExpression(Expression::Identifier( Identifier::new("x").with_position((18, 19)) ))]) @@ -1000,21 +1005,26 @@ mod tests { Statement::ValueExpression(Expression::Value( ValueNode::ParsedFunction { type_parameters: Some(vec![ - TypeConstructor::Argument(Identifier::new("T")).with_position((4, 5)), - TypeConstructor::Argument(Identifier::new("U")).with_position((7, 8)), + Identifier::new("T").with_position((4, 5)), + Identifier::new("U").with_position((7, 8)), ]), value_parameters: vec![ ( Identifier::new("x"), - TypeConstructor::Argument(Identifier::new("T")).with_position((13, 14)) + TypeConstructor::Identifier( + Identifier::new("T").with_position((13, 14)) + ) ), ( Identifier::new("y"), - TypeConstructor::Argument(Identifier::new("U")).with_position((19, 20)) + TypeConstructor::Identifier( + Identifier::new("U").with_position((19, 20)) + ) ) ], - return_type: TypeConstructor::Argument(Identifier::new("T")) - .with_position((22, 23)), + return_type: TypeConstructor::Identifier( + Identifier::new("T").with_position((22, 23)) + ), body: Block::new(vec![Statement::ValueExpression(Expression::Identifier( Identifier::new("x").with_position((26, 27)) ))]) @@ -1299,7 +1309,7 @@ mod tests { Statement::Assignment( Assignment::new( Identifier::new("foobar").with_position((0, 6)), - Some(TypeConstructor::Integer.with_position((8, 11))), + Some(TypeConstructor::Type(Type::Integer.with_position((8, 11)))), AssignmentOperator::Assign, Statement::ValueExpression(Expression::Value( ValueNode::Integer(1).with_position((14, 15))