diff --git a/crates/aiken-lang/src/ast.rs b/crates/aiken-lang/src/ast.rs index 3ac288ff..95310c6c 100644 --- a/crates/aiken-lang/src/ast.rs +++ b/crates/aiken-lang/src/ast.rs @@ -472,6 +472,154 @@ impl TypedValidator { ] } + // Define a validator wrapper extracting and matching on script purpose for + // users. + pub fn into_script_context_handler(&self) -> TypedExpr { + let var_context = "__context__"; + let var_transaction = "__transaction__"; + let var_redeemer = "__redeemer__"; + let var_purpose = "__purpose__"; + let var_purpose_arg = "__purpose_arg__"; + let var_datum = "__datum__"; + + TypedExpr::sequence(&[ + TypedExpr::let_( + TypedExpr::local_var(var_context, Type::script_context()), + TypedPattern::Constructor { + is_record: false, + location: Span::empty(), + name: well_known::SCRIPT_CONTEXT_CONSTRUCTORS[0].to_string(), + arguments: vec![ + CallArg::var(var_transaction), + CallArg::var(var_redeemer), + CallArg::var(var_purpose), + ], + module: None, + constructor: PatternConstructor::Record { + name: well_known::SCRIPT_CONTEXT_CONSTRUCTORS[0].to_string(), + field_map: None, + }, + spread_location: None, + tipo: Type::function( + vec![Type::data(), Type::data(), Type::script_purpose()], + Type::data(), + ), + }, + Type::script_context(), + ), + TypedExpr::When { + location: Span::empty(), + tipo: Type::bool(), + subject: TypedExpr::local_var(var_purpose, Type::script_purpose()).into(), + clauses: self + .handlers + .iter() + .map(|handler| { + let datum = if handler.name.as_str() == "spend" { + handler.arguments.first() + } else { + None + }; + + let redeemer = handler + .arguments + .get(if datum.is_some() { 1 } else { 0 }) + .unwrap(); + + let purpose_arg = handler.arguments.iter().nth_back(1).unwrap(); + + let transaction = handler.arguments.last().unwrap(); + + let pattern = match handler.name.as_str() { + "spend" => TypedPattern::spend_purpose(var_purpose_arg, var_datum), + "mint" => TypedPattern::mint_purpose(var_purpose_arg), + "withdraw" => TypedPattern::withdraw_purpose(var_purpose_arg), + "publish" => TypedPattern::publish_purpose(var_purpose_arg), + "propose" => TypedPattern::propose_purpose(var_purpose_arg), + "vote" => TypedPattern::vote_purpose(var_purpose_arg), + purpose => { + unreachable!("unexpected/unknown purpose: {:?}", purpose) + } + }; + + let mut then = vec![]; + + // expect redeemer: tipo = __redeemer__ + then.push(TypedExpr::flexible_expect( + TypedExpr::local_var(var_redeemer, Type::data()), + TypedPattern::var(redeemer.get_variable_name().unwrap_or("_")), + redeemer.tipo.clone(), + )); + + // Cast the datum, if any + if let Some(datum) = datum { + // expect datum: tipo = __datum__ + then.push(TypedExpr::flexible_expect( + TypedExpr::local_var(var_datum, Type::option(Type::data())), + TypedPattern::var(datum.get_variable_name().unwrap_or("_")), + datum.tipo.clone(), + )) + } + + // let purpose_arg = __purpose_arg__ + if let Some(arg_name) = purpose_arg.get_variable_name() { + then.push(TypedExpr::let_( + TypedExpr::local_var(var_purpose_arg, Type::data()), + TypedPattern::var(arg_name), + purpose_arg.tipo.clone(), + )); + } + + // let last_arg_name = __transaction__ + if let Some(arg_name) = transaction.get_variable_name() { + then.push(TypedExpr::let_( + TypedExpr::local_var(var_transaction, Type::data()), + TypedPattern::var(arg_name), + Type::data(), + )); + } + + then.push(handler.body.clone()); + + TypedClause { + location: Span::empty(), + pattern, + then: TypedExpr::Sequence { + location: Span::empty(), + expressions: then, + }, + } + }) + // FIXME: This is only needed if there's non-exhaustive patterns + // above. + .chain(std::iter::once(&self.fallback).map(|fallback| { + let arg = fallback.arguments.first().unwrap(); + + let then = &[ + TypedExpr::let_( + TypedExpr::local_var(var_context, arg.tipo.clone()), + arg.get_variable_name().map(TypedPattern::var).unwrap_or( + TypedPattern::Discard { + name: var_context.to_string(), + location: Span::empty(), + }, + ), + arg.tipo.clone(), + ), + fallback.body.clone(), + ]; + + TypedClause { + location: Span::empty(), + pattern: TypedPattern::var(var_context), + then: TypedExpr::sequence(then), + } + })) + .collect(), + }, + ]) + } + pub fn find_node(&self, byte_index: usize) -> Option> { self.params .iter() @@ -697,6 +845,19 @@ impl TypedCallArg { } } +impl CallArg { + pub fn var(name: &str) -> Self { + CallArg { + label: None, + location: Span::empty(), + value: TypedPattern::Var { + location: Span::empty(), + name: name.to_string(), + }, + } + } +} + #[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] pub struct RecordConstructor { pub location: Span, @@ -823,6 +984,21 @@ pub struct TypedArg { } impl TypedArg { + pub fn new(name: &str, tipo: Rc) -> Self { + TypedArg { + arg_name: ArgName::Named { + name: name.to_string(), + label: name.to_string(), + location: Span::empty(), + }, + location: Span::empty(), + annotation: None, + doc: None, + is_validator_param: false, + tipo: tipo.clone(), + } + } + pub fn put_doc(&mut self, new_doc: String) { self.doc = Some(new_doc); } @@ -1217,6 +1393,88 @@ impl BinOp { pub type UntypedPattern = Pattern<(), ()>; pub type TypedPattern = Pattern>; +impl TypedPattern { + pub fn var(name: &str) -> Self { + TypedPattern::Var { + name: name.to_string(), + location: Span::empty(), + } + } + + pub fn constructor(name: &str, arguments: &[CallArg], tipo: Rc) -> Self { + TypedPattern::Constructor { + is_record: false, + location: Span::empty(), + name: name.to_string(), + arguments: arguments.to_vec(), + module: None, + constructor: PatternConstructor::Record { + name: name.to_string(), + field_map: None, + }, + spread_location: None, + tipo: tipo.clone(), + } + } + + pub fn mint_purpose(var_purpose_arg: &str) -> Self { + TypedPattern::constructor( + well_known::SCRIPT_PURPOSE_MINT, + &[CallArg::var(var_purpose_arg)], + Type::function(vec![Type::byte_array()], Type::script_purpose()), + ) + } + + pub fn spend_purpose(var_purpose_arg: &str, var_datum: &str) -> Self { + TypedPattern::constructor( + well_known::SCRIPT_PURPOSE_SPEND, + &[CallArg::var(var_purpose_arg), CallArg::var(var_datum)], + Type::function( + vec![Type::data(), Type::option(Type::data())], + Type::script_purpose(), + ), + ) + } + + pub fn withdraw_purpose(var_purpose_arg: &str) -> Self { + TypedPattern::constructor( + well_known::SCRIPT_PURPOSE_WITHDRAW, + &[CallArg::var(var_purpose_arg)], + Type::function(vec![Type::data()], Type::script_purpose()), + ) + } + + pub fn publish_purpose(var_purpose_arg: &str) -> Self { + TypedPattern::constructor( + well_known::SCRIPT_PURPOSE_PUBLISH, + &[ + CallArg::var("__discarded_purpose_ix__"), + CallArg::var(var_purpose_arg), + ], + Type::function(vec![Type::int(), Type::data()], Type::script_purpose()), + ) + } + + pub fn vote_purpose(var_purpose_arg: &str) -> Self { + TypedPattern::constructor( + well_known::SCRIPT_PURPOSE_VOTE, + &[CallArg::var(var_purpose_arg)], + Type::function(vec![Type::data()], Type::script_purpose()), + ) + } + + pub fn propose_purpose(var_purpose_arg: &str) -> Self { + TypedPattern::constructor( + well_known::SCRIPT_PURPOSE_PROPOSE, + &[ + CallArg::var("__discarded_purpose_ix__"), + CallArg::var(var_purpose_arg), + ], + Type::function(vec![Type::int(), Type::data()], Type::script_purpose()), + ) + } +} + #[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] pub enum Pattern { Int { diff --git a/crates/aiken-lang/src/expr.rs b/crates/aiken-lang/src/expr.rs index dc30e48a..07659b36 100644 --- a/crates/aiken-lang/src/expr.rs +++ b/crates/aiken-lang/src/expr.rs @@ -1,16 +1,17 @@ pub(crate) use crate::{ ast::{ - self, Annotation, ArgBy, ArgName, AssignmentPattern, BinOp, Bls12_381Point, + self, Annotation, ArgBy, ArgName, AssignmentKind, AssignmentPattern, BinOp, Bls12_381Point, ByteArrayFormatPreference, CallArg, Curve, DataType, DataTypeKey, DefinitionLocation, Located, LogicalOpChainKind, ParsedCallArg, Pattern, RecordConstructorArg, RecordUpdateSpread, Span, TraceKind, TypedArg, TypedAssignmentKind, TypedClause, - TypedDataType, TypedIfBranch, TypedRecordUpdateArg, UnOp, UntypedArg, + TypedDataType, TypedIfBranch, TypedPattern, TypedRecordUpdateArg, UnOp, UntypedArg, UntypedAssignmentKind, UntypedClause, UntypedIfBranch, UntypedRecordUpdateArg, }, parser::token::Base, tipo::{ check_replaceable_opaque_type, convert_opaque_type, lookup_data_type_by_tipo, ModuleValueConstructor, PatternConstructor, Type, TypeVar, ValueConstructor, + ValueConstructorVariant, }, }; use indexmap::IndexMap; @@ -199,6 +200,52 @@ impl From> for Vec1 { } impl TypedExpr { + pub fn sequence(exprs: &[TypedExpr]) -> Self { + TypedExpr::Sequence { + location: Span::empty(), + expressions: exprs.to_vec(), + } + } + + pub fn let_(value: Self, pattern: TypedPattern, tipo: Rc) -> Self { + TypedExpr::Assignment { + location: Span::empty(), + tipo: tipo.clone(), + value: value.into(), + pattern, + kind: AssignmentKind::let_(), + } + } + + // Create an expect assignment, unless the target type is `Data`; then fallback to a let. + pub fn flexible_expect(value: Self, pattern: TypedPattern, tipo: Rc) -> Self { + TypedExpr::Assignment { + location: Span::empty(), + tipo: tipo.clone(), + value: value.into(), + pattern, + kind: if tipo.is_data() { + AssignmentKind::let_() + } else { + AssignmentKind::expect() + }, + } + } + + pub fn local_var(name: &str, tipo: Rc) -> Self { + TypedExpr::Var { + location: Span::empty(), + constructor: ValueConstructor { + public: true, + variant: ValueConstructorVariant::LocalVariable { + location: Span::empty(), + }, + tipo: tipo.clone(), + }, + name: name.to_string(), + } + } + pub fn tipo(&self) -> Rc { match self { Self::Var { constructor, .. } => constructor.tipo.clone(), diff --git a/crates/aiken-lang/src/gen_uplc.rs b/crates/aiken-lang/src/gen_uplc.rs index 0b762851..e0c5c2e9 100644 --- a/crates/aiken-lang/src/gen_uplc.rs +++ b/crates/aiken-lang/src/gen_uplc.rs @@ -13,9 +13,9 @@ use self::{ }; use crate::{ ast::{ - well_known, ArgName, AssignmentKind, BinOp, Bls12_381Point, CallArg, Curve, DataTypeKey, - FunctionAccessKey, OnTestFailure, Pattern, Span, TraceLevel, Tracing, TypedArg, - TypedClause, TypedDataType, TypedFunction, TypedPattern, TypedValidator, UnOp, + AssignmentKind, BinOp, Bls12_381Point, Curve, DataTypeKey, FunctionAccessKey, Pattern, + Span, TraceLevel, Tracing, TypedArg, TypedClause, TypedDataType, TypedFunction, + TypedPattern, TypedValidator, UnOp, }, builtins::PRELUDE, expr::TypedExpr, @@ -114,501 +114,11 @@ impl<'a> CodeGenerator<'a> { } } - pub fn generate( - &mut self, - TypedValidator { - handlers, - fallback, - params, - .. - }: &TypedValidator, - module_name: &str, - ) -> Program { - let fun = TypedFunction { - arguments: vec![TypedArg { - arg_name: ArgName::Named { - name: "__context__".to_string(), - label: "__context__".to_string(), - location: Span::empty(), - }, - location: Span::empty(), - annotation: None, - doc: None, - is_validator_param: false, - tipo: Type::data(), - }], - body: TypedExpr::Sequence { - location: Span::empty(), - expressions: vec![ - TypedExpr::Assignment { - location: Span::empty(), - tipo: Type::script_context(), - value: TypedExpr::Var { - location: Span::empty(), - constructor: ValueConstructor { - public: true, - variant: ValueConstructorVariant::LocalVariable { - location: Span::empty(), - }, - tipo: Type::script_context(), - }, - name: "__context__".to_string(), - } - .into(), - pattern: TypedPattern::Constructor { - is_record: false, - location: Span::empty(), - name: "ScriptContext".to_string(), - arguments: vec![ - CallArg { - label: None, - location: Span::empty(), - value: TypedPattern::Var { - location: Span::empty(), - name: "__transaction__".to_string(), - }, - }, - CallArg { - label: None, - location: Span::empty(), - value: TypedPattern::Var { - location: Span::empty(), - name: "__redeemer__".to_string(), - }, - }, - CallArg { - label: None, - location: Span::empty(), - value: TypedPattern::Var { - location: Span::empty(), - name: "__purpose__".to_string(), - }, - }, - ], - module: None, - constructor: PatternConstructor::Record { - name: "ScriptContext".to_string(), - field_map: None, - }, - spread_location: None, - tipo: Type::function( - vec![Type::data(), Type::data(), Type::script_purpose()], - Type::data(), - ), - }, - kind: AssignmentKind::let_(), - }, - TypedExpr::When { - location: Span::empty(), - tipo: Type::bool(), - subject: TypedExpr::Var { - location: Span::empty(), - constructor: ValueConstructor { - public: true, - variant: ValueConstructorVariant::LocalVariable { - location: Span::empty(), - }, - tipo: Type::script_purpose(), - }, - name: "__purpose__".to_string(), - } - .into(), - clauses: handlers - .iter() - .map(|handler| { - let datum = if handler.name.as_str() == "spend" { - handler.arguments.first() - } else { - None - }; - - let redeemer = handler - .arguments - .get(if datum.is_some() { 1 } else { 0 }) - .unwrap(); - - let purpose_arg = handler.arguments.iter().nth_back(1).unwrap(); - - let transaction = handler.arguments.last().unwrap(); - - // handler - // - // spend(datum: Option, redeemer, oref, anything) => Spend(datum, redeemer, oref, transaction) - // spend(datum: Datum) => Spend(datum, redeemer, oref, transaction) - // spend(redeemer) => Spend(__datum__, redeemer, oref, transaction) - - let pattern = match handler.name.as_str() { - "spend" => TypedPattern::Constructor { - is_record: false, - location: Span::empty(), - name: well_known::SCRIPT_PURPOSE_SPEND.to_string(), - arguments: vec![ - CallArg { - label: None, - location: Span::empty(), - value: TypedPattern::Var { - name: "__purpose_arg__".to_string(), - location: Span::empty(), - }, - }, - CallArg { - label: None, - location: Span::empty(), - value: TypedPattern::Var { - name: "__datum__".to_string(), - location: Span::empty(), - }, - }, - ], - module: None, - constructor: PatternConstructor::Record { - name: well_known::SCRIPT_PURPOSE_SPEND.to_string(), - field_map: None, - }, - spread_location: None, - tipo: Type::function( - vec![Type::data(), Type::option(Type::data())], - Type::script_purpose(), - ), - }, - - "mint" => TypedPattern::Constructor { - is_record: false, - location: Span::empty(), - name: well_known::SCRIPT_PURPOSE_MINT.to_string(), - arguments: vec![CallArg { - label: None, - location: Span::empty(), - value: TypedPattern::Var { - name: "__purpose_arg__".to_string(), - location: Span::empty(), - }, - }], - module: None, - constructor: PatternConstructor::Record { - name: well_known::SCRIPT_PURPOSE_MINT.to_string(), - field_map: None, - }, - spread_location: None, - tipo: Type::function( - vec![Type::byte_array()], - Type::script_purpose(), - ), - }, - - "withdraw" => TypedPattern::Constructor { - is_record: false, - location: Span::empty(), - name: well_known::SCRIPT_PURPOSE_WITHDRAW.to_string(), - arguments: vec![CallArg { - label: None, - location: Span::empty(), - value: TypedPattern::Var { - name: "__purpose_arg__".to_string(), - location: Span::empty(), - }, - }], - module: None, - constructor: PatternConstructor::Record { - name: well_known::SCRIPT_PURPOSE_WITHDRAW.to_string(), - field_map: None, - }, - spread_location: None, - tipo: Type::function( - vec![Type::data()], - Type::script_purpose(), - ), - }, - - "publish" => TypedPattern::Constructor { - is_record: false, - location: Span::empty(), - name: well_known::SCRIPT_PURPOSE_PUBLISH.to_string(), - arguments: vec![ - CallArg { - label: None, - location: Span::empty(), - value: TypedPattern::Var { - name: "__purpose_arg_ix__".to_string(), - location: Span::empty(), - }, - }, - CallArg { - label: None, - location: Span::empty(), - value: TypedPattern::Var { - name: "__purpose_arg__".to_string(), - location: Span::empty(), - }, - }, - ], - module: None, - constructor: PatternConstructor::Record { - name: well_known::SCRIPT_PURPOSE_PUBLISH.to_string(), - field_map: None, - }, - spread_location: None, - tipo: Type::function( - vec![Type::int(), Type::data()], - Type::script_purpose(), - ), - }, - - "vote" => TypedPattern::Constructor { - is_record: false, - location: Span::empty(), - name: well_known::SCRIPT_PURPOSE_VOTE.to_string(), - arguments: vec![CallArg { - label: None, - location: Span::empty(), - value: TypedPattern::Var { - name: "__purpose_arg__".to_string(), - location: Span::empty(), - }, - }], - module: None, - constructor: PatternConstructor::Record { - name: well_known::SCRIPT_PURPOSE_VOTE.to_string(), - field_map: None, - }, - spread_location: None, - tipo: Type::function( - vec![Type::data()], - Type::script_purpose(), - ), - }, - - "propose" => TypedPattern::Constructor { - is_record: false, - location: Span::empty(), - name: well_known::SCRIPT_PURPOSE_PROPOSE.to_string(), - arguments: vec![ - CallArg { - label: None, - location: Span::empty(), - value: TypedPattern::Var { - name: "__purpose_arg_ix__".to_string(), - location: Span::empty(), - }, - }, - CallArg { - label: None, - location: Span::empty(), - value: TypedPattern::Var { - name: "__purpose_arg__".to_string(), - location: Span::empty(), - }, - }, - ], - module: None, - constructor: PatternConstructor::Record { - name: well_known::SCRIPT_PURPOSE_PROPOSE.to_string(), - field_map: None, - }, - spread_location: None, - tipo: Type::function( - vec![Type::int(), Type::data()], - Type::script_purpose(), - ), - }, - - purpose => { - unreachable!("unexpected/unknown purpose: {:?}", purpose) - } - }; - - let mut then = vec![]; - - // expect redeemer: tipo = __redeemer__ - then.push(TypedExpr::Assignment { - location: Span::empty(), - tipo: redeemer.tipo.clone(), - value: TypedExpr::Var { - location: Span::empty(), - constructor: ValueConstructor { - public: true, - variant: ValueConstructorVariant::LocalVariable { - location: Span::empty(), - }, - tipo: Type::data(), - }, - name: "__redeemer__".to_string(), - } - .into(), - pattern: TypedPattern::Var { - location: Span::empty(), - name: redeemer - .get_variable_name() - .unwrap_or("_") - .to_string(), - }, - kind: if redeemer.tipo.is_data() { - AssignmentKind::let_() - } else { - AssignmentKind::expect() - }, - }); - - // Cast the datum, if any - if let Some(datum) = datum { - // expect datum: tipo = __datum__ - then.push(TypedExpr::Assignment { - location: Span::empty(), - tipo: datum.tipo.clone(), - value: TypedExpr::Var { - location: Span::empty(), - constructor: ValueConstructor { - public: true, - variant: ValueConstructorVariant::LocalVariable { - location: Span::empty(), - }, - tipo: Type::option(Type::data()), - }, - name: "__datum__".to_string(), - } - .into(), - pattern: TypedPattern::Var { - location: Span::empty(), - name: datum - .get_variable_name() - .unwrap_or("_") - .to_string(), - }, - kind: if redeemer.tipo.is_data() { - AssignmentKind::let_() - } else { - AssignmentKind::expect() - }, - }); - } - - // let purpose_arg = __purpose_arg__ - if let Some(arg_name) = purpose_arg.get_variable_name() { - then.push(TypedExpr::Assignment { - location: Span::empty(), - tipo: purpose_arg.tipo.clone(), - value: TypedExpr::Var { - location: Span::empty(), - constructor: ValueConstructor { - public: true, - variant: ValueConstructorVariant::LocalVariable { - location: Span::empty(), - }, - tipo: Type::data(), - }, - name: "__purpose_arg__".to_string(), - } - .into(), - pattern: TypedPattern::Var { - location: Span::empty(), - name: arg_name.to_string(), - }, - kind: AssignmentKind::let_(), - }); - } - - // let last_arg_name = __transaction__ - if let Some(arg_name) = transaction.get_variable_name() { - then.push(TypedExpr::Assignment { - location: Span::empty(), - tipo: transaction.tipo.clone(), - value: TypedExpr::Var { - location: Span::empty(), - constructor: ValueConstructor { - public: true, - variant: ValueConstructorVariant::LocalVariable { - location: Span::empty(), - }, - tipo: Type::data(), - }, - name: "__transaction__".to_string(), - } - .into(), - pattern: TypedPattern::Var { - location: Span::empty(), - name: arg_name.to_string(), - }, - kind: AssignmentKind::let_(), - }); - } - - then.push(handler.body.clone()); - - TypedClause { - location: Span::empty(), - pattern, - then: TypedExpr::Sequence { - location: Span::empty(), - expressions: then, - }, - } - }) - // FIXME: This is only needed if there's non-exhaustive patterns - // above. - .chain(std::iter::once(fallback).map(|fallback| { - let pattern = TypedPattern::Var { - location: Span::empty(), - name: "__context__".to_string(), - }; - - let arg = fallback.arguments.first().unwrap(); - - let then = vec![ - TypedExpr::Assignment { - location: Span::empty(), - tipo: arg.tipo.clone(), - value: TypedExpr::Var { - location: Span::empty(), - constructor: ValueConstructor { - public: true, - variant: ValueConstructorVariant::LocalVariable { - location: Span::empty(), - }, - tipo: arg.tipo.clone(), - }, - name: "__context__".to_string(), - } - .into(), - pattern: arg - .get_variable_name() - .map(|name| TypedPattern::Var { - location: Span::empty(), - name: name.to_string(), - }) - .unwrap_or(TypedPattern::Discard { - name: "__context__".to_string(), - location: Span::empty(), - }), - kind: AssignmentKind::let_(), - }, - fallback.body.clone(), - ]; - - TypedClause { - location: Span::empty(), - pattern, - then: TypedExpr::Sequence { - location: Span::empty(), - expressions: then, - }, - } - })) - .collect(), - }, - ], - }, - doc: None, - location: Span::empty(), - name: "wrapper_validator".to_string(), - public: true, - return_annotation: None, - return_type: Type::bool(), - end_position: 0, - on_test_failure: OnTestFailure::FailImmediately, - }; - - let air_tree_fun = - wrap_validator_condition(self.build(&fun.body, module_name, &[]), self.tracing); + pub fn generate(&mut self, validator: &TypedValidator, module_name: &str) -> Program { + let air_tree_fun = wrap_validator_condition( + self.build(&validator.into_script_context_handler(), module_name, &[]), + self.tracing, + ); let air_tree_fun = AirTree::anon_func(vec!["__context__".to_string()], air_tree_fun, true); @@ -622,7 +132,7 @@ impl<'a> CodeGenerator<'a> { let term = self.uplc_code_gen(full_vec); - let term = cast_validator_args(term, params); + let term = cast_validator_args(term, &validator.params); self.finalize(term) } diff --git a/crates/aiken-lang/src/tipo.rs b/crates/aiken-lang/src/tipo.rs index 948ac448..574c7167 100644 --- a/crates/aiken-lang/src/tipo.rs +++ b/crates/aiken-lang/src/tipo.rs @@ -1132,7 +1132,7 @@ impl ValueConstructor { tipo: Rc, constructors: &[&str], ) -> Vec { - for constructor in &constructors[..] { + for constructor in constructors { values.insert( constructor.to_string(), ValueConstructor::public( @@ -1143,7 +1143,7 @@ impl ValueConstructor { } constructors - .into_iter() + .iter() .map(|constructor| constructor.to_string()) .collect() } @@ -1152,7 +1152,7 @@ impl ValueConstructor { values: &mut HashMap, constructors: &[(&str, Rc)], ) -> Vec { - for (constructor, tipo) in &constructors[..] { + for (constructor, tipo) in constructors { values.insert( constructor.to_string(), ValueConstructor::public( @@ -1167,7 +1167,7 @@ impl ValueConstructor { } constructors - .into_iter() + .iter() .map(|(constructor, _)| constructor.to_string()) .collect() } diff --git a/examples/acceptance_tests/script_context/v3/aiken.lock b/examples/acceptance_tests/script_context/v3/aiken.lock index 5fc8277e..23d0f60e 100644 --- a/examples/acceptance_tests/script_context/v3/aiken.lock +++ b/examples/acceptance_tests/script_context/v3/aiken.lock @@ -13,4 +13,4 @@ requirements = [] source = "github" [etags] -"aiken-lang/stdlib@v2" = [{ secs_since_epoch = 1723818477, nanos_since_epoch = 540444000 }, "cdbbce58b61deb385e7ea787a2e0fc2dc8fe94db9999e0e6275bc9c70e5796be"] +"aiken-lang/stdlib@v2" = [{ secs_since_epoch = 1723824703, nanos_since_epoch = 979555000 }, "cdbbce58b61deb385e7ea787a2e0fc2dc8fe94db9999e0e6275bc9c70e5796be"]