From 2018a18d15678f51537d0a4b12f3c485f02a5386 Mon Sep 17 00:00:00 2001 From: rvcas Date: Tue, 27 Feb 2024 21:21:09 -0500 Subject: [PATCH 01/38] fix: error message for bls elements in a type def closes #840 --- crates/aiken-lang/src/tipo/error.rs | 15 ++++++++++++++- crates/aiken-lang/src/tipo/infer.rs | 7 +++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/crates/aiken-lang/src/tipo/error.rs b/crates/aiken-lang/src/tipo/error.rs index 450a7218..1acbc454 100644 --- a/crates/aiken-lang/src/tipo/error.rs +++ b/crates/aiken-lang/src/tipo/error.rs @@ -259,7 +259,7 @@ You can use '{discard}' and numbers to distinguish between similar names. name: String, }, - #[error("I found a data type that has a function type in it. This is not allowed.\n")] + #[error("I found a type definition that has a function type in it. This is not allowed.\n")] #[diagnostic(code("illegal::function_in_type"))] #[diagnostic(help("Data-types can't hold functions. If you want to define method-like functions, group the type definition and the methods under a common namespace in a standalone module."))] FunctionTypeInData { @@ -267,6 +267,18 @@ You can use '{discard}' and numbers to distinguish between similar names. location: Span, }, + #[error("I found a type definition that has an unsupported type in it.\n")] + #[diagnostic(code("illegal::type_in_data"))] + #[diagnostic(help( + r#"Data-types can't contain type {type_info} because it can't be represented as PlutusData."#, + type_info = tipo.to_pretty(0).if_supports_color(Stdout, |s| s.red()) + ))] + IllegalTypeInData { + #[label] + location: Span, + tipo: Rc, + }, + #[error("I found a discarded expression not bound to a variable.\n")] #[diagnostic(code("implicit_discard"))] #[diagnostic(help( @@ -951,6 +963,7 @@ impl ExtraData for Error { | Error::DuplicateVarInPattern { .. } | Error::ExtraVarInAlternativePattern { .. } | Error::FunctionTypeInData { .. } + | Error::IllegalTypeInData { .. } | Error::ImplicitlyDiscardedExpression { .. } | Error::IncorrectFieldsArity { .. } | Error::IncorrectFunctionCallArity { .. } diff --git a/crates/aiken-lang/src/tipo/infer.rs b/crates/aiken-lang/src/tipo/infer.rs index 5dbea954..6adf8da9 100644 --- a/crates/aiken-lang/src/tipo/infer.rs +++ b/crates/aiken-lang/src/tipo/infer.rs @@ -545,6 +545,13 @@ fn infer_definition( location: *location, }); } + + if tipo.is_bls381_12_g1() || tipo.is_bls381_12_g2() || tipo.is_ml_result() { + return Err(Error::IllegalTypeInData { + location: *location, + tipo: tipo.clone(), + }); + } } } From 50c37c7a1434d2bc03994cbe7f8233acc136b046 Mon Sep 17 00:00:00 2001 From: rvcas Date: Tue, 27 Feb 2024 21:37:53 -0500 Subject: [PATCH 02/38] feat(aikup): error message when version not found closes #837 --- aikup/aikup | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/aikup/aikup b/aikup/aikup index 6f5b5430..66748696 100755 --- a/aikup/aikup +++ b/aikup/aikup @@ -1,5 +1,6 @@ #!/usr/bin/env bash set -e +set -o pipefail AIKEN_DIR=${AIKEN_DIR-"$HOME/.aiken"} AIKEN_BIN_DIR="$AIKEN_DIR/bin" @@ -86,7 +87,9 @@ main() { # Download the binaries tarball and unpack it into the .aiken bin directory. say "downloading aiken" - ensure curl -# -L "$BIN_TARBALL_URL" | tar -xzC "$AIKEN_BIN_DIR" + curl -f -# -L "$BIN_TARBALL_URL" | tar -xzC "$AIKEN_BIN_DIR" || { + err "failed to download aiken: version not found or network error" + } for bin in "${BINS[@]}"; do bin_path="$AIKEN_BIN_DIR/$bin" From d18caaeecbe0ae7b03cb08edd1ad9cfd105e0813 Mon Sep 17 00:00:00 2001 From: rvcas Date: Tue, 27 Feb 2024 21:55:13 -0500 Subject: [PATCH 03/38] feat(cli): support mainnet address output closes #832 --- crates/aiken-project/src/lib.rs | 9 ++++++++- crates/aiken/src/cmd/blueprint/address.rs | 7 ++++++- crates/aiken/src/cmd/blueprint/hash.rs | 2 +- crates/uplc/src/ast.rs | 2 ++ 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/crates/aiken-project/src/lib.rs b/crates/aiken-project/src/lib.rs index 959897c9..e1112b46 100644 --- a/crates/aiken-project/src/lib.rs +++ b/crates/aiken-project/src/lib.rs @@ -359,6 +359,7 @@ where &self, title: Option<&String>, stake_address: Option<&String>, + mainnet: bool, ) -> Result { // Parse stake address let stake_address = stake_address @@ -398,9 +399,15 @@ where if n > 0 { Err(blueprint::error::Error::ParameterizedValidator { n }.into()) } else { + let network = if mainnet { + Network::Mainnet + } else { + Network::Testnet + }; + Ok(validator .program - .address(Network::Testnet, delegation_part.to_owned())) + .address(network, delegation_part.to_owned())) } }) } diff --git a/crates/aiken/src/cmd/blueprint/address.rs b/crates/aiken/src/cmd/blueprint/address.rs index 1d83b69d..285b30d3 100644 --- a/crates/aiken/src/cmd/blueprint/address.rs +++ b/crates/aiken/src/cmd/blueprint/address.rs @@ -23,6 +23,10 @@ pub struct Args { /// Force the project to be rebuilt, otherwise relies on existing artifacts (i.e. plutus.json) #[clap(long)] rebuild: bool, + + /// Output the address for mainnet (this command defaults to testnet) + #[clap(long)] + mainnet: bool, } pub fn exec( @@ -32,6 +36,7 @@ pub fn exec( validator, delegated_to, rebuild, + mainnet, }: Args, ) -> miette::Result<()> { with_project(directory.as_deref(), false, |p| { @@ -51,7 +56,7 @@ pub fn exec( let title = title.as_ref().or(validator.as_ref()); - let address = p.address(title, delegated_to.as_ref())?; + let address = p.address(title, delegated_to.as_ref(), mainnet)?; println!("{}", address.to_bech32().unwrap()); diff --git a/crates/aiken/src/cmd/blueprint/hash.rs b/crates/aiken/src/cmd/blueprint/hash.rs index effe5e7f..ef67e702 100644 --- a/crates/aiken/src/cmd/blueprint/hash.rs +++ b/crates/aiken/src/cmd/blueprint/hash.rs @@ -46,7 +46,7 @@ pub fn exec( let title = title.as_ref().or(validator.as_ref()); - let address = p.address(title, None)?; + let address = p.address(title, None, false)?; println!("{}", address.payment().to_hex()); diff --git a/crates/uplc/src/ast.rs b/crates/uplc/src/ast.rs index e4e502cd..8a2e7323 100644 --- a/crates/uplc/src/ast.rs +++ b/crates/uplc/src/ast.rs @@ -161,7 +161,9 @@ impl<'a> Deserialize<'a> for Program { impl Program { pub fn address(&self, network: Network, delegation: ShelleyDelegationPart) -> ShelleyAddress { let cbor = self.to_cbor().unwrap(); + let validator_hash = babbage::PlutusV2Script(cbor.into()).compute_hash(); + ShelleyAddress::new( network, ShelleyPaymentPart::Script(validator_hash), From ff5491caa068cfead52d559408aba116af7defcb Mon Sep 17 00:00:00 2001 From: rvcas Date: Thu, 29 Feb 2024 11:19:26 -0500 Subject: [PATCH 04/38] fix(check): only disallow ml_result in data --- crates/aiken-lang/src/builtins.rs | 2 +- crates/aiken-lang/src/tests/check.rs | 27 +++++++++++++++++++++++++++ crates/aiken-lang/src/tipo/infer.rs | 2 +- 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/crates/aiken-lang/src/builtins.rs b/crates/aiken-lang/src/builtins.rs index c9016593..c3b0d662 100644 --- a/crates/aiken-lang/src/builtins.rs +++ b/crates/aiken-lang/src/builtins.rs @@ -153,7 +153,7 @@ pub fn prelude(id_gen: &IdGenerator) -> TypeInfo { MILLER_LOOP_RESULT.to_string(), TypeConstructor { parameters: vec![], - tipo: int(), + tipo: miller_loop_result(), location: Span::empty(), module: "".to_string(), public: true, diff --git a/crates/aiken-lang/src/tests/check.rs b/crates/aiken-lang/src/tests/check.rs index d7bc8eb7..1c978c6d 100644 --- a/crates/aiken-lang/src/tests/check.rs +++ b/crates/aiken-lang/src/tests/check.rs @@ -50,6 +50,33 @@ fn check_validator( check_module(ast, ModuleKind::Validator) } +#[test] +fn bls12_381_elements_in_data_type() { + let source_code = r#" + type Datum { + D0(G1Element) + D1(G2Element) + } + "#; + + assert!(check(parse(source_code)).is_ok()) +} + +#[test] +fn bls12_381_ml_result_in_data_type() { + let source_code = r#" + type Datum { + thing: MillerLoopResult + } + "#; + + let res = check(parse(source_code)); + + dbg!(&res); + + assert!(matches!(res, Err((_, Error::IllegalTypeInData { .. })))) +} + #[test] fn validator_illegal_return_type() { let source_code = r#" diff --git a/crates/aiken-lang/src/tipo/infer.rs b/crates/aiken-lang/src/tipo/infer.rs index 6adf8da9..9b94181b 100644 --- a/crates/aiken-lang/src/tipo/infer.rs +++ b/crates/aiken-lang/src/tipo/infer.rs @@ -546,7 +546,7 @@ fn infer_definition( }); } - if tipo.is_bls381_12_g1() || tipo.is_bls381_12_g2() || tipo.is_ml_result() { + if tipo.is_ml_result() { return Err(Error::IllegalTypeInData { location: *location, tipo: tipo.clone(), From d698f76e3c77e9421511e8ed56fb062d3227314d Mon Sep 17 00:00:00 2001 From: rvcas Date: Thu, 29 Feb 2024 12:13:48 -0500 Subject: [PATCH 05/38] fix(codegen): builtin calls for g1 and g2 where flipped closes #840 --- Cargo.lock | 1 + crates/aiken-lang/src/gen_uplc/builder.rs | 4 +- crates/aiken-project/Cargo.toml | 7 +- crates/aiken-project/src/tests/gen_uplc.rs | 118 ++++++++++++++++++++- crates/uplc/src/ast.rs | 2 +- 5 files changed, 125 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 680d68d9..654baf0a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -123,6 +123,7 @@ version = "1.0.24-alpha" dependencies = [ "aiken-lang", "askama", + "blst", "built", "dirs", "fslock", diff --git a/crates/aiken-lang/src/gen_uplc/builder.rs b/crates/aiken-lang/src/gen_uplc/builder.rs index 373bbc35..a9189131 100644 --- a/crates/aiken-lang/src/gen_uplc/builder.rs +++ b/crates/aiken-lang/src/gen_uplc/builder.rs @@ -1494,9 +1494,9 @@ pub fn convert_type_to_data(term: Term, field_type: &Rc) -> Term", - "Kasey White ", - "KtorZ ", + "Lucas Rosa ", + "Kasey White ", + "KtorZ ", ] rust-version = "1.66.1" build = "build.rs" @@ -45,6 +45,7 @@ aiken-lang = { path = "../aiken-lang", version = "1.0.24-alpha" } uplc = { path = '../uplc', version = "1.0.24-alpha" } [dev-dependencies] +blst = "0.3.11" indoc = "2.0.1" insta.workspace = true proptest = "1.2.0" diff --git a/crates/aiken-project/src/tests/gen_uplc.rs b/crates/aiken-project/src/tests/gen_uplc.rs index d3e1d051..6647e7f9 100644 --- a/crates/aiken-project/src/tests/gen_uplc.rs +++ b/crates/aiken-project/src/tests/gen_uplc.rs @@ -4,7 +4,7 @@ use aiken_lang::ast::{Definition, Function, TraceLevel, Tracing, TypedFunction, use uplc::{ ast::{Constant, Data, DeBruijn, Name, Program, Term, Type}, builder::{CONSTR_FIELDS_EXPOSER, CONSTR_INDEX_EXPOSER}, - machine::cost_model::ExBudget, + machine::{cost_model::ExBudget, runtime::Compressable}, optimize, }; @@ -6206,3 +6206,119 @@ fn tuple_2_match() { false, ); } + +#[test] +fn bls12_381_elements_to_data_conversion() { + let src = r#" + pub type Proof { + piA: G1Element, + piB: G2Element, + } + + test thing() { + let pk = + Proof { + piA: #"b28cb29bc282be68df977b35eb9d8e98b3a0a3fc7c372990bddc50419ca86693e491755338fed4fb42231a7c081252ce", + piB: #"b9215e5bc481ba6552384c89c23d45bd650b69462868248bfbb83aee7060579404dba41c781dec7c2bec5fccec06842e0e66ad6d86c7c76c468a32c9c0080eea0219d0953b44b1c4f5605afb1e5a3193264ff730222e94f55207628235f3b423", + } + + pk == pk + } + "#; + + let constant = Term::Constant( + Constant::Data(Data::constr( + 0, + vec![ + Data::bytestring(vec![ + 0xb2, 0x8c, 0xb2, 0x9b, 0xc2, 0x82, 0xbe, 0x68, 0xdf, 0x97, 0x7b, 0x35, 0xeb, + 0x9d, 0x8e, 0x98, 0xb3, 0xa0, 0xa3, 0xfc, 0x7c, 0x37, 0x29, 0x90, 0xbd, 0xdc, + 0x50, 0x41, 0x9c, 0xa8, 0x66, 0x93, 0xe4, 0x91, 0x75, 0x53, 0x38, 0xfe, 0xd4, + 0xfb, 0x42, 0x23, 0x1a, 0x7c, 0x08, 0x12, 0x52, 0xce, + ]), + Data::bytestring(vec![ + 0xb9, 0x21, 0x5e, 0x5b, 0xc4, 0x81, 0xba, 0x65, 0x52, 0x38, 0x4c, 0x89, 0xc2, + 0x3d, 0x45, 0xbd, 0x65, 0x0b, 0x69, 0x46, 0x28, 0x68, 0x24, 0x8b, 0xfb, 0xb8, + 0x3a, 0xee, 0x70, 0x60, 0x57, 0x94, 0x04, 0xdb, 0xa4, 0x1c, 0x78, 0x1d, 0xec, + 0x7c, 0x2b, 0xec, 0x5f, 0xcc, 0xec, 0x06, 0x84, 0x2e, 0x0e, 0x66, 0xad, 0x6d, + 0x86, 0xc7, 0xc7, 0x6c, 0x46, 0x8a, 0x32, 0xc9, 0xc0, 0x08, 0x0e, 0xea, 0x02, + 0x19, 0xd0, 0x95, 0x3b, 0x44, 0xb1, 0xc4, 0xf5, 0x60, 0x5a, 0xfb, 0x1e, 0x5a, + 0x31, 0x93, 0x26, 0x4f, 0xf7, 0x30, 0x22, 0x2e, 0x94, 0xf5, 0x52, 0x07, 0x62, + 0x82, 0x35, 0xf3, 0xb4, 0x23, + ]), + ], + )) + .into(), + ); + + assert_uplc( + src, + Term::equals_data().apply(constant.clone()).apply(constant), + false, + ) +} + +#[test] +fn bls12_381_elements_from_data_conversion() { + let src = r#" + pub type Proof { + piA: G1Element, + piB: G2Element, + } + + test thing() { + let pk = + Proof { + piA: #"b28cb29bc282be68df977b35eb9d8e98b3a0a3fc7c372990bddc50419ca86693e491755338fed4fb42231a7c081252ce", + piB: #"b9215e5bc481ba6552384c89c23d45bd650b69462868248bfbb83aee7060579404dba41c781dec7c2bec5fccec06842e0e66ad6d86c7c76c468a32c9c0080eea0219d0953b44b1c4f5605afb1e5a3193264ff730222e94f55207628235f3b423", + } + + pk.piA == #"b28cb29bc282be68df977b35eb9d8e98b3a0a3fc7c372990bddc50419ca86693e491755338fed4fb42231a7c081252ce" + } + "#; + + let bytes = vec![ + 0xb2, 0x8c, 0xb2, 0x9b, 0xc2, 0x82, 0xbe, 0x68, 0xdf, 0x97, 0x7b, 0x35, 0xeb, 0x9d, 0x8e, + 0x98, 0xb3, 0xa0, 0xa3, 0xfc, 0x7c, 0x37, 0x29, 0x90, 0xbd, 0xdc, 0x50, 0x41, 0x9c, 0xa8, + 0x66, 0x93, 0xe4, 0x91, 0x75, 0x53, 0x38, 0xfe, 0xd4, 0xfb, 0x42, 0x23, 0x1a, 0x7c, 0x08, + 0x12, 0x52, 0xce, + ]; + + let g1 = Term::Constant( + Constant::Bls12_381G1Element(blst::blst_p1::uncompress(&bytes).unwrap().into()).into(), + ); + + let constant = Term::Constant( + Constant::Data(Data::constr( + 0, + vec![ + Data::bytestring(bytes), + Data::bytestring(vec![ + 0xb9, 0x21, 0x5e, 0x5b, 0xc4, 0x81, 0xba, 0x65, 0x52, 0x38, 0x4c, 0x89, 0xc2, + 0x3d, 0x45, 0xbd, 0x65, 0x0b, 0x69, 0x46, 0x28, 0x68, 0x24, 0x8b, 0xfb, 0xb8, + 0x3a, 0xee, 0x70, 0x60, 0x57, 0x94, 0x04, 0xdb, 0xa4, 0x1c, 0x78, 0x1d, 0xec, + 0x7c, 0x2b, 0xec, 0x5f, 0xcc, 0xec, 0x06, 0x84, 0x2e, 0x0e, 0x66, 0xad, 0x6d, + 0x86, 0xc7, 0xc7, 0x6c, 0x46, 0x8a, 0x32, 0xc9, 0xc0, 0x08, 0x0e, 0xea, 0x02, + 0x19, 0xd0, 0x95, 0x3b, 0x44, 0xb1, 0xc4, 0xf5, 0x60, 0x5a, 0xfb, 0x1e, 0x5a, + 0x31, 0x93, 0x26, 0x4f, 0xf7, 0x30, 0x22, 0x2e, 0x94, 0xf5, 0x52, 0x07, 0x62, + 0x82, 0x35, 0xf3, 0xb4, 0x23, + ]), + ], + )) + .into(), + ); + + assert_uplc( + src, + Term::bls12_381_g1_equal() + .apply(Term::bls12_381_g1_uncompress().apply( + Term::un_b_data().apply( + Term::head_list().apply( + Term::snd_pair().apply(Term::unconstr_data().apply(constant.clone())), + ), + ), + )) + .apply(g1), + false, + ) +} diff --git a/crates/uplc/src/ast.rs b/crates/uplc/src/ast.rs index 8a2e7323..880890e0 100644 --- a/crates/uplc/src/ast.rs +++ b/crates/uplc/src/ast.rs @@ -271,7 +271,7 @@ pub enum Constant { Bls12_381MlResult(Box), } -pub struct Data {} +pub struct Data; // TODO: See about moving these builders upstream to Pallas? impl Data { From 2b8e99a1b8866bc362b3cac157a2510ede53371a Mon Sep 17 00:00:00 2001 From: KtorZ Date: Sat, 2 Mar 2024 13:34:25 +0100 Subject: [PATCH 06/38] Fix CI script for acceptance tests, and have them run in parallel. --- examples/acceptance_tests/036/aiken.lock | 2 +- examples/acceptance_tests/036/plutus.json | 2 +- examples/acceptance_tests/047/plutus.json | 2 +- examples/acceptance_tests/054/aiken.lock | 2 +- examples/acceptance_tests/055/aiken.lock | 2 +- examples/acceptance_tests/061/aiken.lock | 2 +- examples/acceptance_tests/063/aiken.lock | 2 +- examples/acceptance_tests/067/aiken.lock | 2 +- examples/acceptance_tests/068/aiken.lock | 2 +- examples/acceptance_tests/069/aiken.lock | 2 +- examples/acceptance_tests/070/aiken.lock | 2 +- examples/acceptance_tests/071/aiken.lock | 2 +- examples/acceptance_tests/071/plutus.json | 2 +- examples/acceptance_tests/072/aiken.lock | 2 +- examples/acceptance_tests/074/aiken.lock | 2 +- examples/acceptance_tests/077/aiken.lock | 2 +- examples/acceptance_tests/077/plutus.json | 2 +- examples/acceptance_tests/079/plutus.json | 2 +- examples/acceptance_tests/082/aiken.lock | 2 +- examples/acceptance_tests/083/aiken.lock | 2 +- examples/acceptance_tests/084/aiken.lock | 2 +- examples/acceptance_tests/086/aiken.lock | 2 +- examples/acceptance_tests/086/plutus.json | 2 +- examples/acceptance_tests/087/aiken.lock | 2 +- examples/acceptance_tests/088/aiken.lock | 2 +- examples/acceptance_tests/089/aiken.lock | 2 +- examples/acceptance_tests/089/plutus.json | 2 +- examples/acceptance_tests/090/plutus.json | 2 +- examples/acceptance_tests/ci | 14 +++++++++++--- .../acceptance_tests/script_context/aiken.lock | 2 +- .../acceptance_tests/script_context/plutus.json | 10 +++++----- 31 files changed, 45 insertions(+), 37 deletions(-) diff --git a/examples/acceptance_tests/036/aiken.lock b/examples/acceptance_tests/036/aiken.lock index eaf67618..d20af676 100644 --- a/examples/acceptance_tests/036/aiken.lock +++ b/examples/acceptance_tests/036/aiken.lock @@ -13,4 +13,4 @@ requirements = [] source = "github" [etags] -"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1707877506, nanos_since_epoch = 997686000 }, "cf946239d3dd481ed41f20e56bf24910b5229ea35aa171a708edc2a47fc20a7b"] +"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1709380938, nanos_since_epoch = 98285000 }, "cf946239d3dd481ed41f20e56bf24910b5229ea35aa171a708edc2a47fc20a7b"] diff --git a/examples/acceptance_tests/036/plutus.json b/examples/acceptance_tests/036/plutus.json index d11275aa..2895ff68 100644 --- a/examples/acceptance_tests/036/plutus.json +++ b/examples/acceptance_tests/036/plutus.json @@ -5,7 +5,7 @@ "plutusVersion": "v2", "compiler": { "name": "Aiken", - "version": "v1.0.24-alpha+ac0c73a" + "version": "v1.0.24-alpha+8532aff" } }, "validators": [ diff --git a/examples/acceptance_tests/047/plutus.json b/examples/acceptance_tests/047/plutus.json index fe71c017..2cce25e6 100644 --- a/examples/acceptance_tests/047/plutus.json +++ b/examples/acceptance_tests/047/plutus.json @@ -5,7 +5,7 @@ "plutusVersion": "v2", "compiler": { "name": "Aiken", - "version": "v1.0.24-alpha+ac0c73a" + "version": "v1.0.24-alpha+8532aff" } }, "validators": [ diff --git a/examples/acceptance_tests/054/aiken.lock b/examples/acceptance_tests/054/aiken.lock index f3562c22..2de9f424 100644 --- a/examples/acceptance_tests/054/aiken.lock +++ b/examples/acceptance_tests/054/aiken.lock @@ -13,4 +13,4 @@ requirements = [] source = "github" [etags] -"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1707877451, nanos_since_epoch = 945453000 }, "cf946239d3dd481ed41f20e56bf24910b5229ea35aa171a708edc2a47fc20a7b"] +"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1709380936, nanos_since_epoch = 549765000 }, "cf946239d3dd481ed41f20e56bf24910b5229ea35aa171a708edc2a47fc20a7b"] diff --git a/examples/acceptance_tests/055/aiken.lock b/examples/acceptance_tests/055/aiken.lock index 53b9e222..08f9c67a 100644 --- a/examples/acceptance_tests/055/aiken.lock +++ b/examples/acceptance_tests/055/aiken.lock @@ -13,4 +13,4 @@ requirements = [] source = "github" [etags] -"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1707877454, nanos_since_epoch = 923046000 }, "cf946239d3dd481ed41f20e56bf24910b5229ea35aa171a708edc2a47fc20a7b"] +"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1709380938, nanos_since_epoch = 133943000 }, "cf946239d3dd481ed41f20e56bf24910b5229ea35aa171a708edc2a47fc20a7b"] diff --git a/examples/acceptance_tests/061/aiken.lock b/examples/acceptance_tests/061/aiken.lock index 7ab1a75f..3ed1db6e 100644 --- a/examples/acceptance_tests/061/aiken.lock +++ b/examples/acceptance_tests/061/aiken.lock @@ -13,4 +13,4 @@ requirements = [] source = "github" [etags] -"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1707877469, nanos_since_epoch = 962343000 }, "cf946239d3dd481ed41f20e56bf24910b5229ea35aa171a708edc2a47fc20a7b"] +"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1709380954, nanos_since_epoch = 378021000 }, "cf946239d3dd481ed41f20e56bf24910b5229ea35aa171a708edc2a47fc20a7b"] diff --git a/examples/acceptance_tests/063/aiken.lock b/examples/acceptance_tests/063/aiken.lock index e917e5bf..89cc8205 100644 --- a/examples/acceptance_tests/063/aiken.lock +++ b/examples/acceptance_tests/063/aiken.lock @@ -13,4 +13,4 @@ requirements = [] source = "github" [etags] -"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1707877454, nanos_since_epoch = 909901000 }, "cf946239d3dd481ed41f20e56bf24910b5229ea35aa171a708edc2a47fc20a7b"] +"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1709380939, nanos_since_epoch = 227480000 }, "cf946239d3dd481ed41f20e56bf24910b5229ea35aa171a708edc2a47fc20a7b"] diff --git a/examples/acceptance_tests/067/aiken.lock b/examples/acceptance_tests/067/aiken.lock index bfcad5c4..f5091c2f 100644 --- a/examples/acceptance_tests/067/aiken.lock +++ b/examples/acceptance_tests/067/aiken.lock @@ -13,4 +13,4 @@ requirements = [] source = "github" [etags] -"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1707877474, nanos_since_epoch = 639765000 }, "cf946239d3dd481ed41f20e56bf24910b5229ea35aa171a708edc2a47fc20a7b"] +"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1709380958, nanos_since_epoch = 713857000 }, "cf946239d3dd481ed41f20e56bf24910b5229ea35aa171a708edc2a47fc20a7b"] diff --git a/examples/acceptance_tests/068/aiken.lock b/examples/acceptance_tests/068/aiken.lock index f67a0f3c..b2fac52f 100644 --- a/examples/acceptance_tests/068/aiken.lock +++ b/examples/acceptance_tests/068/aiken.lock @@ -13,4 +13,4 @@ requirements = [] source = "github" [etags] -"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1707877472, nanos_since_epoch = 989842000 }, "cf946239d3dd481ed41f20e56bf24910b5229ea35aa171a708edc2a47fc20a7b"] +"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1709380955, nanos_since_epoch = 138699000 }, "cf946239d3dd481ed41f20e56bf24910b5229ea35aa171a708edc2a47fc20a7b"] diff --git a/examples/acceptance_tests/069/aiken.lock b/examples/acceptance_tests/069/aiken.lock index 881a3a1c..646152c0 100644 --- a/examples/acceptance_tests/069/aiken.lock +++ b/examples/acceptance_tests/069/aiken.lock @@ -13,4 +13,4 @@ requirements = [] source = "github" [etags] -"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1707877474, nanos_since_epoch = 306725000 }, "cf946239d3dd481ed41f20e56bf24910b5229ea35aa171a708edc2a47fc20a7b"] +"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1709380957, nanos_since_epoch = 530063000 }, "cf946239d3dd481ed41f20e56bf24910b5229ea35aa171a708edc2a47fc20a7b"] diff --git a/examples/acceptance_tests/070/aiken.lock b/examples/acceptance_tests/070/aiken.lock index 7a502e70..ed372c03 100644 --- a/examples/acceptance_tests/070/aiken.lock +++ b/examples/acceptance_tests/070/aiken.lock @@ -13,4 +13,4 @@ requirements = [] source = "github" [etags] -"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1707877444, nanos_since_epoch = 552129000 }, "cf946239d3dd481ed41f20e56bf24910b5229ea35aa171a708edc2a47fc20a7b"] +"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1709380929, nanos_since_epoch = 819852000 }, "cf946239d3dd481ed41f20e56bf24910b5229ea35aa171a708edc2a47fc20a7b"] diff --git a/examples/acceptance_tests/071/aiken.lock b/examples/acceptance_tests/071/aiken.lock index ea215671..c9e56a8c 100644 --- a/examples/acceptance_tests/071/aiken.lock +++ b/examples/acceptance_tests/071/aiken.lock @@ -13,4 +13,4 @@ requirements = [] source = "github" [etags] -"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1707877445, nanos_since_epoch = 711317000 }, "cf946239d3dd481ed41f20e56bf24910b5229ea35aa171a708edc2a47fc20a7b"] +"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1709380931, nanos_since_epoch = 69042000 }, "cf946239d3dd481ed41f20e56bf24910b5229ea35aa171a708edc2a47fc20a7b"] diff --git a/examples/acceptance_tests/071/plutus.json b/examples/acceptance_tests/071/plutus.json index b87f7c64..927551dc 100644 --- a/examples/acceptance_tests/071/plutus.json +++ b/examples/acceptance_tests/071/plutus.json @@ -5,7 +5,7 @@ "plutusVersion": "v2", "compiler": { "name": "Aiken", - "version": "v1.0.24-alpha+ac0c73a" + "version": "v1.0.24-alpha+8532aff" } }, "validators": [ diff --git a/examples/acceptance_tests/072/aiken.lock b/examples/acceptance_tests/072/aiken.lock index ed9592f1..2cef9d7b 100644 --- a/examples/acceptance_tests/072/aiken.lock +++ b/examples/acceptance_tests/072/aiken.lock @@ -13,4 +13,4 @@ requirements = [] source = "github" [etags] -"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1707877462, nanos_since_epoch = 746349000 }, "cf946239d3dd481ed41f20e56bf24910b5229ea35aa171a708edc2a47fc20a7b"] +"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1709380947, nanos_since_epoch = 463143000 }, "cf946239d3dd481ed41f20e56bf24910b5229ea35aa171a708edc2a47fc20a7b"] diff --git a/examples/acceptance_tests/074/aiken.lock b/examples/acceptance_tests/074/aiken.lock index 9bb2c5b6..2c510c4d 100644 --- a/examples/acceptance_tests/074/aiken.lock +++ b/examples/acceptance_tests/074/aiken.lock @@ -13,4 +13,4 @@ requirements = [] source = "github" [etags] -"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1707877459, nanos_since_epoch = 940642000 }, "cf946239d3dd481ed41f20e56bf24910b5229ea35aa171a708edc2a47fc20a7b"] +"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1709380945, nanos_since_epoch = 171552000 }, "cf946239d3dd481ed41f20e56bf24910b5229ea35aa171a708edc2a47fc20a7b"] diff --git a/examples/acceptance_tests/077/aiken.lock b/examples/acceptance_tests/077/aiken.lock index d8e087f4..fd6d450a 100644 --- a/examples/acceptance_tests/077/aiken.lock +++ b/examples/acceptance_tests/077/aiken.lock @@ -13,4 +13,4 @@ requirements = [] source = "github" [etags] -"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1707877443, nanos_since_epoch = 793660000 }, "cf946239d3dd481ed41f20e56bf24910b5229ea35aa171a708edc2a47fc20a7b"] +"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1709380929, nanos_since_epoch = 326252000 }, "cf946239d3dd481ed41f20e56bf24910b5229ea35aa171a708edc2a47fc20a7b"] diff --git a/examples/acceptance_tests/077/plutus.json b/examples/acceptance_tests/077/plutus.json index b374c3a7..53017384 100644 --- a/examples/acceptance_tests/077/plutus.json +++ b/examples/acceptance_tests/077/plutus.json @@ -5,7 +5,7 @@ "plutusVersion": "v2", "compiler": { "name": "Aiken", - "version": "v1.0.24-alpha+ac0c73a" + "version": "v1.0.24-alpha+8532aff" } }, "validators": [ diff --git a/examples/acceptance_tests/079/plutus.json b/examples/acceptance_tests/079/plutus.json index 0efc8b39..251dcd8e 100644 --- a/examples/acceptance_tests/079/plutus.json +++ b/examples/acceptance_tests/079/plutus.json @@ -5,7 +5,7 @@ "plutusVersion": "v2", "compiler": { "name": "Aiken", - "version": "v1.0.24-alpha+ac0c73a" + "version": "v1.0.24-alpha+8532aff" } }, "validators": [ diff --git a/examples/acceptance_tests/082/aiken.lock b/examples/acceptance_tests/082/aiken.lock index 89d839b4..09cd6aa9 100644 --- a/examples/acceptance_tests/082/aiken.lock +++ b/examples/acceptance_tests/082/aiken.lock @@ -13,4 +13,4 @@ requirements = [] source = "github" [etags] -"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1707877446, nanos_since_epoch = 760870000 }, "cf946239d3dd481ed41f20e56bf24910b5229ea35aa171a708edc2a47fc20a7b"] +"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1709380932, nanos_since_epoch = 592853000 }, "cf946239d3dd481ed41f20e56bf24910b5229ea35aa171a708edc2a47fc20a7b"] diff --git a/examples/acceptance_tests/083/aiken.lock b/examples/acceptance_tests/083/aiken.lock index b7bc7f1f..a66a0efc 100644 --- a/examples/acceptance_tests/083/aiken.lock +++ b/examples/acceptance_tests/083/aiken.lock @@ -13,4 +13,4 @@ requirements = [] source = "github" [etags] -"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1707877444, nanos_since_epoch = 539452000 }, "cf946239d3dd481ed41f20e56bf24910b5229ea35aa171a708edc2a47fc20a7b"] +"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1709380929, nanos_since_epoch = 321331000 }, "cf946239d3dd481ed41f20e56bf24910b5229ea35aa171a708edc2a47fc20a7b"] diff --git a/examples/acceptance_tests/084/aiken.lock b/examples/acceptance_tests/084/aiken.lock index b8e14ba1..3f0b4986 100644 --- a/examples/acceptance_tests/084/aiken.lock +++ b/examples/acceptance_tests/084/aiken.lock @@ -13,4 +13,4 @@ requirements = [] source = "github" [etags] -"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1707877443, nanos_since_epoch = 796476000 }, "cf946239d3dd481ed41f20e56bf24910b5229ea35aa171a708edc2a47fc20a7b"] +"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1709380929, nanos_since_epoch = 897643000 }, "cf946239d3dd481ed41f20e56bf24910b5229ea35aa171a708edc2a47fc20a7b"] diff --git a/examples/acceptance_tests/086/aiken.lock b/examples/acceptance_tests/086/aiken.lock index a92ea6dd..5894b022 100644 --- a/examples/acceptance_tests/086/aiken.lock +++ b/examples/acceptance_tests/086/aiken.lock @@ -13,4 +13,4 @@ requirements = [] source = "github" [etags] -"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1707877463, nanos_since_epoch = 421256000 }, "cf946239d3dd481ed41f20e56bf24910b5229ea35aa171a708edc2a47fc20a7b"] +"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1709380947, nanos_since_epoch = 468037000 }, "cf946239d3dd481ed41f20e56bf24910b5229ea35aa171a708edc2a47fc20a7b"] diff --git a/examples/acceptance_tests/086/plutus.json b/examples/acceptance_tests/086/plutus.json index b0165a90..5dc74af8 100644 --- a/examples/acceptance_tests/086/plutus.json +++ b/examples/acceptance_tests/086/plutus.json @@ -5,7 +5,7 @@ "plutusVersion": "v2", "compiler": { "name": "Aiken", - "version": "v1.0.24-alpha+ac0c73a" + "version": "v1.0.24-alpha+8532aff" } }, "validators": [ diff --git a/examples/acceptance_tests/087/aiken.lock b/examples/acceptance_tests/087/aiken.lock index 590c0d52..de2a3c46 100644 --- a/examples/acceptance_tests/087/aiken.lock +++ b/examples/acceptance_tests/087/aiken.lock @@ -13,4 +13,4 @@ requirements = [] source = "github" [etags] -"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1707877459, nanos_since_epoch = 979094000 }, "cf946239d3dd481ed41f20e56bf24910b5229ea35aa171a708edc2a47fc20a7b"] +"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1709380945, nanos_since_epoch = 203745000 }, "cf946239d3dd481ed41f20e56bf24910b5229ea35aa171a708edc2a47fc20a7b"] diff --git a/examples/acceptance_tests/088/aiken.lock b/examples/acceptance_tests/088/aiken.lock index db840104..9324796c 100644 --- a/examples/acceptance_tests/088/aiken.lock +++ b/examples/acceptance_tests/088/aiken.lock @@ -13,4 +13,4 @@ requirements = [] source = "github" [etags] -"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1707877462, nanos_since_epoch = 777187000 }, "cf946239d3dd481ed41f20e56bf24910b5229ea35aa171a708edc2a47fc20a7b"] +"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1709380948, nanos_since_epoch = 315193000 }, "cf946239d3dd481ed41f20e56bf24910b5229ea35aa171a708edc2a47fc20a7b"] diff --git a/examples/acceptance_tests/089/aiken.lock b/examples/acceptance_tests/089/aiken.lock index 248342a5..48b32985 100644 --- a/examples/acceptance_tests/089/aiken.lock +++ b/examples/acceptance_tests/089/aiken.lock @@ -13,4 +13,4 @@ requirements = [] source = "github" [etags] -"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1707877458, nanos_since_epoch = 575935000 }, "cf946239d3dd481ed41f20e56bf24910b5229ea35aa171a708edc2a47fc20a7b"] +"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1709380943, nanos_since_epoch = 662175000 }, "cf946239d3dd481ed41f20e56bf24910b5229ea35aa171a708edc2a47fc20a7b"] diff --git a/examples/acceptance_tests/089/plutus.json b/examples/acceptance_tests/089/plutus.json index c2bbd547..a461a3c0 100644 --- a/examples/acceptance_tests/089/plutus.json +++ b/examples/acceptance_tests/089/plutus.json @@ -5,7 +5,7 @@ "plutusVersion": "v2", "compiler": { "name": "Aiken", - "version": "v1.0.24-alpha+ac0c73a" + "version": "v1.0.24-alpha+8532aff" } }, "validators": [ diff --git a/examples/acceptance_tests/090/plutus.json b/examples/acceptance_tests/090/plutus.json index 9755ea19..90e94bc8 100644 --- a/examples/acceptance_tests/090/plutus.json +++ b/examples/acceptance_tests/090/plutus.json @@ -5,7 +5,7 @@ "plutusVersion": "v2", "compiler": { "name": "Aiken", - "version": "v1.0.24-alpha+ac0c73a" + "version": "v1.0.24-alpha+8532aff" } }, "validators": [ diff --git a/examples/acceptance_tests/ci b/examples/acceptance_tests/ci index 6fbae13c..d3b786fa 100755 --- a/examples/acceptance_tests/ci +++ b/examples/acceptance_tests/ci @@ -2,11 +2,18 @@ exit_codes=() -for scenario in $(find . -maxdepth 1 -mindepth 1 -regex ".*[0-9]\{3\}" -type d); do - ./run $scenario - exit_codes+=("$?") +TESTS=() +for scenario in $(find . -maxdepth 1 -mindepth 1 -type d ! -name script_context); do + ./run $scenario & + TESTS+=("$!") done +for p in ${TESTS[@]}; do + wait $p + exit_codes+=("$?") +done + + for interaction in $(find script_context/validators -type f); do title=$(basename $interaction) title="${title%.*}" @@ -17,6 +24,7 @@ done for code in ${exit_codes[@]}; do if [ $code -ne 0 ]; then + echo "Some test returned non-zero code: $code" exit $code fi done diff --git a/examples/acceptance_tests/script_context/aiken.lock b/examples/acceptance_tests/script_context/aiken.lock index 1ac543fc..95860e37 100644 --- a/examples/acceptance_tests/script_context/aiken.lock +++ b/examples/acceptance_tests/script_context/aiken.lock @@ -13,4 +13,4 @@ requirements = [] source = "github" [etags] -"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1706677006, nanos_since_epoch = 304401000 }, "cf946239d3dd481ed41f20e56bf24910b5229ea35aa171a708edc2a47fc20a7b"] +"aiken-lang/stdlib@main" = [{ secs_since_epoch = 1709381590, nanos_since_epoch = 532309000 }, "cf946239d3dd481ed41f20e56bf24910b5229ea35aa171a708edc2a47fc20a7b"] diff --git a/examples/acceptance_tests/script_context/plutus.json b/examples/acceptance_tests/script_context/plutus.json index 68f84b4c..09020c93 100644 --- a/examples/acceptance_tests/script_context/plutus.json +++ b/examples/acceptance_tests/script_context/plutus.json @@ -5,7 +5,7 @@ "plutusVersion": "v2", "compiler": { "name": "Aiken", - "version": "v1.0.23-alpha+3a53427" + "version": "v1.0.24-alpha+8532aff" } }, "validators": [ @@ -23,8 +23,8 @@ "$ref": "#/definitions/Void" } }, - "compiledCode": "59032b01000032323232323232323222253330063253330073330073375e6018601a601a601a601a601a601a601a601a601a601a601a600a6002600a00498126d8799f58200000000000000000000000000000000000000000000000000000000000000000ff004a09444c94ccc020c8c94ccc028cdc3a400400226464a66601866ebcc018c02800530126d8799f58200000000000000000000000000000000000000000000000000000000000000000ff0013370e6eb4c014c028005200014a0602000260100042c60100026002600c0062646464a666016664464a6660220022c264a666024002264a66602066ebcc024c038004dd318032410151ad720e2a66602066ebcc028c038c028c038005300122d8799f581c11111111111111111111111111111111111111111111111111111111ff0015333010323253330123370e90000008a5014a260200026012601c6014601c0022a66602066ebcc014c03800530103d879800013375e6010601c00298103d87a800014a029405280a5030140021630140013758600460160024602260246024002600a601200c266ebcc00cc024c014c024018dd31800a40a8294094ccc02ccdc3800a4000297adef6c6013232330010014bd6f7b63011299980880089980919bb04c1014000374c00697adef6c6013232323253330123375e66012911000024c103d879800013301633760981014000374c00e00a2a66602466e3d22100002133016337609801014000374c00e00626602c66ec0dd48011ba600133006006003375660260066eb8c044008c054008c04c004c8cc0040052f5bded8c044a66602000226602266ec13001014000375000697adef6c6013232323253330113375e66010911000024c103d879800013301533760981014000375000e00a2a66602266e3d22100002133015337609801014000375000e00626602a66ec0dd48011ba800133006006003375a60240066eb8c040008c050008c048004894ccc02ccdc80010008a6103d87980001533300b3371e0040022980103d87a800014c103d87b80002300e300f300f300f00114a04601a601c00229408c03000452613656230053754002460066ea80055cd2ab9d5573caae7d5d02ba157441", - "hash": "899f2484d18c438e0e100fe6b08e8646d48322f3b3634f86cb51889d" + "compiledCode": "59034d010000323232323232323232232232253330083253330093330093375e601c601e601e601e601e601e601e601e601e601e601e601e600e6002600e00498126d8799f58200000000000000000000000000000000000000000000000000000000000000000ff004a09444c94ccc028c8c94ccc030cdc3a400400226464a66601c66ebcc018c03000530126d8799f58200000000000000000000000000000000000000000000000000000000000000000ff0013370e6eb4c014c030005200014a0602400260140042c6014002600260100062646464a66601a664464a6660260022c264a666028002264a66602466ebcc024c040004dd318032410151ad720e2a66602466ebcc028c040c028c040005300122d8799f581c11111111111111111111111111111111111111111111111111111111ff0015333012323253330143370e90000008a5014a2602400260126020601460200022a66602466ebcc014c04000530103d879800013375e6010602000298103d87a800014a029405280a50301600216301600137586004601a0024602660286028002600a601600c266ebcc00cc02cc014c02c018dd31800a40a8294094ccc034cdc3800a4000297adef6c6013232330010014bd6f7b63011299980980089980a19bb04c1014000374c00697adef6c6013232323253330143375e66012911000024c103d879800013301833760981014000374c00e00a2a66602866e3d22100002133018337609801014000374c00e00626603066ec0dd48011ba6001330060060033756602a0066eb8c04c008c05c008c054004c8cc0040052f5bded8c044a66602400226602666ec13001014000375000697adef6c6013232323253330133375e66010911000024c103d879800013301733760981014000375000e00a2a66602666e3d22100002133017337609801014000375000e00626602e66ec0dd48011ba800133006006003375a60280066eb8c048008c058008c050004894ccc034cdc80010008a6103d87980001533300d3371e0040022980103d87a800014c103d87b80002301030113011301100114a04601e602000229408c0380045261365653330063370e900018039baa0011498594ccc010cdc3a4000600a6ea800452616230053754002460066ea80055cd2ab9d5573caae7d5d02ba15745", + "hash": "381d52fa18759846189ed3aefd79cc3348e9a21bf37d02efd4d82803" }, { "title": "deploy.spend", @@ -68,8 +68,8 @@ "$ref": "#/definitions/Void" } }, - "compiledCode": "5901cb010000323232323232323232222533300632323253330093232533300b3370e90010008b099b87375a60206012004902a1804800998009bab30023007300330070044c0126d8799fd8799f581c22222222222222222222222222222222222222222222222222222222ffff00153330093232533300b3370e90010008b099b87375a60206012004900e1804800998009bab30023007300330070044c126d8799fd87a9f581cafddc16c18e7d8de379fb9aad39b3d1b5afd27603e5ebac818432a72ffff0013375e6e9cc8cc004004dd598019804180218040029129998070008a5eb804cc03cc030c040004cc008008c044004dd399806a6126d8799fd8799f581c22222222222222222222222222222222222222222222222222222222ffff003300d4c126d8799fd87a9f581cafddc16c18e7d8de379fb9aad39b3d1b5afd27603e5ebac818432a72ffff004bd700a5014a044646600200200644a66601e002298103d87a800013232323253330103375e00e004266e95200033014375000297ae0133006006003375a6022006601e004602600460220024601a601c601c601c601c601c601c0024601800229309b2b118029baa001230033754002ae6955ceaab9e5573eae815d0aba21", - "hash": "ab5c648e1399ad1c5ed964ca5eb98e90a842f3674dd26ebf2ec8e107" + "compiledCode": "5901ee01000032323232323232323223223225333008323232533300b3232533300d3370e90010008b099b87375a60246016004902a1805800998009bab30023009300330090044c0126d8799fd8799f581c22222222222222222222222222222222222222222222222222222222ffff001533300b3232533300d3370e90010008b099b87375a60246016004900e1805800998009bab30023009300330090044c126d8799fd87a9f581cafddc16c18e7d8de379fb9aad39b3d1b5afd27603e5ebac818432a72ffff0013375e6e9cc8cc004004dd598019805180218050029129998080008a5eb804cc044c038c048004cc008008c04c004dd399807a6126d8799fd8799f581c22222222222222222222222222222222222222222222222222222222ffff003300f4c126d8799fd87a9f581cafddc16c18e7d8de379fb9aad39b3d1b5afd27603e5ebac818432a72ffff004bd700a5014a044646600200200644a666022002298103d87a800013232323253330123375e00e004266e95200033016375000297ae0133006006003375a60260066022004602a00460260024601e6020602060206020602060200024601c00229309b2b299980319b8748000c01cdd50008a4c2ca66600866e1d2000300537540022930b118029baa001230033754002ae6955ceaab9e5573eae815d0aba201", + "hash": "1595536930902a5b877f84aa220ecf2f140f3f1c8a3f1c6face4b959" } ], "definitions": { From 4ff11f42295e5734fd878f9a821824cba2b888e1 Mon Sep 17 00:00:00 2001 From: KtorZ Date: Sat, 2 Mar 2024 14:11:01 +0100 Subject: [PATCH 07/38] Fix acceptance test 087 following BigInt seralization fix. --- examples/acceptance_tests/087/lib/tests.ak | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/acceptance_tests/087/lib/tests.ak b/examples/acceptance_tests/087/lib/tests.ak index 0c11a588..db884927 100644 --- a/examples/acceptance_tests/087/lib/tests.ak +++ b/examples/acceptance_tests/087/lib/tests.ak @@ -1,7 +1,7 @@ use aiken/cbor.{diagnostic, serialise} test cbor_serialise_large_num() { - serialise(18446744073709551615) == #"c248ffffffffffffffff" + serialise(18446744073709551615) == #"1bffffffffffffffff" } test cbor_diagnostic_large_num() { From 84c4ccaf4cc04be551c8e51a7f574eb01fa3c98f Mon Sep 17 00:00:00 2001 From: KtorZ Date: Sun, 3 Mar 2024 13:37:02 +0100 Subject: [PATCH 08/38] Forbid opaque types in the application binary interface. We cannot enforce internal invariants on opaque types from only structural checks on Data. Thus, it is forbidden to find an opaque type in an outward-facing interface. Instead, users should rely on intermediate representations and lift them into opaque types using constructors and methods provided by the type (e.g. Dict.from_list, Rational.from_int, Rational.new, ...) --- crates/aiken-project/src/blueprint/schema.rs | 75 ++++++++++--------- ...ests__opaque_singleton_multi_variants.snap | 22 ++++++ ...tor__tests__opaque_singleton_variants.snap | 68 ++++++++++------- .../aiken-project/src/blueprint/validator.rs | 64 ++++++++++------ 4 files changed, 147 insertions(+), 82 deletions(-) create mode 100644 crates/aiken-project/src/blueprint/snapshots/aiken_project__blueprint__validator__tests__opaque_singleton_multi_variants.snap diff --git a/crates/aiken-project/src/blueprint/schema.rs b/crates/aiken-project/src/blueprint/schema.rs index f07e02e7..dc40915c 100644 --- a/crates/aiken-project/src/blueprint/schema.rs +++ b/crates/aiken-project/src/blueprint/schema.rs @@ -1,5 +1,7 @@ -use crate::blueprint::definitions::{Definitions, Reference}; -use crate::CheckedModule; +use crate::{ + blueprint::definitions::{Definitions, Reference}, + CheckedModule, +}; use aiken_lang::{ ast::{Definition, TypedDataType, TypedDefinition}, builtins::wrapped_redeemer, @@ -12,8 +14,7 @@ use serde::{ ser::{Serialize, SerializeStruct, Serializer}, }; use serde_json as json; -use std::rc::Rc; -use std::{collections::HashMap, fmt, ops::Deref}; +use std::{collections::HashMap, fmt, ops::Deref, rc::Rc}; // NOTE: Can be anything BUT 0 pub const REDEEMER_DISCRIMINANT: usize = 1; @@ -385,21 +386,6 @@ impl Annotated { Type::Fn { .. } => unreachable!(), } } - - fn into_data(self, type_info: &Type) -> Result, Error> { - match self { - Annotated { - title, - description, - annotated: Schema::Data(data), - } => Ok(Annotated { - title, - description, - annotated: data, - }), - _ => Err(Error::new(ErrorContext::ExpectedData, type_info)), - } - } } impl Data { @@ -409,28 +395,24 @@ impl Data { type_parameters: &mut HashMap>, definitions: &mut Definitions>, ) -> Result { + if data_type.opaque { + // NOTE: No breadcrumbs here which is *okay*, as the caller will backtrack + // and add the necessary type information. + return Err(Error { + context: ErrorContext::IllegalOpaqueType, + breadcrumbs: vec![], + }); + } + let mut variants = vec![]; - let len_constructors = data_type.constructors.len(); for (index, constructor) in data_type.constructors.iter().enumerate() { let mut fields = vec![]; - let len_arguments = data_type.constructors.len(); for field in constructor.arguments.iter() { let reference = Annotated::do_from_type(&field.tipo, modules, type_parameters, definitions)?; - // NOTE: Opaque data-types with a single variant and a single field are transparent, they - // are erased completely at compilation time. - if data_type.opaque && len_constructors == 1 && len_arguments == 1 { - let schema = definitions - .lookup(&reference) - .expect("Schema definition registered just above") - .clone(); - definitions.remove(&reference); - return Ok(schema.into_data(&field.tipo)?.annotated); - } - fields.push(Annotated { title: field.label.clone(), description: field.doc.clone().map(|s| s.trim().to_string()), @@ -479,7 +461,7 @@ fn find_data_type(name: &str, definitions: &[TypedDefinition]) -> Option { - return Some(data_type.clone()) + return Some(data_type.clone()); } Definition::Fn { .. } | Definition::Validator { .. } @@ -928,7 +910,9 @@ pub struct Error { #[derive(Debug, PartialEq, Clone, thiserror::Error)] pub enum ErrorContext { - #[error("I failed at my own job and couldn't figure out how to generate a specification for a type.")] + #[error( + "I failed at my own job and couldn't figure out how to generate a specification for a type." + )] UnsupportedType, #[error("I discovered a type hole where I would expect a concrete type.")] @@ -942,6 +926,9 @@ pub enum ErrorContext { #[error("I figured you tried to export a function in your contract's binary interface.")] UnexpectedFunction, + + #[error("I caught an opaque type trying to escape")] + IllegalOpaqueType, } impl Error { @@ -963,6 +950,26 @@ impl Error { pub fn help(&self) -> String { match self.context { + ErrorContext::IllegalOpaqueType => format!( + r#"Opaque types cannot figure anywhere in an outward-facing type like a validator's redeemer or datum. This is because an {opaque} type hides its implementation details, and likely enforce invariants that cannot be expressed only structurally. In particular, the {opaque} type {signature} cannot be safely constructed from any Plutus Data. + +Hence, {opaque} types are forbidden from interface points with the off-chain world. Instead, use an intermediate representation and construct the {opaque} type at runtime using constructors and methods provided for that type (e.g. {Dict}.{from_list}, {Rational}.{new}, ...)."#, + opaque = "opaque".if_supports_color(Stdout, |s| s.purple()), + signature = Error::fmt_breadcrumbs(&[self + .breadcrumbs + .last() + .expect("always at least one breadcrumb") + .to_owned()]), + Dict = "Dict" + .if_supports_color(Stdout, |s| s.bright_blue()) + .if_supports_color(Stdout, |s| s.bold()), + from_list = "from_list".if_supports_color(Stdout, |s| s.blue()), + Rational = "Rational" + .if_supports_color(Stdout, |s| s.bright_blue()) + .if_supports_color(Stdout, |s| s.bold()), + new = "new".if_supports_color(Stdout, |s| s.blue()), + ), + ErrorContext::UnsupportedType => format!( r#"I do not know how to generate a portable Plutus specification for the following type: diff --git a/crates/aiken-project/src/blueprint/snapshots/aiken_project__blueprint__validator__tests__opaque_singleton_multi_variants.snap b/crates/aiken-project/src/blueprint/snapshots/aiken_project__blueprint__validator__tests__opaque_singleton_multi_variants.snap new file mode 100644 index 00000000..e397e816 --- /dev/null +++ b/crates/aiken-project/src/blueprint/snapshots/aiken_project__blueprint__validator__tests__opaque_singleton_multi_variants.snap @@ -0,0 +1,22 @@ +--- +source: crates/aiken-project/src/blueprint/validator.rs +description: "Code:\n\npub opaque type Rational {\n numerator: Int,\n denominator: Int,\n}\n\nvalidator {\n fn opaque_singleton_multi_variants(redeemer: Rational, ctx: Void) {\n True\n }\n}\n" +--- +Schema { + error: Error { + context: IllegalOpaqueType, + breadcrumbs: [ + App { + public: true, + module: "test_module", + name: "Rational", + args: [], + }, + ], + }, + location: 117..135, + source_code: NamedSource { + name: "", + source: "", + , +} diff --git a/crates/aiken-project/src/blueprint/snapshots/aiken_project__blueprint__validator__tests__opaque_singleton_variants.snap b/crates/aiken-project/src/blueprint/snapshots/aiken_project__blueprint__validator__tests__opaque_singleton_variants.snap index 2485eb95..18a09e86 100644 --- a/crates/aiken-project/src/blueprint/snapshots/aiken_project__blueprint__validator__tests__opaque_singleton_variants.snap +++ b/crates/aiken-project/src/blueprint/snapshots/aiken_project__blueprint__validator__tests__opaque_singleton_variants.snap @@ -2,32 +2,46 @@ source: crates/aiken-project/src/blueprint/validator.rs description: "Code:\n\npub opaque type Dict {\n inner: List<(ByteArray, value)>\n}\n\ntype UUID { UUID }\n\nvalidator {\n fn opaque_singleton_variants(redeemer: Dict, ctx: Void) {\n True\n }\n}\n" --- -{ - "title": "test_module.opaque_singleton_variants", - "redeemer": { - "title": "redeemer", - "schema": { - "$ref": "#/definitions/test_module~1Dict$test_module~1UUID_Int" - } - }, - "compiledCode": "58f201000032323232323232323223232253330064a22930a99803a4811856616c696461746f722072657475726e65642066616c73650013656323300100100222533300a00114984c8cc00c00cc034008c8c8c94cccccc04000454cc0280205854cc0280205854cc028020584dd68008a998050040b18058011929999998078008a998048038b0a998048038b0a998048038b0a998048038b09bae0013009001300b001533333300a001153300400216137560022a660080042c2a660080042c2a660080042c9211972656465656d65723a20446963743c555549442c20496e743e005734ae7155ceaab9e5573eae855d12ba41", - "hash": "c3f68ad7fb4d6c26e1f19799fe0ded6c9904bf04b924835ddad2abf0", - "definitions": { - "ByteArray": { - "dataType": "bytes" +Schema { + error: Error { + context: IllegalOpaqueType, + breadcrumbs: [ + App { + public: true, + module: "test_module", + name: "Dict", + args: [ + Var { + tipo: RefCell { + value: Link { + tipo: App { + public: false, + module: "test_module", + name: "UUID", + args: [], + }, + }, + }, + }, + Var { + tipo: RefCell { + value: Link { + tipo: App { + public: true, + module: "", + name: "Int", + args: [], + }, + }, + }, + }, + ], + }, + ], }, - "Int": { - "dataType": "integer" - }, - "test_module/Dict$test_module/UUID_Int": { - "title": "Dict", - "dataType": "map", - "keys": { - "$ref": "#/definitions/ByteArray" - }, - "values": { - "$ref": "#/definitions/Int" - } - } - } + location: 137..162, + source_code: NamedSource { + name: "", + source: "", + , } diff --git a/crates/aiken-project/src/blueprint/validator.rs b/crates/aiken-project/src/blueprint/validator.rs index cd891418..990b7de9 100644 --- a/crates/aiken-project/src/blueprint/validator.rs +++ b/crates/aiken-project/src/blueprint/validator.rs @@ -12,8 +12,7 @@ use aiken_lang::{ }; use miette::NamedSource; use serde; -use std::borrow::Borrow; -use std::rc::Rc; +use std::{borrow::Borrow, rc::Rc}; use uplc::{ ast::{Constant, DeBruijn, Program, Term}, PlutusData, @@ -250,17 +249,6 @@ impl Validator { #[cfg(test)] mod tests { - use std::collections::HashMap; - - use aiken_lang::{ - self, - ast::{TraceLevel, Tracing}, - builtins, - }; - use uplc::ast as uplc_ast; - - use crate::tests::TestProject; - use super::{ super::{ definitions::{Definitions, Reference}, @@ -269,6 +257,14 @@ mod tests { }, *, }; + use crate::tests::TestProject; + use aiken_lang::{ + self, + ast::{TraceLevel, Tracing}, + builtins, + }; + use std::collections::HashMap; + use uplc::ast as uplc_ast; macro_rules! assert_validator { ($code:expr) => { @@ -296,15 +292,23 @@ mod tests { let validator = validators .get(0) .unwrap() - .as_ref() - .expect("Failed to create validator blueprint"); + .as_ref(); - insta::with_settings!({ - description => concat!("Code:\n\n", indoc::indoc! { $code }), - omit_expression => true - }, { - insta::assert_json_snapshot!(validator); - }); + match validator { + Err(e) => insta::with_settings!({ + description => concat!("Code:\n\n", indoc::indoc! { $code }), + omit_expression => true + }, { + insta::assert_debug_snapshot!(e); + }), + + Ok(validator) => insta::with_settings!({ + description => concat!("Code:\n\n", indoc::indoc! { $code }), + omit_expression => true + }, { + insta::assert_json_snapshot!(validator); + }), + }; }; } @@ -514,6 +518,24 @@ mod tests { ); } + #[test] + fn opaque_singleton_multi_variants() { + assert_validator!( + r#" + pub opaque type Rational { + numerator: Int, + denominator: Int, + } + + validator { + fn opaque_singleton_multi_variants(redeemer: Rational, ctx: Void) { + True + } + } + "# + ); + } + #[test] fn nested_data() { assert_validator!( From aadf3cfb48c37ca305dd9978eb64e95e186797cb Mon Sep 17 00:00:00 2001 From: KtorZ Date: Sat, 24 Feb 2024 19:02:45 +0100 Subject: [PATCH 09/38] Allow test definition to carry one parameter The parameter is special as it takes no annotation but a 'via' keyword followed by an expression that should unify to a Fuzzer, where Fuzzer = fn(Seed) -> (Seed, a). The current commit only allow name identifiers for now. Ultimately, this may allow full expressions. --- crates/aiken-lang/src/ast.rs | 69 +++- crates/aiken-lang/src/format.rs | 99 ++++-- .../snapshots/def_invalid_property_test.snap | 50 +++ .../snapshots/def_property_test.snap | 38 ++ .../parser/definition/snapshots/def_test.snap | 21 ++ .../aiken-lang/src/parser/definition/test.rs | 102 +++++- crates/aiken-lang/src/parser/lexer.rs | 1 + crates/aiken-lang/src/parser/token.rs | 2 + crates/aiken-lang/src/tipo/environment.rs | 35 +- crates/aiken-lang/src/tipo/error.rs | 12 + crates/aiken-lang/src/tipo/expr.rs | 2 +- crates/aiken-lang/src/tipo/infer.rs | 331 ++++++++++++------ crates/aiken-project/src/tests/gen_uplc.rs | 4 +- 13 files changed, 579 insertions(+), 187 deletions(-) create mode 100644 crates/aiken-lang/src/parser/definition/snapshots/def_invalid_property_test.snap create mode 100644 crates/aiken-lang/src/parser/definition/snapshots/def_property_test.snap create mode 100644 crates/aiken-lang/src/parser/definition/snapshots/def_test.snap diff --git a/crates/aiken-lang/src/ast.rs b/crates/aiken-lang/src/ast.rs index 1811243b..68af1566 100644 --- a/crates/aiken-lang/src/ast.rs +++ b/crates/aiken-lang/src/ast.rs @@ -158,12 +158,15 @@ fn str_to_keyword(word: &str) -> Option { } } -pub type TypedFunction = Function, TypedExpr>; -pub type UntypedFunction = Function<(), UntypedExpr>; +pub type TypedFunction = Function, TypedExpr, TypedArg>; +pub type UntypedFunction = Function<(), UntypedExpr, UntypedArg>; + +pub type TypedTest = Function, TypedExpr, TypedArgVia>; +pub type UntypedTest = Function<(), UntypedExpr, UntypedArgVia>; #[derive(Debug, Clone, PartialEq)] -pub struct Function { - pub arguments: Vec>, +pub struct Function { + pub arguments: Vec, pub body: Expr, pub doc: Option, pub location: Span, @@ -178,7 +181,7 @@ pub struct Function { pub type TypedTypeAlias = TypeAlias>; pub type UntypedTypeAlias = TypeAlias<()>; -impl TypedFunction { +impl TypedTest { pub fn test_hint(&self) -> Option<(BinOp, Box, Box)> { do_test_hint(&self.body) } @@ -358,18 +361,24 @@ pub type UntypedValidator = Validator<(), UntypedExpr>; pub struct Validator { pub doc: Option, pub end_position: usize, - pub fun: Function, - pub other_fun: Option>, + pub fun: Function>, + pub other_fun: Option>>, pub location: Span, pub params: Vec>, } -pub type TypedDefinition = Definition, TypedExpr, String>; -pub type UntypedDefinition = Definition<(), UntypedExpr, ()>; +#[derive(Debug, Clone, PartialEq)] +pub struct DefinitionIdentifier { + pub module: Option, + pub name: String, +} + +pub type TypedDefinition = Definition, TypedExpr, String, ()>; +pub type UntypedDefinition = Definition<(), UntypedExpr, (), DefinitionIdentifier>; #[derive(Debug, Clone, PartialEq)] -pub enum Definition { - Fn(Function), +pub enum Definition { + Fn(Function>), TypeAlias(TypeAlias), @@ -379,12 +388,12 @@ pub enum Definition { ModuleConstant(ModuleConstant), - Test(Function), + Test(Function>), Validator(Validator), } -impl Definition { +impl Definition { pub fn location(&self) -> Span { match self { Definition::Fn(Function { location, .. }) @@ -634,6 +643,40 @@ impl Arg { } } +pub type TypedArgVia = ArgVia, ()>; +pub type UntypedArgVia = ArgVia<(), DefinitionIdentifier>; + +#[derive(Debug, Clone, PartialEq)] +pub struct ArgVia { + pub arg_name: ArgName, + pub location: Span, + pub via: Ann, + pub tipo: T, +} + +impl From> for Arg { + fn from(arg: ArgVia) -> Arg { + Arg { + arg_name: arg.arg_name, + location: arg.location, + tipo: arg.tipo, + annotation: None, + doc: None, + } + } +} + +impl From for TypedArgVia { + fn from(arg: TypedArg) -> TypedArgVia { + ArgVia { + arg_name: arg.arg_name, + tipo: arg.tipo, + location: arg.location, + via: (), + } + } +} + #[derive(Debug, Clone, PartialEq, Eq)] pub enum ArgName { Discarded { diff --git a/crates/aiken-lang/src/format.rs b/crates/aiken-lang/src/format.rs index 176aa02c..9d3045fb 100644 --- a/crates/aiken-lang/src/format.rs +++ b/crates/aiken-lang/src/format.rs @@ -1,11 +1,12 @@ use crate::{ ast::{ - Annotation, Arg, ArgName, AssignmentKind, BinOp, ByteArrayFormatPreference, CallArg, - ClauseGuard, Constant, CurveType, DataType, Definition, Function, IfBranch, - LogicalOpChainKind, ModuleConstant, Pattern, RecordConstructor, RecordConstructorArg, - RecordUpdateSpread, Span, TraceKind, TypeAlias, TypedArg, UnOp, UnqualifiedImport, - UntypedArg, UntypedClause, UntypedClauseGuard, UntypedDefinition, UntypedFunction, - UntypedModule, UntypedPattern, UntypedRecordUpdateArg, Use, Validator, CAPTURE_VARIABLE, + Annotation, Arg, ArgName, ArgVia, AssignmentKind, BinOp, ByteArrayFormatPreference, + CallArg, ClauseGuard, Constant, CurveType, DataType, Definition, DefinitionIdentifier, + Function, IfBranch, LogicalOpChainKind, ModuleConstant, Pattern, RecordConstructor, + RecordConstructorArg, RecordUpdateSpread, Span, TraceKind, TypeAlias, TypedArg, UnOp, + UnqualifiedImport, UntypedArg, UntypedArgVia, UntypedClause, UntypedClauseGuard, + UntypedDefinition, UntypedFunction, UntypedModule, UntypedPattern, UntypedRecordUpdateArg, + Use, Validator, CAPTURE_VARIABLE, }, docvec, expr::{FnStyle, UntypedExpr, DEFAULT_ERROR_STR, DEFAULT_TODO_STR}, @@ -231,16 +232,7 @@ impl<'comments> Formatter<'comments> { return_annotation, end_position, .. - }) => self.definition_fn( - public, - "fn", - name, - args, - return_annotation, - body, - *end_position, - false, - ), + }) => self.definition_fn(public, name, args, return_annotation, body, *end_position), Definition::Validator(Validator { end_position, @@ -257,16 +249,7 @@ impl<'comments> Formatter<'comments> { end_position, can_error, .. - }) => self.definition_fn( - &false, - "test", - name, - args, - &None, - body, - *end_position, - *can_error, - ), + }) => self.definition_test(name, args, body, *end_position, *can_error), Definition::TypeAlias(TypeAlias { alias, @@ -488,25 +471,40 @@ impl<'comments> Formatter<'comments> { commented(doc, comments) } + fn fn_arg_via<'a, A>(&mut self, arg: &'a ArgVia) -> Document<'a> { + let comments = self.pop_comments(arg.location.start); + + let doc_comments = self.doc_comments(arg.location.start); + + let doc = arg.arg_name.to_doc().append(" via "); + + let doc = match arg.via.module { + Some(ref module) => doc.append(module.to_doc()).append("."), + None => doc, + } + .append(arg.via.name.to_doc()) + .group(); + + let doc = doc_comments.append(doc.group()).group(); + + commented(doc, comments) + } + #[allow(clippy::too_many_arguments)] fn definition_fn<'a>( &mut self, public: &'a bool, - keyword: &'a str, name: &'a str, args: &'a [UntypedArg], return_annotation: &'a Option, body: &'a UntypedExpr, end_location: usize, - can_error: bool, ) -> Document<'a> { // Fn name and args let head = pub_(*public) - .append(keyword) - .append(" ") + .append("fn ") .append(name) - .append(wrap_args(args.iter().map(|e| (self.fn_arg(e), false)))) - .append(if can_error { " fail" } else { "" }); + .append(wrap_args(args.iter().map(|e| (self.fn_arg(e), false)))); // Add return annotation let head = match return_annotation { @@ -531,6 +529,39 @@ impl<'comments> Formatter<'comments> { .append("}") } + #[allow(clippy::too_many_arguments)] + fn definition_test<'a>( + &mut self, + name: &'a str, + args: &'a [UntypedArgVia], + body: &'a UntypedExpr, + end_location: usize, + can_error: bool, + ) -> Document<'a> { + // Fn name and args + let head = "test " + .to_doc() + .append(name) + .append(wrap_args(args.iter().map(|e| (self.fn_arg_via(e), false)))) + .append(if can_error { " fail" } else { "" }) + .group(); + + // Format body + let body = self.expr(body, true); + + // Add any trailing comments + let body = match printed_comments(self.pop_comments(end_location), false) { + Some(comments) => body.append(line()).append(comments), + None => body, + }; + + // Stick it all together + head.append(" {") + .append(line().append(body).nest(INDENT).group()) + .append(line()) + .append("}") + } + fn definition_validator<'a>( &mut self, params: &'a [UntypedArg], @@ -550,13 +581,11 @@ impl<'comments> Formatter<'comments> { let first_fn = self .definition_fn( &false, - "fn", &fun.name, &fun.arguments, &fun.return_annotation, &fun.body, fun.end_position, - false, ) .group(); let first_fn = commented(fun_doc_comments.append(first_fn).group(), fun_comments); @@ -570,13 +599,11 @@ impl<'comments> Formatter<'comments> { let other_fn = self .definition_fn( &false, - "fn", &other.name, &other.arguments, &other.return_annotation, &other.body, other.end_position, - false, ) .group(); diff --git a/crates/aiken-lang/src/parser/definition/snapshots/def_invalid_property_test.snap b/crates/aiken-lang/src/parser/definition/snapshots/def_invalid_property_test.snap new file mode 100644 index 00000000..7cd61a30 --- /dev/null +++ b/crates/aiken-lang/src/parser/definition/snapshots/def_invalid_property_test.snap @@ -0,0 +1,50 @@ +--- +source: crates/aiken-lang/src/parser/definition/test.rs +description: "Code:\n\ntest foo(x via f, y via g) {\n True\n}\n" +--- +Test( + Function { + arguments: [ + ArgVia { + arg_name: Named { + name: "x", + label: "x", + location: 9..10, + is_validator_param: false, + }, + location: 9..16, + via: DefinitionIdentifier { + module: None, + name: "f", + }, + tipo: (), + }, + ArgVia { + arg_name: Named { + name: "y", + label: "y", + location: 18..19, + is_validator_param: false, + }, + location: 18..25, + via: DefinitionIdentifier { + module: None, + name: "g", + }, + tipo: (), + }, + ], + body: Var { + location: 33..37, + name: "True", + }, + doc: None, + location: 0..26, + name: "foo", + public: false, + return_annotation: None, + return_type: (), + end_position: 38, + can_error: false, + }, +) diff --git a/crates/aiken-lang/src/parser/definition/snapshots/def_property_test.snap b/crates/aiken-lang/src/parser/definition/snapshots/def_property_test.snap new file mode 100644 index 00000000..8047f21e --- /dev/null +++ b/crates/aiken-lang/src/parser/definition/snapshots/def_property_test.snap @@ -0,0 +1,38 @@ +--- +source: crates/aiken-lang/src/parser/definition/test.rs +description: "Code:\n\ntest foo(x via fuzz.any_int) {\n True\n}\n" +--- +Test( + Function { + arguments: [ + ArgVia { + arg_name: Named { + name: "x", + label: "x", + location: 9..10, + is_validator_param: false, + }, + location: 9..27, + via: DefinitionIdentifier { + module: Some( + "fuzz", + ), + name: "any_int", + }, + tipo: (), + }, + ], + body: Var { + location: 35..39, + name: "True", + }, + doc: None, + location: 0..28, + name: "foo", + public: false, + return_annotation: None, + return_type: (), + end_position: 40, + can_error: false, + }, +) diff --git a/crates/aiken-lang/src/parser/definition/snapshots/def_test.snap b/crates/aiken-lang/src/parser/definition/snapshots/def_test.snap new file mode 100644 index 00000000..de24dc47 --- /dev/null +++ b/crates/aiken-lang/src/parser/definition/snapshots/def_test.snap @@ -0,0 +1,21 @@ +--- +source: crates/aiken-lang/src/parser/definition/test.rs +description: "Code:\n\ntest foo() {\n True\n}\n" +--- +Test( + Function { + arguments: [], + body: Var { + location: 17..21, + name: "True", + }, + doc: None, + location: 0..10, + name: "foo", + public: false, + return_annotation: None, + return_type: (), + end_position: 22, + can_error: false, + }, +) diff --git a/crates/aiken-lang/src/parser/definition/test.rs b/crates/aiken-lang/src/parser/definition/test.rs index 6691edb2..33d48628 100644 --- a/crates/aiken-lang/src/parser/definition/test.rs +++ b/crates/aiken-lang/src/parser/definition/test.rs @@ -13,8 +13,12 @@ pub fn parser() -> impl Parser name}) - .then_ignore(just(Token::LeftParen)) - .then_ignore(just(Token::RightParen)) + .then( + via() + .separated_by(just(Token::Comma)) + .allow_trailing() + .delimited_by(just(Token::LeftParen), just(Token::RightParen)), + ) .then(just(Token::Fail).ignored().or_not()) .map_with_span(|name, span| (name, span)) .then( @@ -22,26 +26,72 @@ pub fn parser() -> impl Parser impl Parser { + choice(( + select! {Token::DiscardName {name} => name}.map_with_span(|name, span| { + ast::ArgName::Discarded { + label: name.clone(), name, - public: false, - return_annotation: None, - return_type: (), - can_error: fail.is_some() || old_fail.is_some(), - }) - }) + location: span, + } + }), + select! {Token::Name {name} => name}.map_with_span(move |name, location| { + ast::ArgName::Named { + label: name.clone(), + name, + location, + is_validator_param: false, + } + }), + )) + .then_ignore(just(Token::Via)) + .then( + select! { Token::Name { name } => name } + .then_ignore(just(Token::Dot)) + .or_not(), + ) + .then(select! { Token::Name { name } => name }) + .map_with_span(|((arg_name, module), name), location| ast::ArgVia { + arg_name, + via: ast::DefinitionIdentifier { module, name }, + tipo: (), + location, + }) } #[cfg(test)] mod tests { use crate::assert_definition; + #[test] + fn def_test() { + assert_definition!( + r#" + test foo() { + True + } + "# + ); + } + #[test] fn def_test_fail() { assert_definition!( @@ -54,4 +104,26 @@ mod tests { "# ); } + + #[test] + fn def_property_test() { + assert_definition!( + r#" + test foo(x via fuzz.any_int) { + True + } + "# + ); + } + + #[test] + fn def_invalid_property_test() { + assert_definition!( + r#" + test foo(x via f, y via g) { + True + } + "# + ); + } } diff --git a/crates/aiken-lang/src/parser/lexer.rs b/crates/aiken-lang/src/parser/lexer.rs index 9dea075a..3e0df9cf 100644 --- a/crates/aiken-lang/src/parser/lexer.rs +++ b/crates/aiken-lang/src/parser/lexer.rs @@ -240,6 +240,7 @@ pub fn lexer() -> impl Parser, Error = ParseError> { "type" => Token::Type, "when" => Token::When, "validator" => Token::Validator, + "via" => Token::Via, _ => { if s.chars().next().map_or(false, |c| c.is_uppercase()) { Token::UpName { diff --git a/crates/aiken-lang/src/parser/token.rs b/crates/aiken-lang/src/parser/token.rs index cae2665b..d48e1179 100644 --- a/crates/aiken-lang/src/parser/token.rs +++ b/crates/aiken-lang/src/parser/token.rs @@ -89,6 +89,7 @@ pub enum Token { When, Trace, Validator, + Via, } impl fmt::Display for Token { @@ -176,6 +177,7 @@ impl fmt::Display for Token { Token::Test => "test", Token::Fail => "fail", Token::Validator => "validator", + Token::Via => "via", }; write!(f, "\"{s}\"") } diff --git a/crates/aiken-lang/src/tipo/environment.rs b/crates/aiken-lang/src/tipo/environment.rs index 3ba8e904..8bb9b383 100644 --- a/crates/aiken-lang/src/tipo/environment.rs +++ b/crates/aiken-lang/src/tipo/environment.rs @@ -10,7 +10,7 @@ use crate::{ RecordConstructor, RecordConstructorArg, Span, TypeAlias, TypedDefinition, TypedPattern, UnqualifiedImport, UntypedArg, UntypedDefinition, Use, Validator, PIPE_VARIABLE, }, - builtins::{self, function, generic_var, tuple, unbound_var}, + builtins::{function, generic_var, tuple, unbound_var}, tipo::fields::FieldMap, IdGenerator, }; @@ -1185,23 +1185,22 @@ impl<'a> Environment<'a> { }) } - Definition::Test(Function { name, location, .. }) => { - assert_unique_value_name(names, name, location)?; - hydrators.insert(name.clone(), Hydrator::new()); - let arg_types = vec![]; - let return_type = builtins::bool(); - self.insert_variable( - name.clone(), - ValueConstructorVariant::ModuleFn { - name: name.clone(), - field_map: None, - module: module_name.to_owned(), - arity: 0, - location: *location, - builtin: None, - }, - function(arg_types, return_type), - ); + Definition::Test(test) => { + let arguments = test + .arguments + .iter() + .map(|arg| arg.clone().into()) + .collect::>(); + + self.register_function( + &test.name, + &arguments, + &test.return_annotation, + module_name, + hydrators, + names, + &test.location, + )?; } Definition::DataType(DataType { diff --git a/crates/aiken-lang/src/tipo/error.rs b/crates/aiken-lang/src/tipo/error.rs index 1acbc454..1ed18458 100644 --- a/crates/aiken-lang/src/tipo/error.rs +++ b/crates/aiken-lang/src/tipo/error.rs @@ -946,6 +946,17 @@ The best thing to do from here is to remove it."#))] #[label("{} arguments", if *count < 2 { "not enough" } else { "too many" })] location: Span, }, + + #[error("I caught a test with too many arguments.\n")] + #[diagnostic(code("illegal::test_arity"))] + #[diagnostic(help( + "Tests are allowed to have 0 or 1 argument, but no more. Here I've found a test definition with {count} arguments. If you need to provide multiple values to a test, use a Record or a Tuple.", + ))] + IncorrectTestArity { + count: usize, + #[label("too many arguments")] + location: Span, + }, } impl ExtraData for Error { @@ -997,6 +1008,7 @@ impl ExtraData for Error { | Error::UnnecessarySpreadOperator { .. } | Error::UpdateMultiConstructorType { .. } | Error::ValidatorImported { .. } + | Error::IncorrectTestArity { .. } | Error::ValidatorMustReturnBool { .. } => None, Error::UnknownType { name, .. } diff --git a/crates/aiken-lang/src/tipo/expr.rs b/crates/aiken-lang/src/tipo/expr.rs index 83e55f33..b7bee950 100644 --- a/crates/aiken-lang/src/tipo/expr.rs +++ b/crates/aiken-lang/src/tipo/expr.rs @@ -1860,7 +1860,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { } } - fn infer_value_constructor( + pub fn infer_value_constructor( &mut self, module: &Option, name: &str, diff --git a/crates/aiken-lang/src/tipo/infer.rs b/crates/aiken-lang/src/tipo/infer.rs index 9b94181b..106a9aa3 100644 --- a/crates/aiken-lang/src/tipo/infer.rs +++ b/crates/aiken-lang/src/tipo/infer.rs @@ -2,15 +2,19 @@ use std::collections::HashMap; use crate::{ ast::{ - ArgName, DataType, Definition, Function, Layer, ModuleConstant, ModuleKind, - RecordConstructor, RecordConstructorArg, Tracing, TypeAlias, TypedDefinition, - TypedFunction, TypedModule, UntypedDefinition, UntypedModule, Use, Validator, + Annotation, Arg, ArgName, DataType, Definition, Function, Layer, ModuleConstant, + ModuleKind, RecordConstructor, RecordConstructorArg, Tracing, TypeAlias, TypedArg, + TypedDefinition, TypedFunction, TypedModule, UntypedArg, UntypedDefinition, UntypedModule, + Use, Validator, }, builtins, builtins::function, + expr::{TypedExpr, UntypedExpr}, line_numbers::LineNumbers, + tipo::{Span, Type}, IdGenerator, }; +use std::rc::Rc; use super::{ environment::{generalise, EntityKind, Environment}, @@ -159,97 +163,14 @@ fn infer_definition( tracing: Tracing, ) -> Result { match def { - Definition::Fn(Function { - doc, - location, - name, - public, - arguments: args, - body, - return_annotation, - end_position, - can_error, - .. - }) => { - let preregistered_fn = environment - .get_variable(&name) - .expect("Could not find preregistered type for function"); - - let field_map = preregistered_fn.field_map().cloned(); - - let preregistered_type = preregistered_fn.tipo.clone(); - - let (args_types, return_type) = preregistered_type - .function_types() - .expect("Preregistered type for fn was not a fn"); - - // Infer the type using the preregistered args + return types as a starting point - let (tipo, args, body, safe_to_generalise) = - environment.in_new_scope(|environment| { - let args = args - .into_iter() - .zip(&args_types) - .map(|(arg_name, tipo)| arg_name.set_type(tipo.clone())) - .collect(); - - let mut expr_typer = ExprTyper::new(environment, lines, tracing); - - expr_typer.hydrator = hydrators - .remove(&name) - .expect("Could not find hydrator for fn"); - - let (args, body) = - expr_typer.infer_fn_with_known_types(args, body, Some(return_type))?; - - let args_types = args.iter().map(|a| a.tipo.clone()).collect(); - - let tipo = function(args_types, body.tipo()); - - let safe_to_generalise = !expr_typer.ungeneralised_function_used; - - Ok::<_, Error>((tipo, args, body, safe_to_generalise)) - })?; - - // Assert that the inferred type matches the type of any recursive call - environment.unify(preregistered_type, tipo.clone(), location, false)?; - - // Generalise the function if safe to do so - let tipo = if safe_to_generalise { - environment.ungeneralised_functions.remove(&name); - - let tipo = generalise(tipo, 0); - - let module_fn = ValueConstructorVariant::ModuleFn { - name: name.clone(), - field_map, - module: module_name.to_owned(), - arity: args.len(), - location, - builtin: None, - }; - - environment.insert_variable(name.clone(), module_fn, tipo.clone()); - - tipo - } else { - tipo - }; - - Ok(Definition::Fn(Function { - doc, - location, - name, - public, - arguments: args, - return_annotation, - return_type: tipo - .return_type() - .expect("Could not find return type for fn"), - body, - can_error, - end_position, - })) - } + Definition::Fn(f) => Ok(Definition::Fn(infer_function( + f, + module_name, + hydrators, + environment, + lines, + tracing, + )?)), Definition::Validator(Validator { doc, @@ -412,20 +333,127 @@ fn infer_definition( } Definition::Test(f) => { - if let Definition::Fn(f) = infer_definition( - Definition::Fn(f), + fn annotate_fuzzer(tipo: &Type, location: &Span) -> Result { + match tipo { + // TODO: Ensure args & first returned element is a Prelude's PRNG. + Type::Fn { ret, .. } => { + let ann = tipo_to_annotation(ret, location)?; + match ann { + Annotation::Tuple { elems, .. } if elems.len() == 2 => { + Ok(elems.get(1).expect("Tuple has two elements").to_owned()) + } + _ => todo!("Fuzzer returns something else than a 2-tuple? "), + } + } + Type::Var { .. } | Type::App { .. } | Type::Tuple { .. } => { + todo!("Fuzzer type isn't a function?"); + } + } + } + + fn tipo_to_annotation(tipo: &Type, location: &Span) -> Result { + match tipo { + Type::App { + name, module, args, .. + } => { + let arguments = args + .iter() + .map(|arg| tipo_to_annotation(arg, location)) + .collect::, _>>()?; + Ok(Annotation::Constructor { + name: name.to_owned(), + module: Some(module.to_owned()), + arguments, + location: *location, + }) + } + Type::Tuple { elems } => { + let elems = elems + .iter() + .map(|arg| tipo_to_annotation(arg, location)) + .collect::, _>>()?; + Ok(Annotation::Tuple { + elems, + location: *location, + }) + } + Type::Fn { .. } | Type::Var { .. } => { + todo!("Fuzzer contains functions and/or non-concrete data-types?"); + } + } + } + + let annotation = match f.arguments.first() { + Some(arg) => { + if f.arguments.len() > 1 { + return Err(Error::IncorrectTestArity { + count: f.arguments.len(), + location: f.arguments.get(1).unwrap().location, + }); + } + + let ValueConstructor { tipo, .. } = ExprTyper::new(environment, lines, tracing) + .infer_value_constructor(&arg.via.module, &arg.via.name, &arg.location)?; + + Ok(Some(annotate_fuzzer(&tipo, &arg.location)?)) + } + None => Ok(None), + }?; + + let typed_f = infer_function( + Function { + doc: f.doc, + location: f.location, + name: f.name, + public: f.public, + arguments: f + .arguments + .into_iter() + .map(|arg| Arg { + annotation: annotation.clone(), + ..arg.into() + }) + .collect(), + return_annotation: f.return_annotation, + return_type: f.return_type, + body: f.body, + can_error: f.can_error, + end_position: f.end_position, + }, module_name, hydrators, environment, lines, tracing, - )? { - environment.unify(f.return_type.clone(), builtins::bool(), f.location, false)?; + )?; - Ok(Definition::Test(f)) - } else { - unreachable!("test definition inferred as something other than a function?") - } + environment.unify( + typed_f.return_type.clone(), + builtins::bool(), + typed_f.location, + false, + )?; + + Ok(Definition::Test(Function { + doc: typed_f.doc, + location: typed_f.location, + name: typed_f.name, + public: typed_f.public, + arguments: match annotation { + Some(_) => vec![typed_f + .arguments + .first() + .expect("has exactly one argument") + .to_owned() + .into()], + None => vec![], + }, + return_annotation: typed_f.return_annotation, + return_type: typed_f.return_type, + body: typed_f.body, + can_error: typed_f.can_error, + end_position: typed_f.end_position, + })) } Definition::TypeAlias(TypeAlias { @@ -640,3 +668,102 @@ fn infer_definition( } } } + +fn infer_function( + f: Function<(), UntypedExpr, UntypedArg>, + module_name: &String, + hydrators: &mut HashMap, + environment: &mut Environment<'_>, + lines: &LineNumbers, + tracing: Tracing, +) -> Result, TypedExpr, TypedArg>, Error> { + let Function { + doc, + location, + name, + public, + arguments, + body, + return_annotation, + end_position, + can_error, + .. + } = f; + + let preregistered_fn = environment + .get_variable(&name) + .expect("Could not find preregistered type for function"); + + let field_map = preregistered_fn.field_map().cloned(); + + let preregistered_type = preregistered_fn.tipo.clone(); + + let (args_types, return_type) = preregistered_type + .function_types() + .expect("Preregistered type for fn was not a fn"); + + // Infer the type using the preregistered args + return types as a starting point + let (tipo, arguments, body, safe_to_generalise) = environment.in_new_scope(|environment| { + let args = arguments + .into_iter() + .zip(&args_types) + .map(|(arg_name, tipo)| arg_name.set_type(tipo.clone())) + .collect(); + + let mut expr_typer = ExprTyper::new(environment, lines, tracing); + + expr_typer.hydrator = hydrators + .remove(&name) + .expect("Could not find hydrator for fn"); + + let (args, body) = expr_typer.infer_fn_with_known_types(args, body, Some(return_type))?; + + let args_types = args.iter().map(|a| a.tipo.clone()).collect(); + + let tipo = function(args_types, body.tipo()); + + let safe_to_generalise = !expr_typer.ungeneralised_function_used; + + Ok::<_, Error>((tipo, args, body, safe_to_generalise)) + })?; + + // Assert that the inferred type matches the type of any recursive call + environment.unify(preregistered_type, tipo.clone(), location, false)?; + + // Generalise the function if safe to do so + let tipo = if safe_to_generalise { + environment.ungeneralised_functions.remove(&name); + + let tipo = generalise(tipo, 0); + + let module_fn = ValueConstructorVariant::ModuleFn { + name: name.clone(), + field_map, + module: module_name.to_owned(), + arity: arguments.len(), + location, + builtin: None, + }; + + environment.insert_variable(name.clone(), module_fn, tipo.clone()); + + tipo + } else { + tipo + }; + + Ok(Function { + doc, + location, + name, + public, + arguments, + return_annotation, + return_type: tipo + .return_type() + .expect("Could not find return type for fn"), + body, + can_error, + end_position, + }) +} diff --git a/crates/aiken-project/src/tests/gen_uplc.rs b/crates/aiken-project/src/tests/gen_uplc.rs index 6647e7f9..a9ab36d5 100644 --- a/crates/aiken-project/src/tests/gen_uplc.rs +++ b/crates/aiken-project/src/tests/gen_uplc.rs @@ -1,6 +1,6 @@ use pretty_assertions::assert_eq; -use aiken_lang::ast::{Definition, Function, TraceLevel, Tracing, TypedFunction, TypedValidator}; +use aiken_lang::ast::{Definition, Function, TraceLevel, Tracing, TypedTest, TypedValidator}; use uplc::{ ast::{Constant, Data, DeBruijn, Name, Program, Term, Type}, builder::{CONSTR_FIELDS_EXPOSER, CONSTR_INDEX_EXPOSER}, @@ -13,7 +13,7 @@ use crate::module::CheckedModules; use super::TestProject; enum TestType { - Func(TypedFunction), + Func(TypedTest), Validator(TypedValidator), } From 3762473a600e5211cbf85e7829625081e8f2056d Mon Sep 17 00:00:00 2001 From: KtorZ Date: Sun, 25 Feb 2024 01:09:26 +0100 Subject: [PATCH 10/38] Add preliminary plumbing to run property test through the CLI. This is very very rough at the moment. But it does a couple of thing: 1. The 'ArgVia' now contains an Expr/TypedExpr which should unify to a Fuzzer. This is to avoid having to introduce custom logic to handle fuzzer referencing. So this now accepts function call, field access etc.. so long as they unify to the right thing. 2. I've done quite a lot of cleanup in aiken-project mostly around the tests and the naming surrounding them. What we used to call 'Script' is now called 'Test' and is an enum between UnitTest (ex-Script) and PropertyTest. I've moved some boilerplate and relevant function under those module Impl. 3. I've completed the end-to-end pipeline of: - Compiling the property test - Compiling the fuzzer - Generating an initial seed - Running property tests sequentially, threading the seed through each step. An interesting finding is that, I had to wrap the prop test in a similar wrapper that we use for validator, to ensure we convert primitive types wrapped in Data back to UPLC terms. This is necessary because the fuzzer return a ProtoPair (and soon an Array) which holds 'Data'. At the moment, we do nothing with the size, though the size should ideally grow after each iteration (up to a certain cap). In addition, there are a couple of todo/fixme that I left in the code as reminders of what's left to do beyond the obvious (error and success reporting, testing, etc..) --- Cargo.lock | 387 +++++++++--------- crates/aiken-lang/src/ast.rs | 41 +- crates/aiken-lang/src/format.rs | 28 +- crates/aiken-lang/src/gen_uplc.rs | 2 +- .../aiken-lang/src/parser/definition/test.rs | 36 +- crates/aiken-lang/src/tipo/infer.rs | 43 +- crates/aiken-project/Cargo.toml | 1 + crates/aiken-project/src/lib.rs | 137 +++++-- crates/aiken-project/src/script.rs | 179 ++++++-- crates/aiken-project/src/telemetry.rs | 22 +- crates/aiken-project/src/tests/gen_uplc.rs | 2 +- crates/uplc/src/machine/error.rs | 2 +- crates/uplc/src/machine/eval_result.rs | 5 +- examples/acceptance_tests/093/aiken.toml | 5 +- examples/acceptance_tests/093/lib/foo.ak | 16 +- 15 files changed, 559 insertions(+), 347 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 654baf0a..e97a58dc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -19,9 +19,9 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "aes" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" dependencies = [ "cfg-if", "cipher", @@ -30,9 +30,9 @@ dependencies = [ [[package]] name = "ahash" -version = "0.8.7" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77c3a9648d43b9cd48db467b3f87fdd6e146bcc88ab0180006cef2179fe11d01" +checksum = "8b79b82693f705137f8fb9b37871d99e4f9a7df12b917eed79c3d3954830a60b" dependencies = [ "cfg-if", "once_cell", @@ -136,6 +136,7 @@ dependencies = [ "itertools", "miette", "notify", + "num-bigint", "owo-colors", "pallas", "petgraph", @@ -164,9 +165,9 @@ checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" [[package]] name = "anstream" -version = "0.6.11" +version = "0.6.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e2e1ebcb11de5c03c67de28a7df593d32191b44939c482e97702baaaa6ab6a5" +checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb" dependencies = [ "anstyle", "anstyle-parse", @@ -178,9 +179,9 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.4" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" +checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" [[package]] name = "anstyle-parse" @@ -212,9 +213,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.79" +version = "1.0.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" +checksum = "5ad32ce52e4161730f7098c077cd2ed6229b5804ccf99e5366be1ab72a98b4e1" [[package]] name = "arrayvec" @@ -248,7 +249,7 @@ dependencies = [ "proc-macro2", "quote", "serde", - "syn 2.0.48", + "syn 2.0.52", ] [[package]] @@ -274,7 +275,7 @@ checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.52", ] [[package]] @@ -458,9 +459,9 @@ dependencies = [ [[package]] name = "bstr" -version = "1.9.0" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c48f0051a4b4c5e0b6d365cd04af53aeaa209e3cc15ec2cdb69e73cc87fbd0dc" +checksum = "05efc5cfd9110c8416e471df0e96702d58690178e206e61b7173706673c93706" dependencies = [ "memchr", "serde", @@ -478,9 +479,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.14.0" +version = "3.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" +checksum = "8ea184aa71bb362a1157c896979544cc23974e08fd265f29ea96b59f0b4a555b" [[package]] name = "byteorder" @@ -529,11 +530,10 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.83" +version = "1.0.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +checksum = "02f341c093d19155a6e41631ce5971aac4e9a868262212153124c15fa22d1cdc" dependencies = [ - "jobserver", "libc", ] @@ -545,9 +545,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.32" +version = "0.4.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41daef31d7a747c5c847246f36de49ced6f7403b4cdabc807a97b5cc184cda7a" +checksum = "5bc015644b92d5890fab7489e49d21f879d5c990186827d42ec511919404f38b" dependencies = [ "num-traits", ] @@ -574,9 +574,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.18" +version = "4.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e578d6ec4194633722ccf9544794b71b1385c3c027efe0c55db226fc880865c" +checksum = "c918d541ef2913577a0f9566e9ce27cb35b6df072075769e0b26cb5a554520da" dependencies = [ "clap_builder", "clap_derive", @@ -584,9 +584,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.18" +version = "4.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4df4df40ec50c46000231c914968278b1eb05098cf8f1b3a518a95030e71d1c7" +checksum = "9f3e7391dad68afb0c2ede1bf619f579a3dc9c2ec67f089baa397123a2f3d1eb" dependencies = [ "anstream", "anstyle", @@ -599,30 +599,30 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.4.9" +version = "4.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df631ae429f6613fcd3a7c1adbdb65f637271e561b03680adaa6573015dfb106" +checksum = "885e4d7d5af40bfb99ae6f9433e292feac98d452dcb3ec3d25dfe7552b77da8c" dependencies = [ "clap", ] [[package]] name = "clap_derive" -version = "4.4.7" +version = "4.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" +checksum = "307bc0538d5f0f83b8248db3087aa92fe504e4691294d0c96c0eabc33f47ba47" dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.52", ] [[package]] name = "clap_lex" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" +checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" [[package]] name = "colorchoice" @@ -696,18 +696,18 @@ checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" [[package]] name = "crc32fast" -version = "1.3.2" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" dependencies = [ "cfg-if", ] [[package]] name = "crossbeam-channel" -version = "0.5.11" +version = "0.5.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "176dc175b78f56c0f321911d9c8eb2b77a78a4860b9c19db83835fea1a46649b" +checksum = "ab3db02a9c5b5121e1e42fbdb1aeb65f5e02624cc58c43f2884c6ccac0b82f95" dependencies = [ "crossbeam-utils", ] @@ -849,9 +849,9 @@ dependencies = [ [[package]] name = "dyn-clone" -version = "1.0.16" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "545b22097d44f8a9581187cdf93de7a71e4722bf51200cfaba810865b49a495d" +checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" [[package]] name = "ecdsa" @@ -869,9 +869,9 @@ dependencies = [ [[package]] name = "either" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" [[package]] name = "elliptic-curve" @@ -1072,7 +1072,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.52", ] [[package]] @@ -1188,7 +1188,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap 2.1.0", + "indexmap 2.2.5", "slab", "tokio", "tokio-util", @@ -1197,9 +1197,9 @@ dependencies = [ [[package]] name = "half" -version = "1.8.2" +version = "1.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" +checksum = "1b43ede17f21864e81be2fa654110bf1e793774238d86ef8555c37e6519c0403" [[package]] name = "hashbrown" @@ -1234,9 +1234,9 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.3.4" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d3d0e0f38255e7fa3cf31335b3a56f05febd18025f4db5ef7a0cfb4f8da651f" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" [[package]] name = "hex" @@ -1392,9 +1392,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.1.0" +version = "2.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" +checksum = "7b0b929d511467233429c45a44ac1dcaa21ba0f5ba11e4879e6ed28ddb4f9df4" dependencies = [ "equivalent", "hashbrown 0.14.3", @@ -1453,9 +1453,9 @@ dependencies = [ [[package]] name = "insta" -version = "1.34.0" +version = "1.35.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d64600be34b2fcfc267740a243fa7744441bb4947a619ac4e5bb6507f35fbfc" +checksum = "7c985c1bef99cf13c58fade470483d81a2bfe846ebde60ed28cc2dddec2df9e2" dependencies = [ "console", "lazy_static", @@ -1473,20 +1473,20 @@ checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" [[package]] name = "is-terminal" -version = "0.4.10" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bad00257d07be169d870ab665980b06cdb366d792ad690bf2e76876dc503455" +checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" dependencies = [ - "hermit-abi 0.3.4", - "rustix", + "hermit-abi 0.3.9", + "libc", "windows-sys 0.52.0", ] [[package]] name = "is_ci" -version = "1.1.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "616cde7c720bb2bb5824a224687d8f77bfd38922027f01d825cd7453be5099fb" +checksum = "7655c9839580ee829dfacba1d1278c2b7883e50a277ff7541299489d6bdfdc45" [[package]] name = "itertools" @@ -1503,20 +1503,11 @@ version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" -[[package]] -name = "jobserver" -version = "0.1.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d" -dependencies = [ - "libc", -] - [[package]] name = "js-sys" -version = "0.3.67" +version = "0.3.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a1d36f1235bc969acba30b7f5990b864423a6068a10f7c90ae8f0112e3a59d1" +checksum = "406cda4b368d531c842222cf9d2600a9a4acce8d29423695379c6868a143a9ee" dependencies = [ "wasm-bindgen", ] @@ -1572,9 +1563,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.152" +version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" [[package]] name = "libgit2-sys" @@ -1607,9 +1598,9 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.1.14" +version = "1.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "295c17e837573c8c821dbaeb3cceb3d745ad082f7572191409e69cbc1b3fd050" +checksum = "037731f5d3aaa87a5675e895b63ddff1a87624bc29f77004ea829809654e48f6" dependencies = [ "cc", "libc", @@ -1641,9 +1632,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.20" +version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" [[package]] name = "lsp-server" @@ -1711,7 +1702,7 @@ checksum = "49e7bc1560b95a3c4a25d03de42fe76ca718ab92d1a22a55b9b4cf67b3ae635c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.52", ] [[package]] @@ -1759,9 +1750,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" dependencies = [ "adler", ] @@ -1852,20 +1843,25 @@ dependencies = [ ] [[package]] -name = "num-integer" -version = "0.1.45" +name = "num-conv" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" dependencies = [ - "autocfg", "num-traits", ] [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" dependencies = [ "autocfg", "libm", @@ -1877,7 +1873,7 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi 0.3.4", + "hermit-abi 0.3.9", "libc", ] @@ -1898,9 +1894,9 @@ checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "openssl" -version = "0.10.63" +version = "0.10.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15c9d69dd87a29568d4d017cfe8ec518706046a05184e5aea92d0af890b803c8" +checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" dependencies = [ "bitflags 2.4.2", "cfg-if", @@ -1919,7 +1915,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.52", ] [[package]] @@ -1930,9 +1926,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.99" +version = "0.9.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22e1bf214306098e4832460f797824c05d25aacdf896f64a985fb0fd992454ae" +checksum = "dda2b0f344e78efc2facf7d195d098df0dd72151b26ab98da807afc26c198dff" dependencies = [ "cc", "libc", @@ -2239,27 +2235,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" dependencies = [ "fixedbitset", - "indexmap 2.1.0", + "indexmap 2.2.5", ] [[package]] name = "pin-project" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" +checksum = "0302c4a0442c456bd56f841aee5c3bfd17967563f6fadc9ceb9f9c23cf3807e0" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" +checksum = "266c042b60c9c76b8d53061e52b2e0d1116abc57cefc8c5cd671619a56ac3690" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.52", ] [[package]] @@ -2286,9 +2282,9 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2900ede94e305130c13ddd391e0ab7cbaeb783945ae07a279c268cb05109c6cb" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" [[package]] name = "powerfmt" @@ -2428,11 +2424,11 @@ dependencies = [ [[package]] name = "pulldown-cmark" -version = "0.9.3" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a1a2f1f0a7ecff9c31abbe177637be0e97a0aef46cf8738ece09327985d998" +checksum = "57206b407293d2bcd3af849ce869d52068623f19e1b5ff8e8778e3309439682b" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.4.2", "memchr", "unicase", ] @@ -2493,9 +2489,9 @@ dependencies = [ [[package]] name = "rayon" -version = "1.8.1" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7237101a77a10773db45d62004a272517633fbcc3df19d96455ede1122e051" +checksum = "e4963ed1bc86e4f3ee217022bd855b297cef07fb9eac5dfa1f788b220b49b3bd" dependencies = [ "either", "rayon-core", @@ -2545,9 +2541,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b7fa1134405e2ec9353fd416b17f8dacd46c473d7d3fd1cf202706a14eb792a" +checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd" dependencies = [ "aho-corasick", "memchr", @@ -2562,9 +2558,9 @@ checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" [[package]] name = "reqwest" -version = "0.11.23" +version = "0.11.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37b1ae8d9ac08420c66222fb9096fc5de435c3c48542bc5336c51892cffafb41" +checksum = "c6920094eb85afde5e4a138be3f2de8bbdf28000f0029e72c45025a56b042251" dependencies = [ "base64 0.21.7", "bytes", @@ -2584,9 +2580,11 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", + "rustls-pemfile", "serde", "serde_json", "serde_urlencoded", + "sync_wrapper", "system-configuration", "tokio", "tokio-native-tls", @@ -2616,9 +2614,9 @@ checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" [[package]] name = "rustix" -version = "0.38.30" +version = "0.38.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "322394588aaf33c24007e8bb3238ee3e4c5c09c084ab32bc73890b99ff326bca" +checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" dependencies = [ "bitflags 2.4.2", "errno", @@ -2627,6 +2625,15 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "rustls-pemfile" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +dependencies = [ + "base64 0.21.7", +] + [[package]] name = "rustversion" version = "1.0.14" @@ -2647,9 +2654,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.16" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" +checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" [[package]] name = "same-file" @@ -2732,40 +2739,40 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.21" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0" +checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" dependencies = [ "serde", ] [[package]] name = "serde" -version = "1.0.195" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02" +checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.195" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c" +checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.52", ] [[package]] name = "serde_json" -version = "1.0.111" +version = "1.0.114" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "176e46fa42316f18edd598015a5166857fc835ec732f5215eac6b7bdbf0a84f4" +checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" dependencies = [ - "indexmap 2.1.0", + "indexmap 2.2.5", "itoa", "ryu", "serde", @@ -2779,7 +2786,7 @@ checksum = "0b2e6b945e9d3df726b65d6ee24060aff8e3533d431f677a9695db04eff9dfdb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.52", ] [[package]] @@ -2904,12 +2911,12 @@ checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c" [[package]] name = "socket2" -version = "0.5.5" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" +checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871" dependencies = [ "libc", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -2946,9 +2953,9 @@ dependencies = [ [[package]] name = "strsim" -version = "0.10.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01" [[package]] name = "strum" @@ -3026,9 +3033,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.48" +version = "2.0.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "b699d15b36d1f02c3e7c69f8ffef53de37aefae075d8488d4ba1a7788d574a07" dependencies = [ "proc-macro2", "quote", @@ -3064,13 +3071,12 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.9.0" +version = "3.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01ce4141aa927a6d1bd34a041795abd0db1cccba5d5f24b009f694bdf3a1f3fa" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" dependencies = [ "cfg-if", "fastrand", - "redox_syscall", "rustix", "windows-sys 0.52.0", ] @@ -3108,22 +3114,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.56" +version = "1.0.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" +checksum = "1e45bcbe8ed29775f228095caf2cd67af7a4ccf756ebff23a306bf3e8b47b24b" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.56" +version = "1.0.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" +checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.52", ] [[package]] @@ -3137,11 +3143,12 @@ dependencies = [ [[package]] name = "time" -version = "0.3.31" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f657ba42c3f86e7680e53c8cd3af8abbe56b5491790b46e22e19c0d57463583e" +checksum = "c8248b6521bb14bc45b4067159b9b6ad792e2d6d754d6c41fb50e29fefe38749" dependencies = [ "deranged", + "num-conv", "powerfmt", "serde", "time-core", @@ -3170,9 +3177,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.35.1" +version = "1.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c89b4efa943be685f629b149f53829423f8f5531ea21249408e8e2f8671ec104" +checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" dependencies = [ "backtrace", "bytes", @@ -3205,7 +3212,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.52", ] [[package]] @@ -3270,7 +3277,7 @@ version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap 2.1.0", + "indexmap 2.2.5", "serde", "serde_spanned", "toml_datetime", @@ -3356,7 +3363,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.52", ] [[package]] @@ -3421,18 +3428,18 @@ checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" [[package]] name = "unicode-normalization" -version = "0.1.22" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" dependencies = [ "tinyvec", ] [[package]] name = "unicode-segmentation" -version = "1.10.1" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" +checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" [[package]] name = "unicode-width" @@ -3607,9 +3614,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.90" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1223296a201415c7fad14792dbefaace9bd52b62d33453ade1c5b5f07555406" +checksum = "c1e124130aee3fb58c5bdd6b639a0509486b0338acaaae0c84a5124b0f588b7f" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -3617,24 +3624,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.90" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcdc935b63408d58a32f8cc9738a0bffd8f05cc7c002086c6ef20b7312ad9dcd" +checksum = "c9e7e1900c352b609c8488ad12639a311045f40a35491fb69ba8c12f758af70b" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.52", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.40" +version = "0.4.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bde2032aeb86bdfaecc8b261eef3cba735cc426c1f3a3416d1e0791be95fc461" +checksum = "877b9c3f61ceea0e56331985743b13f3d25c406a7098d45180fb5f09bc19ed97" dependencies = [ "cfg-if", "js-sys", @@ -3644,9 +3651,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.90" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e4c238561b2d428924c49815533a8b9121c664599558a5d9ec51f8a1740a999" +checksum = "b30af9e2d358182b5c7449424f017eba305ed32a7010509ede96cdc4696c46ed" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3654,28 +3661,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.90" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bae1abb6806dc1ad9e560ed242107c0f6c84335f1749dd4e8ddb012ebd5e25a7" +checksum = "642f325be6301eb8107a83d12a8ac6c1e1c54345a7ef1a9261962dfefda09e66" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.52", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.90" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b" +checksum = "4f186bd2dcf04330886ce82d6f33dd75a7bfcf69ecf5763b89fcde53b6ac9838" [[package]] name = "web-sys" -version = "0.3.67" +version = "0.3.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58cd2333b6e0be7a39605f0e255892fd7418a682d8da8fe042fe25128794d2ed" +checksum = "96565907687f7aceb35bc5fc03770a8a0471d82e479f25832f54a0e3f4b28446" dependencies = [ "js-sys", "wasm-bindgen", @@ -3739,7 +3746,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.0", + "windows-targets 0.52.4", ] [[package]] @@ -3759,17 +3766,17 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" dependencies = [ - "windows_aarch64_gnullvm 0.52.0", - "windows_aarch64_msvc 0.52.0", - "windows_i686_gnu 0.52.0", - "windows_i686_msvc 0.52.0", - "windows_x86_64_gnu 0.52.0", - "windows_x86_64_gnullvm 0.52.0", - "windows_x86_64_msvc 0.52.0", + "windows_aarch64_gnullvm 0.52.4", + "windows_aarch64_msvc 0.52.4", + "windows_i686_gnu 0.52.4", + "windows_i686_msvc 0.52.4", + "windows_x86_64_gnu 0.52.4", + "windows_x86_64_gnullvm 0.52.4", + "windows_x86_64_msvc 0.52.4", ] [[package]] @@ -3780,9 +3787,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" +checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" [[package]] name = "windows_aarch64_msvc" @@ -3792,9 +3799,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" +checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" [[package]] name = "windows_i686_gnu" @@ -3804,9 +3811,9 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" +checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" [[package]] name = "windows_i686_msvc" @@ -3816,9 +3823,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" +checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" [[package]] name = "windows_x86_64_gnu" @@ -3828,9 +3835,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" +checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" [[package]] name = "windows_x86_64_gnullvm" @@ -3840,9 +3847,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" +checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" [[package]] name = "windows_x86_64_msvc" @@ -3852,15 +3859,15 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" +checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" [[package]] name = "winnow" -version = "0.5.34" +version = "0.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7cf47b659b318dccbd69cc4797a39ae128f533dce7902a1096044d1967b9c16" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" dependencies = [ "memchr", ] @@ -3907,7 +3914,7 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.52", ] [[package]] @@ -3927,7 +3934,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.52", ] [[package]] diff --git a/crates/aiken-lang/src/ast.rs b/crates/aiken-lang/src/ast.rs index 68af1566..faf7ff98 100644 --- a/crates/aiken-lang/src/ast.rs +++ b/crates/aiken-lang/src/ast.rs @@ -183,7 +183,11 @@ pub type UntypedTypeAlias = TypeAlias<()>; impl TypedTest { pub fn test_hint(&self) -> Option<(BinOp, Box, Box)> { - do_test_hint(&self.body) + if self.arguments.is_empty() { + do_test_hint(&self.body) + } else { + None + } } } @@ -367,17 +371,11 @@ pub struct Validator { pub params: Vec>, } -#[derive(Debug, Clone, PartialEq)] -pub struct DefinitionIdentifier { - pub module: Option, - pub name: String, -} - -pub type TypedDefinition = Definition, TypedExpr, String, ()>; -pub type UntypedDefinition = Definition<(), UntypedExpr, (), DefinitionIdentifier>; +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), @@ -388,12 +386,12 @@ pub enum Definition { ModuleConstant(ModuleConstant), - Test(Function>), + Test(Function>), Validator(Validator), } -impl Definition { +impl Definition { pub fn location(&self) -> Span { match self { Definition::Fn(Function { location, .. }) @@ -643,14 +641,14 @@ impl Arg { } } -pub type TypedArgVia = ArgVia, ()>; -pub type UntypedArgVia = ArgVia<(), DefinitionIdentifier>; +pub type TypedArgVia = ArgVia, TypedExpr>; +pub type UntypedArgVia = ArgVia<(), UntypedExpr>; #[derive(Debug, Clone, PartialEq)] -pub struct ArgVia { +pub struct ArgVia { pub arg_name: ArgName, pub location: Span, - pub via: Ann, + pub via: Expr, pub tipo: T, } @@ -666,17 +664,6 @@ impl From> for Arg { } } -impl From for TypedArgVia { - fn from(arg: TypedArg) -> TypedArgVia { - ArgVia { - arg_name: arg.arg_name, - tipo: arg.tipo, - location: arg.location, - via: (), - } - } -} - #[derive(Debug, Clone, PartialEq, Eq)] pub enum ArgName { Discarded { diff --git a/crates/aiken-lang/src/format.rs b/crates/aiken-lang/src/format.rs index 9d3045fb..25caf3ec 100644 --- a/crates/aiken-lang/src/format.rs +++ b/crates/aiken-lang/src/format.rs @@ -1,12 +1,12 @@ use crate::{ ast::{ Annotation, Arg, ArgName, ArgVia, AssignmentKind, BinOp, ByteArrayFormatPreference, - CallArg, ClauseGuard, Constant, CurveType, DataType, Definition, DefinitionIdentifier, - Function, IfBranch, LogicalOpChainKind, ModuleConstant, Pattern, RecordConstructor, - RecordConstructorArg, RecordUpdateSpread, Span, TraceKind, TypeAlias, TypedArg, UnOp, - UnqualifiedImport, UntypedArg, UntypedArgVia, UntypedClause, UntypedClauseGuard, - UntypedDefinition, UntypedFunction, UntypedModule, UntypedPattern, UntypedRecordUpdateArg, - Use, Validator, CAPTURE_VARIABLE, + CallArg, ClauseGuard, Constant, CurveType, DataType, Definition, Function, IfBranch, + LogicalOpChainKind, ModuleConstant, Pattern, RecordConstructor, RecordConstructorArg, + RecordUpdateSpread, Span, TraceKind, TypeAlias, TypedArg, UnOp, UnqualifiedImport, + UntypedArg, UntypedArgVia, UntypedClause, UntypedClauseGuard, UntypedDefinition, + UntypedFunction, UntypedModule, UntypedPattern, UntypedRecordUpdateArg, Use, Validator, + CAPTURE_VARIABLE, }, docvec, expr::{FnStyle, UntypedExpr, DEFAULT_ERROR_STR, DEFAULT_TODO_STR}, @@ -471,19 +471,17 @@ impl<'comments> Formatter<'comments> { commented(doc, comments) } - fn fn_arg_via<'a, A>(&mut self, arg: &'a ArgVia) -> Document<'a> { + fn fn_arg_via<'a, A>(&mut self, arg: &'a ArgVia) -> Document<'a> { let comments = self.pop_comments(arg.location.start); let doc_comments = self.doc_comments(arg.location.start); - let doc = arg.arg_name.to_doc().append(" via "); - - let doc = match arg.via.module { - Some(ref module) => doc.append(module.to_doc()).append("."), - None => doc, - } - .append(arg.via.name.to_doc()) - .group(); + let doc = arg + .arg_name + .to_doc() + .append(" via ") + .append(self.expr(&arg.via, false)) + .group(); let doc = doc_comments.append(doc.group()).group(); diff --git a/crates/aiken-lang/src/gen_uplc.rs b/crates/aiken-lang/src/gen_uplc.rs index 86fbeaeb..63907f47 100644 --- a/crates/aiken-lang/src/gen_uplc.rs +++ b/crates/aiken-lang/src/gen_uplc.rs @@ -198,7 +198,7 @@ impl<'a> CodeGenerator<'a> { self.finalize(term) } - pub fn generate_test(&mut self, test_body: &TypedExpr, module_name: &String) -> Program { + pub fn generate_raw(&mut self, test_body: &TypedExpr, module_name: &String) -> Program { let mut air_tree = self.build(test_body, module_name, &[]); air_tree = AirTree::no_op(air_tree); diff --git a/crates/aiken-lang/src/parser/definition/test.rs b/crates/aiken-lang/src/parser/definition/test.rs index 33d48628..748c187e 100644 --- a/crates/aiken-lang/src/parser/definition/test.rs +++ b/crates/aiken-lang/src/parser/definition/test.rs @@ -3,7 +3,12 @@ use chumsky::prelude::*; use crate::{ ast, expr::UntypedExpr, - parser::{error::ParseError, expr, token::Token}, + parser::{ + chain::{call::parser as call, field_access, tuple_index::parser as tuple_index, Chain}, + error::ParseError, + expr::{self, var}, + token::Token, + }, }; pub fn parser() -> impl Parser { @@ -63,20 +68,33 @@ pub fn via() -> impl Parser { }), )) .then_ignore(just(Token::Via)) - .then( - select! { Token::Name { name } => name } - .then_ignore(just(Token::Dot)) - .or_not(), - ) - .then(select! { Token::Name { name } => name }) - .map_with_span(|((arg_name, module), name), location| ast::ArgVia { + .then(fuzzer()) + .map_with_span(|(arg_name, via), location| ast::ArgVia { arg_name, - via: ast::DefinitionIdentifier { module, name }, + via, tipo: (), location, }) } +pub fn fuzzer<'a>() -> impl Parser + 'a { + recursive(|expression| { + let chain = choice(( + tuple_index(), + field_access::parser(), + call(expression.clone()), + )); + + var() + .then(chain.repeated()) + .foldl(|expr, chain| match chain { + Chain::Call(args, span) => expr.call(args, span), + Chain::FieldAccess(label, span) => expr.field_access(label, span), + Chain::TupleIndex(index, span) => expr.tuple_index(index, span), + }) + }) +} + #[cfg(test)] mod tests { use crate::assert_definition; diff --git a/crates/aiken-lang/src/tipo/infer.rs b/crates/aiken-lang/src/tipo/infer.rs index 106a9aa3..6f76709d 100644 --- a/crates/aiken-lang/src/tipo/infer.rs +++ b/crates/aiken-lang/src/tipo/infer.rs @@ -2,7 +2,7 @@ use std::collections::HashMap; use crate::{ ast::{ - Annotation, Arg, ArgName, DataType, Definition, Function, Layer, ModuleConstant, + Annotation, Arg, ArgName, ArgVia, DataType, Definition, Function, Layer, ModuleConstant, ModuleKind, RecordConstructor, RecordConstructorArg, Tracing, TypeAlias, TypedArg, TypedDefinition, TypedFunction, TypedModule, UntypedArg, UntypedDefinition, UntypedModule, Use, Validator, @@ -383,7 +383,7 @@ fn infer_definition( } } - let annotation = match f.arguments.first() { + let (typed_via, annotation) = match f.arguments.first() { Some(arg) => { if f.arguments.len() > 1 { return Err(Error::IncorrectTestArity { @@ -392,12 +392,17 @@ fn infer_definition( }); } - let ValueConstructor { tipo, .. } = ExprTyper::new(environment, lines, tracing) - .infer_value_constructor(&arg.via.module, &arg.via.name, &arg.location)?; + let typed_via = + ExprTyper::new(environment, lines, tracing).infer(arg.via.clone())?; - Ok(Some(annotate_fuzzer(&tipo, &arg.location)?)) + let tipo = typed_via.tipo(); + + Ok(( + Some(typed_via), + Some(annotate_fuzzer(&tipo, &arg.location)?), + )) } - None => Ok(None), + None => Ok((None, None)), }?; let typed_f = infer_function( @@ -439,13 +444,25 @@ fn infer_definition( location: typed_f.location, name: typed_f.name, public: typed_f.public, - arguments: match annotation { - Some(_) => vec![typed_f - .arguments - .first() - .expect("has exactly one argument") - .to_owned() - .into()], + arguments: match typed_via { + Some(via) => { + let Arg { + arg_name, + location, + tipo, + .. + } = typed_f + .arguments + .first() + .expect("has exactly one argument") + .to_owned(); + vec![ArgVia { + arg_name, + location, + tipo, + via, + }] + } None => vec![], }, return_annotation: typed_f.return_annotation, diff --git a/crates/aiken-project/Cargo.toml b/crates/aiken-project/Cargo.toml index ca52a5d1..9ada572f 100644 --- a/crates/aiken-project/Cargo.toml +++ b/crates/aiken-project/Cargo.toml @@ -43,6 +43,7 @@ zip = "0.6.4" aiken-lang = { path = "../aiken-lang", version = "1.0.24-alpha" } uplc = { path = '../uplc', version = "1.0.24-alpha" } +num-bigint = "0.4.4" [dev-dependencies] blst = "0.3.11" diff --git a/crates/aiken-project/src/lib.rs b/crates/aiken-project/src/lib.rs index e1112b46..d7199e6c 100644 --- a/crates/aiken-project/src/lib.rs +++ b/crates/aiken-project/src/lib.rs @@ -22,10 +22,13 @@ use crate::blueprint::{ Blueprint, }; use aiken_lang::{ - ast::{Definition, Function, ModuleKind, Tracing, TypedDataType, TypedFunction, Validator}, + ast::{ + Definition, Function, ModuleKind, Span, Tracing, TypedDataType, TypedFunction, Validator, + }, builtins, - gen_uplc::builder::{DataTypeKey, FunctionAccessKey}, - tipo::TypeInfo, + expr::TypedExpr, + gen_uplc::builder::{cast_validator_args, DataTypeKey, FunctionAccessKey}, + tipo::{Type, TypeInfo}, IdGenerator, }; use indexmap::IndexMap; @@ -38,16 +41,17 @@ use pallas::ledger::{ traverse::ComputeHash, }; -use script::{EvalHint, EvalInfo, Script}; +use script::{EvalHint, EvalInfo, PropertyTest, Test}; use std::{ collections::HashMap, fs::{self, File}, io::BufReader, path::{Path, PathBuf}, + rc::Rc, }; use telemetry::EventListener; use uplc::{ - ast::{DeBruijn, Name, Program, Term}, + ast::{DeBruijn, Name, NamedDeBruijn, Program, Term}, machine::cost_model::ExBudget, PlutusData, }; @@ -319,7 +323,7 @@ where self.event_listener.handle_event(Event::RunningTests); } - let results = self.eval_scripts(tests); + let results = self.run_tests(tests.iter().collect()); let errors: Vec = results .iter() @@ -328,14 +332,13 @@ where None } else { Some(Error::TestFailure { - name: e.script.name.clone(), - path: e.script.input_path.clone(), + name: e.test.name().to_string(), + path: e.test.input_path().to_path_buf(), evaluation_hint: e - .script - .evaluation_hint - .as_ref() + .test + .evaluation_hint() .map(|hint| hint.to_string()), - src: e.script.program.to_pretty(), + src: e.test.program().to_pretty(), verbose, }) } @@ -684,7 +687,7 @@ where match_tests: Option>, exact_match: bool, tracing: Tracing, - ) -> Result, Error> { + ) -> Result, Error> { let mut scripts = Vec::new(); let mut testable_validators = Vec::new(); @@ -802,6 +805,7 @@ where name, body, can_error, + arguments, .. } = func_def; @@ -815,13 +819,13 @@ where let evaluation_hint = func_def.test_hint().map(|(bin_op, left_src, right_src)| { let left = generator .clone() - .generate_test(&left_src, &module_name) + .generate_raw(&left_src, &module_name) .try_into() .unwrap(); let right = generator .clone() - .generate_test(&right_src, &module_name) + .generate_raw(&right_src, &module_name) .try_into() .unwrap(); @@ -833,44 +837,91 @@ where } }); - let program = generator.generate_test(body, &module_name); + if arguments.is_empty() { + let program = generator.generate_raw(body, &module_name); - let script = Script::new( - input_path, - module_name, - name.to_string(), - *can_error, - program.try_into().unwrap(), - evaluation_hint, - ); + let test = Test::unit_test( + input_path, + module_name, + name.to_string(), + *can_error, + program.try_into().unwrap(), + evaluation_hint, + ); - programs.push(script); + programs.push(test); + } else { + let parameter = arguments.first().unwrap().to_owned(); + + let via = parameter.via.clone(); + + let body = TypedExpr::Fn { + location: Span::empty(), + tipo: Rc::new(Type::Fn { + args: vec![parameter.tipo.clone()], + ret: body.tipo(), + }), + is_capture: false, + args: vec![parameter.clone().into()], + body: Box::new(body.clone()), + return_annotation: None, + }; + + let program = generator.clone().generate_raw(&body, &module_name); + + let term = cast_validator_args(program.term, &[parameter.into()]); + + let fuzzer: Program = generator + .clone() + .generate_raw(&via, &module_name) + .try_into() + .expect("TODO: provide a better error when one is trying to instantiate something that isn't a fuzzer as one"); + + let prop = Test::property_test( + input_path, + module_name, + name.to_string(), + *can_error, + Program { term, ..program }.try_into().unwrap(), + fuzzer, + ); + + programs.push(prop); + } } Ok(programs) } - fn eval_scripts(&self, scripts: Vec