From 30a6b77116950e8b15381dc78be3b31eec695a41 Mon Sep 17 00:00:00 2001 From: KtorZ Date: Thu, 4 Jan 2024 17:59:15 +0100 Subject: [PATCH] Get rid of 'VoidMsg' in favor of an 'Option'. --- crates/aiken-lang/src/gen_uplc.rs | 61 ++++++++++++------- crates/aiken-lang/src/gen_uplc/builder.rs | 4 +- crates/aiken-lang/src/gen_uplc/tree.rs | 74 ++++++++++++++--------- 3 files changed, 86 insertions(+), 53 deletions(-) diff --git a/crates/aiken-lang/src/gen_uplc.rs b/crates/aiken-lang/src/gen_uplc.rs index 4aa2ad29..d1d3369d 100644 --- a/crates/aiken-lang/src/gen_uplc.rs +++ b/crates/aiken-lang/src/gen_uplc.rs @@ -479,9 +479,9 @@ impl<'a> CodeGenerator<'a> { ); let msg_func = if self.tracing && kind.is_expect() { - self.special_functions.use_function_msg(msg_func_name) + Some(self.special_functions.use_function_msg(msg_func_name)) } else { - AirMsg::Void + None }; self.assignment( @@ -534,7 +534,7 @@ impl<'a> CodeGenerator<'a> { kind: AssignmentKind::Let, remove_unused: false, full_check: false, - msg_func: AirMsg::Void, + msg_func: None, }, ); @@ -1027,7 +1027,8 @@ impl<'a> CodeGenerator<'a> { tipo.clone(), tail.is_some(), value, - Some(props.msg_func), + props.msg_func, + true, ) }; @@ -1180,12 +1181,12 @@ impl<'a> CodeGenerator<'a> { if check_replaceable_opaque_type(tipo, &self.data_types) { sequence.push(AirTree::let_assignment(&indices[0].1, value)); } else { - let msg = if props.full_check { - Some(props.msg_func) + let (is_expect, msg) = if props.full_check { + (true, props.msg_func) } else { - None + (false, None) }; - sequence.push(AirTree::fields_expose(indices, value, msg)); + sequence.push(AirTree::fields_expose(indices, value, msg, is_expect)); } sequence.append( @@ -1266,15 +1267,21 @@ impl<'a> CodeGenerator<'a> { let indices = elems.iter().map(|(name, _)| name.to_string()).collect_vec(); - let msg = if props.full_check { - Some(props.msg_func) + let (is_expect, msg) = if props.full_check { + (true, props.msg_func) } else { - None + (false, None) }; // This `value` is either value param that was passed in or // local var - sequence.push(AirTree::tuple_access(indices, tipo.clone(), value, msg)); + sequence.push(AirTree::tuple_access( + indices, + tipo.clone(), + value, + msg, + is_expect, + )); sequence.append(&mut elems.into_iter().map(|(_, field)| field).collect_vec()); @@ -1289,7 +1296,7 @@ impl<'a> CodeGenerator<'a> { value: AirTree, defined_data_types: &mut IndexMap, location: Span, - msg_func: AirMsg, + msg_func: Option, ) -> AirTree { assert!(tipo.get_generic().is_none()); let tipo = &convert_opaque_type(tipo, &self.data_types); @@ -1317,6 +1324,7 @@ impl<'a> CodeGenerator<'a> { inner_list_type.clone(), AirTree::local_var(&pair_name, inner_list_type.clone()), None, + false, ); let expect_fst = self.expect_type_assign( @@ -1469,6 +1477,7 @@ impl<'a> CodeGenerator<'a> { tipo.clone(), AirTree::local_var(pair_name, tipo.clone()), None, + false, ); let expect_fst = self.expect_type_assign( @@ -1534,7 +1543,8 @@ impl<'a> CodeGenerator<'a> { tuple_index_names, tipo.clone(), AirTree::local_var(tuple_name, tipo.clone()), - Some(msg_func), + msg_func, + true, ); let mut tuple_expects = tuple_expect_items @@ -1580,15 +1590,15 @@ impl<'a> CodeGenerator<'a> { let msg = AirMsg::LocalVar("__param_msg".to_string()); ( - msg.clone(), + Some(msg.clone()), AirTree::trace( - msg.to_air_tree().unwrap(), + msg.to_air_tree(), tipo.clone(), AirTree::error(tipo.clone(), false), ), ) } else { - (msg_func.clone(), AirTree::error(tipo.clone(), false)) + (None, AirTree::error(tipo.clone(), false)) }; defined_data_types.insert(data_type_name.clone(), 1); @@ -1659,7 +1669,8 @@ impl<'a> CodeGenerator<'a> { ), tipo.clone(), ), - Some(msg_term.clone()), + msg_term.clone(), + true, ); assigns.insert(0, expose); @@ -1727,7 +1738,12 @@ impl<'a> CodeGenerator<'a> { } let args = if self.tracing { - vec![value, msg_func.to_air_tree().unwrap()] + vec![ + value, + msg_func + .expect("should be unreachable: no msg func with tracing enabled.") + .to_air_tree(), + ] } else { vec![value] }; @@ -2255,6 +2271,7 @@ impl<'a> CodeGenerator<'a> { // So for the msg we pass in empty string if tracing is on // Since check_last_item is false this will never get added to the final uplc anyway None, + false, ) } else { assert!(defined_tails.len() >= defined_heads.len()); @@ -2398,6 +2415,7 @@ impl<'a> CodeGenerator<'a> { subject_tipo.clone(), ), None, + false, ) }; @@ -2532,6 +2550,7 @@ impl<'a> CodeGenerator<'a> { subject_tipo.clone(), AirTree::local_var(&props.original_subject_name, subject_tipo.clone()), None, + false, ), ); } @@ -2744,9 +2763,9 @@ impl<'a> CodeGenerator<'a> { ); let msg_func = if self.tracing && !actual_type.is_data() { - self.special_functions.use_function_msg(msg_func_name) + Some(self.special_functions.use_function_msg(msg_func_name)) } else { - AirMsg::Void + None }; let assign = self.assignment( diff --git a/crates/aiken-lang/src/gen_uplc/builder.rs b/crates/aiken-lang/src/gen_uplc/builder.rs index 41110b72..a5ea8a52 100644 --- a/crates/aiken-lang/src/gen_uplc/builder.rs +++ b/crates/aiken-lang/src/gen_uplc/builder.rs @@ -85,7 +85,7 @@ pub struct AssignmentProperties { pub kind: AssignmentKind, pub remove_unused: bool, pub full_check: bool, - pub msg_func: AirMsg, + pub msg_func: Option, } #[derive(Clone, Debug)] @@ -1753,7 +1753,7 @@ pub fn wrap_as_multi_validator( ) -> Term { if trace { let trace_string = format!( - "Incorrect redeemer type for validator {}. + "Incorrect redeemer type for validator {}. Double check you have wrapped the redeemer type as specified in your plutus.json", spend_name ); diff --git a/crates/aiken-lang/src/gen_uplc/tree.rs b/crates/aiken-lang/src/gen_uplc/tree.rs index c4f391c6..d2e7d290 100644 --- a/crates/aiken-lang/src/gen_uplc/tree.rs +++ b/crates/aiken-lang/src/gen_uplc/tree.rs @@ -92,17 +92,15 @@ impl Default for IndexCounter { #[derive(Debug, Clone, PartialEq)] pub enum AirMsg { - Void, LocalVar(String), Msg(String), } impl AirMsg { - pub fn to_air_tree(&self) -> Option { + pub fn to_air_tree(&self) -> AirTree { match self { - AirMsg::Void => None, - AirMsg::LocalVar(name) => Some(AirTree::local_var(name, string())), - AirMsg::Msg(msg) => Some(AirTree::string(msg)), + AirMsg::LocalVar(name) => AirTree::local_var(name, string()), + AirMsg::Msg(msg) => AirTree::string(msg), } } } @@ -144,12 +142,12 @@ pub enum AirStatement { AssertConstr { constr_index: usize, constr: Box, - msg: AirMsg, + msg: Option, }, AssertBool { is_true: bool, value: Box, - msg: AirMsg, + msg: Option, }, // Clause Guards ClauseGuard { @@ -172,6 +170,7 @@ pub enum AirStatement { FieldsExpose { indices: Vec<(usize, String, Rc)>, record: Box, + is_expect: bool, msg: Option, }, // List Access @@ -180,6 +179,7 @@ pub enum AirStatement { names: Vec, tail: bool, list: Box, + is_expect: bool, msg: Option, }, ListExpose { @@ -192,16 +192,17 @@ pub enum AirStatement { names: Vec, tipo: Rc, tuple: Box, + is_expect: bool, msg: Option, }, // Misc. FieldsEmpty { constr: Box, - msg: AirMsg, + msg: Option, }, ListEmpty { list: Box, - msg: AirMsg, + msg: Option, }, NoOp, } @@ -513,7 +514,11 @@ impl AirTree { value: value.into(), }) } - pub fn assert_constr_index(constr_index: usize, constr: AirTree, msg: AirMsg) -> AirTree { + pub fn assert_constr_index( + constr_index: usize, + constr: AirTree, + msg: Option, + ) -> AirTree { AirTree::Statement { statement: AirStatement::AssertConstr { constr_index, @@ -523,7 +528,7 @@ impl AirTree { hoisted_over: None, } } - pub fn assert_bool(is_true: bool, value: AirTree, msg: AirMsg) -> AirTree { + pub fn assert_bool(is_true: bool, value: AirTree, msg: Option) -> AirTree { AirTree::Statement { statement: AirStatement::AssertBool { is_true, @@ -735,12 +740,14 @@ impl AirTree { indices: Vec<(usize, String, Rc)>, record: AirTree, msg: Option, + is_expect: bool, ) -> AirTree { AirTree::Statement { statement: AirStatement::FieldsExpose { indices, record: record.into(), msg, + is_expect, }, hoisted_over: None, } @@ -751,6 +758,7 @@ impl AirTree { tail: bool, list: AirTree, msg: Option, + is_expect: bool, ) -> AirTree { AirTree::Statement { statement: AirStatement::ListAccessor { @@ -758,6 +766,7 @@ impl AirTree { names, tail, list: list.into(), + is_expect, msg, }, hoisted_over: None, @@ -782,6 +791,7 @@ impl AirTree { tipo: Rc, tuple: AirTree, msg: Option, + is_expect: bool, ) -> AirTree { AirTree::Statement { statement: AirStatement::TupleAccessor { @@ -789,6 +799,7 @@ impl AirTree { tipo, tuple: tuple.into(), msg, + is_expect, }, hoisted_over: None, } @@ -823,7 +834,7 @@ impl AirTree { hoisted_over: None, } } - pub fn fields_empty(constr: AirTree, msg: AirMsg) -> AirTree { + pub fn fields_empty(constr: AirTree, msg: Option) -> AirTree { AirTree::Statement { statement: AirStatement::FieldsEmpty { constr: constr.into(), @@ -832,7 +843,7 @@ impl AirTree { hoisted_over: None, } } - pub fn list_empty(list: AirTree, msg: AirMsg) -> AirTree { + pub fn list_empty(list: AirTree, msg: Option) -> AirTree { AirTree::Statement { statement: AirStatement::ListEmpty { list: list.into(), @@ -980,8 +991,8 @@ impl AirTree { // msg is first so we can pop it off first in uplc_gen // if traces are on - if let Some(msg) = msg.to_air_tree() { - msg.create_air_vec(air_vec); + if let Some(msg) = msg { + msg.to_air_tree().create_air_vec(air_vec); } constr.create_air_vec(air_vec); @@ -993,8 +1004,8 @@ impl AirTree { } => { air_vec.push(Air::AssertBool { is_true: *is_true }); - if let Some(msg) = msg.to_air_tree() { - msg.create_air_vec(air_vec); + if let Some(msg) = msg { + msg.to_air_tree().create_air_vec(air_vec); } value.create_air_vec(air_vec); @@ -1039,14 +1050,15 @@ impl AirTree { indices, record, msg, + is_expect, } => { air_vec.push(Air::FieldsExpose { indices: indices.clone(), - is_expect: msg.is_some(), + is_expect: *is_expect, }); - if let Some(msg) = msg.as_ref().and_then(|item| item.to_air_tree()) { - msg.create_air_vec(air_vec); + if let Some(msg) = msg { + msg.to_air_tree().create_air_vec(air_vec); } record.create_air_vec(air_vec); @@ -1057,16 +1069,17 @@ impl AirTree { tail, list, msg, + is_expect, } => { air_vec.push(Air::ListAccessor { tipo: tipo.clone(), names: names.clone(), tail: *tail, - is_expect: msg.is_some(), + is_expect: *is_expect, }); - if let Some(msg) = msg.as_ref().and_then(|item| item.to_air_tree()) { - msg.create_air_vec(air_vec); + if let Some(msg) = msg { + msg.to_air_tree().create_air_vec(air_vec); } list.create_air_vec(air_vec); @@ -1087,15 +1100,16 @@ impl AirTree { tipo, tuple, msg, + is_expect, } => { air_vec.push(Air::TupleAccessor { names: names.clone(), tipo: tipo.clone(), - is_expect: msg.is_some(), + is_expect: *is_expect, }); - if let Some(msg) = msg.as_ref().and_then(|item| item.to_air_tree()) { - msg.create_air_vec(air_vec); + if let Some(msg) = msg { + msg.to_air_tree().create_air_vec(air_vec); } tuple.create_air_vec(air_vec); @@ -1106,8 +1120,8 @@ impl AirTree { AirStatement::FieldsEmpty { constr, msg } => { air_vec.push(Air::FieldsEmpty); - if let Some(msg) = msg.to_air_tree() { - msg.create_air_vec(air_vec); + if let Some(msg) = msg { + msg.to_air_tree().create_air_vec(air_vec); } constr.create_air_vec(air_vec); @@ -1115,8 +1129,8 @@ impl AirTree { AirStatement::ListEmpty { list, msg } => { air_vec.push(Air::ListEmpty); - if let Some(msg) = msg.to_air_tree() { - msg.create_air_vec(air_vec); + if let Some(msg) = msg { + msg.to_air_tree().create_air_vec(air_vec); } list.create_air_vec(air_vec);