From a9d782e2063952b38342a1ec46d587430ecd1a45 Mon Sep 17 00:00:00 2001 From: KtorZ Date: Fri, 19 Jul 2024 09:40:05 +0200 Subject: [PATCH] re-introduce code-gen patch, but with a test. Actually, this has been a bug for a long time it seems. Calling any prelude functions using a qualified import would result in a codegen crash. Whoopsie. This is now fixed as shown by the regression test. --- crates/aiken-lang/src/gen_uplc.rs | 16 ++++++++++++++-- crates/aiken-project/src/tests/gen_uplc.rs | 22 ++++++++++++++++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/crates/aiken-lang/src/gen_uplc.rs b/crates/aiken-lang/src/gen_uplc.rs index 82f1cbae..707ff3e5 100644 --- a/crates/aiken-lang/src/gen_uplc.rs +++ b/crates/aiken-lang/src/gen_uplc.rs @@ -17,7 +17,7 @@ use crate::{ Span, TraceLevel, Tracing, TypedArg, TypedClause, TypedDataType, TypedFunction, TypedPattern, TypedValidator, UnOp, }, - builtins::{bool, data, int, list, void}, + builtins::{bool, data, int, list, void, PRELUDE}, expr::TypedExpr, gen_uplc::{ air::ExpectLevel, @@ -748,7 +748,19 @@ impl<'a> CodeGenerator<'a> { } ModuleValueConstructor::Fn { name, module, .. } => { let func = self.functions.get(&FunctionAccessKey { - module_name: module_name.clone(), + // NOTE: This is needed because we register prelude functions under an + // empty module name. This is to facilitate their access when used + // directly. Note that, if we weren't doing this particular + // transformation, we would need to do the other direction anyway: + // + // if module_name.is_empty() { PRELUDE.to_string() } else { module_name.clone() } + // + // So either way, we need to take care of this. + module_name: if module_name == PRELUDE { + String::new() + } else { + module_name.clone() + }, function_name: name.clone(), }); diff --git a/crates/aiken-project/src/tests/gen_uplc.rs b/crates/aiken-project/src/tests/gen_uplc.rs index 20c88855..0019836e 100644 --- a/crates/aiken-project/src/tests/gen_uplc.rs +++ b/crates/aiken-project/src/tests/gen_uplc.rs @@ -7003,3 +7003,25 @@ fn bls12_381_elements_from_data_conversion() { false, ) } + +#[test] +fn qualified_prelude_functions() { + let src = r#" + use aiken + + test foo() { + aiken.identity(True) && identity(True) + } + "#; + + let constant_true = Term::Constant(Constant::Bool(true).into()); + let constant_false = Term::Constant(Constant::Bool(false).into()); + + assert_uplc( + src, + constant_true + .clone() + .delayed_if_then_else(constant_true, constant_false), + false, + ) +}