diff --git a/crates/aiken-lang/src/ast.rs b/crates/aiken-lang/src/ast.rs index fe6723ad..6c807bc9 100644 --- a/crates/aiken-lang/src/ast.rs +++ b/crates/aiken-lang/src/ast.rs @@ -3,7 +3,7 @@ use std::{fmt, ops::Range, sync::Arc}; use crate::{ builtins::{self, bool}, expr::{TypedExpr, UntypedExpr}, - tipo::{fields::FieldMap, PatternConstructor, Type, TypeInfo, ValueConstructor}, + tipo::{PatternConstructor, Type, TypeInfo}, }; pub const ASSERT_VARIABLE: &str = "_try"; @@ -244,17 +244,17 @@ pub struct Use { pub unqualified: Vec, } -pub type TypedModuleConstant = ModuleConstant, String>; -pub type UntypedModuleConstant = ModuleConstant<(), ()>; +pub type TypedModuleConstant = ModuleConstant>; +pub type UntypedModuleConstant = ModuleConstant<()>; #[derive(Debug, Clone, PartialEq)] -pub struct ModuleConstant { +pub struct ModuleConstant { pub doc: Option, pub location: Span, pub public: bool, pub name: String, pub annotation: Option, - pub value: Box>, + pub value: Box, pub tipo: T, } @@ -270,11 +270,11 @@ pub struct Validator { pub params: Vec>, } -pub type TypedDefinition = Definition, TypedExpr, String, String>; -pub type UntypedDefinition = Definition<(), UntypedExpr, (), ()>; +pub type TypedDefinition = Definition, TypedExpr, String>; +pub type UntypedDefinition = Definition<(), UntypedExpr, ()>; #[derive(Debug, Clone, PartialEq)] -pub enum Definition { +pub enum Definition { Fn(Function), TypeAlias(TypeAlias), @@ -283,14 +283,14 @@ pub enum Definition { Use(Use), - ModuleConstant(ModuleConstant), + ModuleConstant(ModuleConstant), Test(Function), Validator(Validator), } -impl Definition { +impl Definition { pub fn location(&self) -> Span { match self { Definition::Fn(Function { location, .. }) @@ -324,91 +324,31 @@ pub struct DefinitionLocation<'module> { pub span: Span, } -pub type TypedConstant = Constant, String>; -pub type UntypedConstant = Constant<(), ()>; - #[derive(Debug, Clone, PartialEq)] -pub enum Constant { - Int { - location: Span, - value: String, - }, +pub enum Constant { + Int { location: Span, value: String }, - String { - location: Span, - value: String, - }, + String { location: Span, value: String }, - Tuple { - location: Span, - elements: Vec, - }, - - List { - location: Span, - elements: Vec, - tipo: T, - }, - - Record { - location: Span, - module: Option, - name: String, - args: Vec>, - tag: RecordTag, - tipo: T, - field_map: Option, - }, - - ByteArray { - location: Span, - bytes: Vec, - }, - - Var { - location: Span, - module: Option, - name: String, - constructor: Option>, - tipo: T, - }, + ByteArray { location: Span, bytes: Vec }, } -impl TypedConstant { +impl Constant { pub fn tipo(&self) -> Arc { match self { Constant::Int { .. } => builtins::int(), Constant::String { .. } => builtins::string(), Constant::ByteArray { .. } => builtins::byte_array(), - Constant::Tuple { elements, .. } => { - builtins::tuple(elements.iter().map(|e| e.tipo()).collect()) - } - Constant::List { tipo, .. } - | Constant::Record { tipo, .. } - | Constant::Var { tipo, .. } => tipo.clone(), } } -} -impl Constant { pub fn location(&self) -> Span { match self { Constant::Int { location, .. } - | Constant::Tuple { location, .. } - | Constant::List { location, .. } | Constant::String { location, .. } - | Constant::Record { location, .. } - | Constant::ByteArray { location, .. } - | Constant::Var { location, .. } => *location, + | Constant::ByteArray { location, .. } => *location, } } - - pub fn is_simple(&self) -> bool { - matches!( - self, - Self::Int { .. } | Self::ByteArray { .. } | Self::String { .. } - ) - } } pub type TypedCallArg = CallArg; @@ -836,15 +776,15 @@ pub type MultiPattern = Vec; pub type TypedMultiPattern = MultiPattern>; -pub type TypedClause = Clause, String>; -pub type UntypedClause = Clause; +pub type TypedClause = Clause>; +pub type UntypedClause = Clause; #[derive(Debug, Clone, PartialEq)] -pub struct Clause { +pub struct Clause { pub location: Span, pub pattern: MultiPattern, pub alternative_patterns: Vec>, - pub guard: Option>, + pub guard: Option>, pub then: Expr, } @@ -861,11 +801,11 @@ impl TypedClause { } } -pub type UntypedClauseGuard = ClauseGuard<(), ()>; -pub type TypedClauseGuard = ClauseGuard, String>; +pub type UntypedClauseGuard = ClauseGuard<()>; +pub type TypedClauseGuard = ClauseGuard>; #[derive(Debug, Clone, PartialEq)] -pub enum ClauseGuard { +pub enum ClauseGuard { Not { location: Span, value: Box, @@ -925,10 +865,10 @@ pub enum ClauseGuard { name: String, }, - Constant(Constant), + Constant(Constant), } -impl ClauseGuard { +impl ClauseGuard { pub fn location(&self) -> Span { match self { ClauseGuard::Constant(constant) => constant.location(), diff --git a/crates/aiken-lang/src/builder.rs b/crates/aiken-lang/src/builder.rs index 876626f3..3d9c0a64 100644 --- a/crates/aiken-lang/src/builder.rs +++ b/crates/aiken-lang/src/builder.rs @@ -397,8 +397,8 @@ pub fn convert_data_to_type(term: Term, field_type: &Arc) -> Term, String>>, -) -> Vec, String>> { + clauses: Vec>>, +) -> Vec>> { let mut sorted_clauses = clauses; // if we have a list sort clauses so we can plug holes for cases not covered by clauses @@ -1066,11 +1066,7 @@ pub fn check_when_pattern_needs( } } -pub fn constants_ir( - literal: &Constant, String>, - ir_stack: &mut Vec, - scope: Vec, -) { +pub fn constants_ir(literal: &Constant, ir_stack: &mut Vec, scope: Vec) { match literal { Constant::Int { value, .. } => { ir_stack.push(Air::Int { @@ -1084,32 +1080,12 @@ pub fn constants_ir( value: value.clone(), }); } - Constant::Tuple { .. } => { - todo!() - } - Constant::List { elements, tipo, .. } => { - ir_stack.push(Air::List { - scope: scope.clone(), - count: elements.len(), - tipo: tipo.clone(), - tail: false, - }); - - for element in elements { - constants_ir(element, ir_stack, scope.clone()); - } - } - Constant::Record { .. } => { - // ir_stack.push(Air::Record { scope, }); - todo!() - } Constant::ByteArray { bytes, .. } => { ir_stack.push(Air::ByteArray { scope, bytes: bytes.clone(), }); } - Constant::Var { .. } => todo!(), }; } @@ -2072,7 +2048,7 @@ pub fn replace_opaque_type(t: &mut Arc, data_types: IndexMap, String>, + clause_guard: &ClauseGuard>, clause_guard_vec: &mut Vec, scope: Vec, ) { diff --git a/crates/aiken-lang/src/expr.rs b/crates/aiken-lang/src/expr.rs index 36cfb1f0..2ce99d3b 100644 --- a/crates/aiken-lang/src/expr.rs +++ b/crates/aiken-lang/src/expr.rs @@ -103,7 +103,7 @@ pub enum TypedExpr { location: Span, tipo: Arc, subjects: Vec, - clauses: Vec, String>>, + clauses: Vec>>, }, If { @@ -390,7 +390,7 @@ pub enum UntypedExpr { When { location: Span, subjects: Vec, - clauses: Vec>, + clauses: Vec>, }, If { diff --git a/crates/aiken-lang/src/format.rs b/crates/aiken-lang/src/format.rs index 9b8cd0d3..ffeeca5d 100644 --- a/crates/aiken-lang/src/format.rs +++ b/crates/aiken-lang/src/format.rs @@ -7,10 +7,10 @@ use crate::{ ast::{ Annotation, Arg, ArgName, AssignmentKind, BinOp, CallArg, ClauseGuard, Constant, DataType, Definition, Function, IfBranch, ModuleConstant, Pattern, RecordConstructor, - RecordConstructorArg, RecordUpdateSpread, Span, TraceKind, TypeAlias, TypedArg, - TypedConstant, UnOp, UnqualifiedImport, UntypedArg, UntypedClause, UntypedClauseGuard, - UntypedDefinition, UntypedFunction, UntypedModule, UntypedPattern, UntypedRecordUpdateArg, - Use, Validator, CAPTURE_VARIABLE, + RecordConstructorArg, RecordUpdateSpread, Span, TraceKind, TypeAlias, TypedArg, UnOp, + UnqualifiedImport, UntypedArg, UntypedClause, UntypedClauseGuard, UntypedDefinition, + UntypedFunction, UntypedModule, UntypedPattern, UntypedRecordUpdateArg, Use, Validator, + CAPTURE_VARIABLE, }, docvec, expr::{UntypedExpr, DEFAULT_ERROR_STR, DEFAULT_TODO_STR}, @@ -324,82 +324,15 @@ impl<'comments> Formatter<'comments> { }) } - fn const_expr<'a, A, B>(&mut self, value: &'a Constant) -> Document<'a> { + fn const_expr<'a>(&mut self, value: &'a Constant) -> Document<'a> { match value { Constant::ByteArray { bytes, .. } => self.bytearray(bytes), Constant::Int { value, .. } => value.to_doc(), - Constant::String { value, .. } => self.string(value), - - Constant::List { elements, .. } => { - let comma: fn() -> Document<'a> = if elements.iter().all(Constant::is_simple) { - || flex_break(",", ", ") - } else { - || break_(",", ", ") - }; - let elements_document = join(elements.iter().map(|e| self.const_expr(e)), comma()); - list(elements_document, elements.len(), None) - } - - Constant::Record { - name, - args, - module: None, - .. - } if args.is_empty() => name.to_doc(), - - Constant::Record { - name, - args, - module: Some(m), - .. - } if args.is_empty() => m.to_doc().append(".").append(name.as_str()), - - Constant::Record { - name, - args, - module: None, - .. - } => name - .to_doc() - .append(wrap_args( - args.iter() - .map(|a| (self.constant_call_arg(a), a.label.is_some())), - )) - .group(), - - Constant::Record { - name, - args, - module: Some(m), - .. - } => m - .to_doc() - .append(".") - .append(name.as_str()) - .append(wrap_args( - args.iter() - .map(|a| (self.constant_call_arg(a), a.label.is_some())), - )) - .group(), - - Constant::Var { - name, module: None, .. - } => name.to_doc(), - - Constant::Var { - name, - module: Some(module), - .. - } => docvec![module, ".", name], - - Constant::Tuple { elements, .. } => { - wrap_args(elements.iter().map(|e| (self.const_expr(e), false))).group() - } } } - pub fn docs_const_expr<'a>(&mut self, name: &'a str, value: &'a TypedConstant) -> Document<'a> { + pub fn docs_const_expr<'a>(&mut self, name: &'a str, value: &'a Constant) -> Document<'a> { let mut printer = tipo::pretty::Printer::new(); name.to_doc() .append(": ") @@ -1631,13 +1564,6 @@ impl<'comments> Formatter<'comments> { } } - fn constant_call_arg<'a, A, B>(&mut self, arg: &'a CallArg>) -> Document<'a> { - match &arg.label { - None => self.const_expr(&arg.value), - Some(s) => s.to_doc().append(": ").append(self.const_expr(&arg.value)), - } - } - fn un_op<'a>(&mut self, value: &'a UntypedExpr, op: &'a UnOp) -> Document<'a> { match op { UnOp::Not => docvec!["!", self.wrap_unary_op(value)], diff --git a/crates/aiken-lang/src/parser.rs b/crates/aiken-lang/src/parser.rs index 2a3fd7bd..fabdec17 100644 --- a/crates/aiken-lang/src/parser.rs +++ b/crates/aiken-lang/src/parser.rs @@ -386,162 +386,32 @@ fn constant_parser() -> impl Parser impl Parser { - recursive(|r| { - let constant_string_parser = - select! {Token::String {value} => value}.map_with_span(|value, span| { - ast::UntypedConstant::String { - location: span, - value, - } - }); - - let constant_int_parser = - select! {Token::Int {value} => value}.map_with_span(|value, span| { - ast::UntypedConstant::Int { - location: span, - value, - } - }); - - let constant_tuple_parser = r - .clone() - .separated_by(just(Token::Comma)) - .at_least(2) - .allow_trailing() - .delimited_by( - choice((just(Token::LeftParen), just(Token::NewLineLeftParen))), - just(Token::RightParen), - ) - .map_with_span(|elements, span| ast::UntypedConstant::Tuple { +fn constant_value_parser() -> impl Parser { + let constant_string_parser = + select! {Token::String {value} => value}.map_with_span(|value, span| { + ast::Constant::String { location: span, - elements, - }); + value, + } + }); - let constant_bytearray_parser = - bytearray_parser().map_with_span(|bytes, span| ast::UntypedConstant::ByteArray { - location: span, - bytes, - }); + let constant_int_parser = + select! {Token::Int {value} => value}.map_with_span(|value, span| ast::Constant::Int { + location: span, + value, + }); - let constant_list_parser = r - .clone() - .separated_by(just(Token::Comma)) - .allow_trailing() - .delimited_by(just(Token::LeftSquare), just(Token::RightSquare)) - .map_with_span(|elements, span| ast::UntypedConstant::List { - location: span, - elements, - tipo: (), - }); + let constant_bytearray_parser = + bytearray_parser().map_with_span(|bytes, span| ast::Constant::ByteArray { + location: span, + bytes, + }); - let constant_record_parser = choice(( - choice(( - select! {Token::Name { name } => name} - .then_ignore(just(Token::Dot)) - .or_not() - .then(select! {Token::UpName { name } => name}) - .then( - select! {Token::Name {name} => name} - .then_ignore(just(Token::Colon)) - .or_not() - .then(r.clone()) - .validate(|(label_opt, value), span, emit| { - let label = if label_opt.is_some() { - label_opt - } else if let ast::UntypedConstant::Var { name, .. } = &value { - Some(name.clone()) - } else { - emit(ParseError::expected_input_found( - value.location(), - None, - Some(error::Pattern::RecordPunning), - )); - - None - }; - - ast::CallArg { - location: span, - value, - label, - } - }) - .separated_by(just(Token::Comma)) - .allow_trailing() - .delimited_by(just(Token::LeftBrace), just(Token::RightBrace)), - ) - .map_with_span( - |((module, name), args), span| ast::UntypedConstant::Record { - location: span, - module, - name, - args, - tag: (), - tipo: (), - field_map: None, - }, - ), - select! {Token::Name { name } => name} - .then_ignore(just(Token::Dot)) - .or_not() - .then(select! {Token::UpName { name } => name}) - .then( - r.clone() - .map_with_span(|value, span| ast::CallArg { - location: span, - value, - label: None, - }) - .separated_by(just(Token::Comma)) - .allow_trailing() - .delimited_by(just(Token::LeftParen), just(Token::RightParen)), - ) - .map_with_span( - |((module, name), args), span| ast::UntypedConstant::Record { - location: span, - module, - name, - args, - tag: (), - tipo: (), - field_map: None, - }, - ), - )), - select! {Token::Name { name } => name} - .then_ignore(just(Token::Dot)) - .then(select! {Token::Name{name} => name}) - .map_with_span(|(module, name), span: Span| ast::UntypedConstant::Var { - location: span.union(span), - module: Some(module), - name, - constructor: None, - tipo: (), - }), - )); - - let constant_var_parser = - select! {Token::Name {name} => name}.map_with_span(|name, span| { - ast::UntypedConstant::Var { - location: span, - module: None, - name, - constructor: None, - tipo: (), - } - }); - - choice(( - constant_string_parser, - constant_int_parser, - constant_bytearray_parser, - constant_tuple_parser, - constant_list_parser, - constant_record_parser, - constant_var_parser, - )) - }) + choice(( + constant_string_parser, + constant_int_parser, + constant_bytearray_parser, + )) } pub fn bytearray_parser() -> impl Parser, Error = ParseError> { @@ -1407,8 +1277,7 @@ pub fn expr_parser( }) } -pub fn when_clause_guard_parser() -> impl Parser, Error = ParseError> -{ +pub fn when_clause_guard_parser() -> impl Parser, Error = ParseError> { recursive(|r| { let var_parser = select! { Token::Name { name } => name, diff --git a/crates/aiken-lang/src/tipo.rs b/crates/aiken-lang/src/tipo.rs index fa8f31e3..693a193b 100644 --- a/crates/aiken-lang/src/tipo.rs +++ b/crates/aiken-lang/src/tipo.rs @@ -3,7 +3,7 @@ use std::{cell::RefCell, collections::HashMap, ops::Deref, sync::Arc}; use uplc::{ast::Type as UplcType, builtins::DefaultFunction}; use crate::{ - ast::{Constant, DefinitionLocation, ModuleKind, Span, TypedConstant}, + ast::{Constant, DefinitionLocation, ModuleKind, Span}, tipo::fields::FieldMap, }; @@ -584,7 +584,7 @@ pub enum ValueConstructorVariant { ModuleConstant { location: Span, module: String, - literal: Constant, String>, + literal: Constant, }, /// A function belonging to the module @@ -744,7 +744,7 @@ pub enum ModuleValueConstructor { }, Constant { - literal: TypedConstant, + literal: Constant, location: Span, }, } diff --git a/crates/aiken-lang/src/tipo/expr.rs b/crates/aiken-lang/src/tipo/expr.rs index 7eabeb90..8bb97739 100644 --- a/crates/aiken-lang/src/tipo/expr.rs +++ b/crates/aiken-lang/src/tipo/expr.rs @@ -6,9 +6,9 @@ use crate::{ ast::{ Annotation, Arg, ArgName, AssignmentKind, BinOp, CallArg, Clause, ClauseGuard, Constant, IfBranch, RecordUpdateSpread, Span, TraceKind, Tracing, TypedArg, TypedCallArg, - TypedClause, TypedClauseGuard, TypedConstant, TypedIfBranch, TypedMultiPattern, - TypedRecordUpdateArg, UnOp, UntypedArg, UntypedClause, UntypedClauseGuard, UntypedConstant, - UntypedIfBranch, UntypedMultiPattern, UntypedPattern, UntypedRecordUpdateArg, + TypedClause, TypedClauseGuard, TypedIfBranch, TypedMultiPattern, TypedRecordUpdateArg, + UnOp, UntypedArg, UntypedClause, UntypedClauseGuard, UntypedIfBranch, UntypedMultiPattern, + UntypedPattern, UntypedRecordUpdateArg, }, builtins::{bool, byte_array, function, int, list, string, tuple}, expr::{TypedExpr, UntypedExpr}, @@ -22,8 +22,7 @@ use super::{ hydrator::Hydrator, pattern::PatternTyper, pipe::PipeTyper, - ModuleValueConstructor, PatternConstructor, RecordAccessor, Type, ValueConstructor, - ValueConstructorVariant, + PatternConstructor, RecordAccessor, Type, ValueConstructor, ValueConstructorVariant, }; #[derive(Debug)] @@ -48,7 +47,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { &mut self, subjects_count: usize, subjects: &[Arc], - typed_clauses: &[Clause, String>], + typed_clauses: &[Clause>], location: Span, ) -> Result<(), Vec> { // Because exhaustiveness checking in presence of multiple subjects is similar @@ -1338,29 +1337,13 @@ impl<'a, 'b> ExprTyper<'a, 'b> { Ok((typed_pattern, typed_alternatives)) } - fn infer_const_tuple( - &mut self, - untyped_elements: Vec, - location: Span, - ) -> Result { - let mut elements = Vec::with_capacity(untyped_elements.len()); - - for element in untyped_elements { - let element = self.infer_const(&None, element)?; - - elements.push(element); - } - - Ok(Constant::Tuple { elements, location }) - } - // TODO: extract the type annotation checking into a infer_module_const // function that uses this function internally pub fn infer_const( &mut self, annotation: &Option, - value: UntypedConstant, - ) -> Result { + value: Constant, + ) -> Result { let inferred = match value { Constant::Int { location, value, .. @@ -1370,216 +1353,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { location, value, .. } => Ok(Constant::String { location, value }), - Constant::Tuple { - elements, location, .. - } => self.infer_const_tuple(elements, location), - - Constant::List { - elements, location, .. - } => self.infer_const_list(elements, location), - Constant::ByteArray { location, bytes } => Ok(Constant::ByteArray { location, bytes }), - - Constant::Record { - module, - location, - name, - args, - // field_map, is always None here because untyped not yet unified - .. - } if args.is_empty() => { - // Register the module as having been used if it was imported - if let Some(ref module) = &module { - self.environment.unused_modules.remove(module); - } - - // Type check the record constructor - let constructor = self.infer_value_constructor(&module, &name, &location)?; - - let (tag, field_map) = match &constructor.variant { - ValueConstructorVariant::Record { - name, field_map, .. - } => (name.clone(), field_map.clone()), - - ValueConstructorVariant::ModuleFn { .. } - | ValueConstructorVariant::LocalVariable { .. } => { - return Err(Error::NonLocalClauseGuardVariable { location, name }) - } - - // TODO: remove this clone. Could use an rc instead - ValueConstructorVariant::ModuleConstant { literal, .. } => { - return Ok(literal.clone()) - } - }; - - Ok(Constant::Record { - module, - location, - name, - args: vec![], - tipo: constructor.tipo, - tag, - field_map, - }) - } - - Constant::Record { - module, - location, - name, - mut args, - // field_map, is always None here because untyped not yet unified - .. - } => { - // Register the module as having been used if it was imported - if let Some(ref module) = &module { - self.environment.unused_modules.remove(module); - } - - let constructor = self.infer_value_constructor(&module, &name, &location)?; - - let (tag, field_map) = match &constructor.variant { - ValueConstructorVariant::Record { - name, field_map, .. - } => (name.clone(), field_map.clone()), - - ValueConstructorVariant::ModuleFn { .. } - | ValueConstructorVariant::LocalVariable { .. } => { - return Err(Error::NonLocalClauseGuardVariable { location, name }) - } - - // TODO: remove this clone. Could be an rc instead - ValueConstructorVariant::ModuleConstant { literal, .. } => { - return Ok(literal.clone()) - } - }; - - // Pretty much all the other infer functions operate on UntypedExpr - // or TypedExpr rather than ClauseGuard. To make things easier we - // build the TypedExpr equivalent of the constructor and use that - // TODO: resvisit this. It is rather awkward at present how we - // have to convert to this other data structure. - let fun = match &module { - Some(module_name) => { - let tipo = Arc::clone(&constructor.tipo); - - let module_name = self - .environment - .imported_modules - .get(module_name) - .expect("Failed to find previously located module import") - .1 - .name - .clone(); - - let module_value_constructor = ModuleValueConstructor::Record { - name: name.clone(), - field_map: field_map.clone(), - arity: args.len(), - tipo: Arc::clone(&tipo), - location: constructor.variant.location(), - }; - - TypedExpr::ModuleSelect { - label: name.clone(), - module_alias: module_name.clone(), - module_name, - tipo, - constructor: module_value_constructor, - location, - } - } - - None => TypedExpr::Var { - constructor, - location, - name: name.clone(), - }, - }; - - // This is basically the same code as do_infer_call_with_known_fun() - // except the args are typed with infer_clause_guard() here. - // This duplication is a bit awkward but it works! - // Potentially this could be improved later - match self.get_field_map(&fun, location)? { - // The fun has a field map so labelled arguments may be present and need to be reordered. - Some(field_map) => field_map.reorder(&mut args, location)?, - - // The fun has no field map and so we error if arguments have been labelled - None => assert_no_labeled_arguments(&args) - .map(|(location, label)| { - Err(Error::UnexpectedLabeledArg { location, label }) - }) - .unwrap_or(Ok(()))?, - } - - let (mut args_types, return_type) = self.environment.match_fun_type( - fun.tipo(), - args.len(), - fun.location(), - location, - )?; - - let mut typed_args = Vec::new(); - - for (tipo, arg) in args_types.iter_mut().zip(args) { - let CallArg { - label, - value, - location, - } = arg; - - let value = self.infer_const(&None, value)?; - - self.unify(tipo.clone(), value.tipo(), value.location(), tipo.is_data())?; - - typed_args.push(CallArg { - label, - value, - location, - }); - } - - Ok(Constant::Record { - module, - location, - name, - args: typed_args, - tipo: return_type, - tag, - field_map, - }) - } - Constant::Var { - location, - module, - name, - .. - } => { - // Register the module as having been used if it was imported - if let Some(ref module) = &module { - self.environment.unused_modules.remove(module); - } - - // Infer the type of this constant - let constructor = self.infer_value_constructor(&module, &name, &location)?; - - match constructor.variant { - ValueConstructorVariant::ModuleConstant { .. } - | ValueConstructorVariant::ModuleFn { .. } => Ok(Constant::Var { - location, - module, - name, - tipo: Arc::clone(&constructor.tipo), - constructor: Some(Box::from(constructor)), - }), - // constructor.variant cannot be a LocalVariable because module constants can - // only be defined at module scope. It also cannot be a Record because then - // this constant would have been parsed as a Constant::Record. Therefore this - // code is unreachable. - _ => unreachable!(), - } - } }?; // Check type annotation is accurate. @@ -1597,30 +1371,6 @@ impl<'a, 'b> ExprTyper<'a, 'b> { Ok(inferred) } - fn infer_const_list( - &mut self, - untyped_elements: Vec, - location: Span, - ) -> Result { - let tipo = self.new_unbound_var(); - - let mut elements = Vec::with_capacity(untyped_elements.len()); - - for element in untyped_elements { - let element = self.infer_const(&None, element)?; - - self.unify(tipo.clone(), element.tipo(), element.location(), false)?; - - elements.push(element); - } - - Ok(Constant::List { - elements, - location, - tipo: list(tipo), - }) - } - fn infer_if( &mut self, branches: Vec1, diff --git a/crates/aiken-lang/src/uplc.rs b/crates/aiken-lang/src/uplc.rs index 8e3004eb..0e451146 100644 --- a/crates/aiken-lang/src/uplc.rs +++ b/crates/aiken-lang/src/uplc.rs @@ -689,7 +689,7 @@ impl<'a> CodeGenerator<'a> { &mut self, ir_stack: &mut Vec, clause_properties: &mut ClauseProperties, - clauses: &[Clause, String>], + clauses: &[Clause>], subject_type: &Arc, scope: Vec, ) { diff --git a/examples/acceptance_tests/060/aiken.lock b/examples/acceptance_tests/060/aiken.lock new file mode 100644 index 00000000..3a78b1e7 --- /dev/null +++ b/examples/acceptance_tests/060/aiken.lock @@ -0,0 +1,5 @@ +# This file was generated by Aiken +# You typically do not need to edit this file + +requirements = [] +packages = [] diff --git a/examples/acceptance_tests/060/aiken.toml b/examples/acceptance_tests/060/aiken.toml new file mode 100644 index 00000000..615fb5ac --- /dev/null +++ b/examples/acceptance_tests/060/aiken.toml @@ -0,0 +1,2 @@ +name = "aiken-lang/acceptance_test_060" +version = "0.0.0" diff --git a/examples/acceptance_tests/060/lib/tests.ak b/examples/acceptance_tests/060/lib/tests.ak new file mode 100644 index 00000000..1a7c8776 --- /dev/null +++ b/examples/acceptance_tests/060/lib/tests.ak @@ -0,0 +1,17 @@ +const int_constant = 42 + +test int() { + int_constant == 42 +} + +const bytearray_constant = #"abcd" + +test bytearray() { + bytearray_constant == #"abcd" +} + +const string_constant = "FOO" + +test string() { + string_constant == "FOO" +}