From 41b941e0e3154c673309af8a779e220fc79b1b24 Mon Sep 17 00:00:00 2001 From: microproofs Date: Thu, 13 Jun 2024 14:06:11 -0400 Subject: [PATCH] Fix castfromData in record access cases --- crates/aiken-lang/src/gen_uplc.rs | 18 ++++++++++++++---- crates/aiken-lang/src/gen_uplc/air.rs | 1 + crates/aiken-lang/src/gen_uplc/tree.rs | 21 ++++++++++++++++++--- 3 files changed, 33 insertions(+), 7 deletions(-) diff --git a/crates/aiken-lang/src/gen_uplc.rs b/crates/aiken-lang/src/gen_uplc.rs index f90a8324..52f0c46d 100644 --- a/crates/aiken-lang/src/gen_uplc.rs +++ b/crates/aiken-lang/src/gen_uplc.rs @@ -901,7 +901,7 @@ impl<'a> CodeGenerator<'a> { // Cast value to or from data so we don't have to worry from this point onward if props.value_type.is_data() && props.kind.is_expect() && !tipo.is_data() { - value = AirTree::cast_from_data(value, tipo.clone(), props.otherwise.clone()); + value = AirTree::cast_from_data(value, tipo.clone(), props.otherwise.clone(), true); } else if !props.value_type.is_data() && tipo.is_data() { value = AirTree::cast_to_data(value, props.value_type.clone()); } @@ -1648,6 +1648,7 @@ impl<'a> CodeGenerator<'a> { AirTree::local_var(&item_name, data()), inner_list_type.clone(), otherwise.clone(), + true, ), defined_data_types, location, @@ -4766,11 +4767,20 @@ impl<'a> CodeGenerator<'a> { Some(term) } - Air::CastFromData { tipo, .. } => { + Air::CastFromData { tipo, full_cast } => { let mut term = arg_stack.pop().unwrap(); - let otherwise = arg_stack.pop().unwrap(); - term = convert_data_to_type(term, &tipo, otherwise); + let otherwise = if full_cast { + arg_stack.pop().unwrap() + } else { + Term::Error + }; + + term = if full_cast { + convert_data_to_type(term, &tipo, otherwise) + } else { + known_data_to_type(term, &tipo) + }; if extract_constant(&term).is_some() { let mut program: Program = Program { diff --git a/crates/aiken-lang/src/gen_uplc/air.rs b/crates/aiken-lang/src/gen_uplc/air.rs index 327da0c7..56b1a72e 100644 --- a/crates/aiken-lang/src/gen_uplc/air.rs +++ b/crates/aiken-lang/src/gen_uplc/air.rs @@ -102,6 +102,7 @@ pub enum Air { }, CastFromData { tipo: Rc, + full_cast: bool, }, CastToData { tipo: Rc, diff --git a/crates/aiken-lang/src/gen_uplc/tree.rs b/crates/aiken-lang/src/gen_uplc/tree.rs index 5e3b0dc7..51a6b3c0 100644 --- a/crates/aiken-lang/src/gen_uplc/tree.rs +++ b/crates/aiken-lang/src/gen_uplc/tree.rs @@ -298,6 +298,7 @@ pub enum AirTree { tipo: Rc, value: Box, otherwise: Box, + full_cast: bool, }, CastToData { tipo: Rc, @@ -566,11 +567,17 @@ impl AirTree { } } - pub fn cast_from_data(value: AirTree, tipo: Rc, otherwise: AirTree) -> AirTree { + pub fn cast_from_data( + value: AirTree, + tipo: Rc, + otherwise: AirTree, + full_cast: bool, + ) -> AirTree { AirTree::CastFromData { tipo, value: value.into(), otherwise: otherwise.into(), + full_cast, } } @@ -837,6 +844,7 @@ impl AirTree { ), tipo.clone(), AirTree::error(void(), false), + false, ) } @@ -942,6 +950,7 @@ impl AirTree { ), tipo.clone(), AirTree::error(void(), false), + false, ) } @@ -1406,11 +1415,17 @@ impl AirTree { tipo, value, otherwise, + full_cast, } => { - air_vec.push(Air::CastFromData { tipo: tipo.clone() }); + air_vec.push(Air::CastFromData { + tipo: tipo.clone(), + full_cast: *full_cast, + }); value.create_air_vec(air_vec); - otherwise.create_air_vec(air_vec); + if *full_cast { + otherwise.create_air_vec(air_vec); + } } AirTree::CastToData { tipo, value } => { air_vec.push(Air::CastToData { tipo: tipo.clone() });