Fix unwrap issues
This commit is contained in:
parent
93a141bfa4
commit
a132a2e486
|
@ -354,9 +354,29 @@ pub fn erase_opaque_type_operations(
|
||||||
pub fn find_introduced_variables(air_tree: &AirTree) -> Vec<String> {
|
pub fn find_introduced_variables(air_tree: &AirTree) -> Vec<String> {
|
||||||
match air_tree {
|
match air_tree {
|
||||||
AirTree::Let { name, .. } => vec![name.clone()],
|
AirTree::Let { name, .. } => vec![name.clone()],
|
||||||
|
AirTree::SoftCastLet { name, .. } => vec![name.clone()],
|
||||||
AirTree::TupleGuard { indices, .. } | AirTree::TupleClause { indices, .. } => {
|
AirTree::TupleGuard { indices, .. } | AirTree::TupleClause { indices, .. } => {
|
||||||
indices.iter().map(|(_, name)| name.clone()).collect()
|
indices.iter().map(|(_, name)| name.clone()).collect()
|
||||||
}
|
}
|
||||||
|
AirTree::PairGuard {
|
||||||
|
fst_name, snd_name, ..
|
||||||
|
} => fst_name
|
||||||
|
.into_iter()
|
||||||
|
.cloned()
|
||||||
|
.chain(snd_name.into_iter().cloned())
|
||||||
|
.collect_vec(),
|
||||||
|
AirTree::PairAccessor { fst, snd, .. } => fst
|
||||||
|
.into_iter()
|
||||||
|
.cloned()
|
||||||
|
.chain(snd.into_iter().cloned())
|
||||||
|
.collect_vec(),
|
||||||
|
AirTree::PairClause {
|
||||||
|
fst_name, snd_name, ..
|
||||||
|
} => fst_name
|
||||||
|
.into_iter()
|
||||||
|
.cloned()
|
||||||
|
.chain(snd_name.into_iter().cloned())
|
||||||
|
.collect_vec(),
|
||||||
AirTree::Fn { params, .. } => params.to_vec(),
|
AirTree::Fn { params, .. } => params.to_vec(),
|
||||||
AirTree::ListAccessor { names, .. } => names.clone(),
|
AirTree::ListAccessor { names, .. } => names.clone(),
|
||||||
AirTree::ListExpose {
|
AirTree::ListExpose {
|
||||||
|
@ -913,17 +933,7 @@ pub fn unknown_data_to_type(term: Term<Name>, field_type: &Type) -> Term<Name> {
|
||||||
.lambda("__list_data")
|
.lambda("__list_data")
|
||||||
.apply(Term::unlist_data().apply(term)),
|
.apply(Term::unlist_data().apply(term)),
|
||||||
Some(UplcType::Bool) => Term::unwrap_bool_or(term, |result| result, &Term::Error.delay()),
|
Some(UplcType::Bool) => Term::unwrap_bool_or(term, |result| result, &Term::Error.delay()),
|
||||||
Some(UplcType::Unit) => Term::equals_integer()
|
Some(UplcType::Unit) => Term::unwrap_void_or(term, |result| result, &Term::Error.delay()),
|
||||||
.apply(Term::integer(0.into()))
|
|
||||||
.apply(Term::fst_pair().apply(Term::var("__pair__")))
|
|
||||||
.delayed_if_then_else(
|
|
||||||
Term::snd_pair()
|
|
||||||
.apply(Term::var("__pair__"))
|
|
||||||
.delayed_choose_list(Term::unit(), Term::Error),
|
|
||||||
Term::Error,
|
|
||||||
)
|
|
||||||
.lambda("__pair__")
|
|
||||||
.apply(Term::unconstr_data().apply(term)),
|
|
||||||
|
|
||||||
Some(UplcType::Data) | None => term,
|
Some(UplcType::Data) | None => term,
|
||||||
}
|
}
|
||||||
|
@ -948,7 +958,7 @@ pub fn softcast_data_to_type_otherwise(
|
||||||
value.as_var("__val", |val| match uplc_type {
|
value.as_var("__val", |val| match uplc_type {
|
||||||
None => Term::choose_data_constr(val, then_delayed, &otherwise_delayed).force(),
|
None => Term::choose_data_constr(val, then_delayed, &otherwise_delayed).force(),
|
||||||
|
|
||||||
Some(UplcType::Data) => just_then,
|
Some(UplcType::Data) => just_then.lambda(name).apply(Term::Var(val)),
|
||||||
|
|
||||||
Some(UplcType::Bls12_381MlResult) => {
|
Some(UplcType::Bls12_381MlResult) => {
|
||||||
unreachable!("attempted to cast Data into Bls12_381MlResult ?!")
|
unreachable!("attempted to cast Data into Bls12_381MlResult ?!")
|
||||||
|
@ -1343,9 +1353,9 @@ pub fn list_access_to_uplc(
|
||||||
&tail_name,
|
&tail_name,
|
||||||
acc.apply(
|
acc.apply(
|
||||||
Term::tail_list().apply(Term::var(tail_name.to_string())),
|
Term::tail_list().apply(Term::var(tail_name.to_string())),
|
||||||
)
|
),
|
||||||
.delay(),
|
)
|
||||||
),
|
.delay(),
|
||||||
)
|
)
|
||||||
.force()
|
.force()
|
||||||
.lambda(tail_name)
|
.lambda(tail_name)
|
||||||
|
|
|
@ -8,7 +8,10 @@ use crate::{
|
||||||
use indexmap::IndexSet;
|
use indexmap::IndexSet;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use std::{borrow::BorrowMut, rc::Rc, slice::Iter};
|
use std::{borrow::BorrowMut, rc::Rc, slice::Iter};
|
||||||
use uplc::{builder::EXPECT_ON_LIST, builtins::DefaultFunction};
|
use uplc::{
|
||||||
|
builder::{EXPECT_ON_LIST, INNER_EXPECT_ON_LIST},
|
||||||
|
builtins::DefaultFunction,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Copy)]
|
#[derive(Clone, Debug, PartialEq, Copy)]
|
||||||
pub enum Fields {
|
pub enum Fields {
|
||||||
|
@ -1037,28 +1040,36 @@ impl AirTree {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn expect_on_list2() -> AirTree {
|
pub fn expect_on_list2() -> AirTree {
|
||||||
let expect_on_list = AirTree::var(
|
let inner_expect_on_list = AirTree::local_var(INNER_EXPECT_ON_LIST, void());
|
||||||
ValueConstructor::public(
|
|
||||||
void(),
|
|
||||||
ValueConstructorVariant::ModuleFn {
|
|
||||||
name: EXPECT_ON_LIST.to_string(),
|
|
||||||
field_map: None,
|
|
||||||
module: "".to_string(),
|
|
||||||
arity: 1,
|
|
||||||
location: Span::empty(),
|
|
||||||
builtin: None,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
EXPECT_ON_LIST,
|
|
||||||
"",
|
|
||||||
);
|
|
||||||
|
|
||||||
let list_var = AirTree::local_var("__list_to_check", list(data()));
|
let list_var = AirTree::local_var("__list_to_check", list(data()));
|
||||||
|
|
||||||
AirTree::call(
|
AirTree::let_assignment(
|
||||||
AirTree::local_var("__check_with", void()),
|
INNER_EXPECT_ON_LIST,
|
||||||
void(),
|
AirTree::anon_func(
|
||||||
vec![list_var, expect_on_list],
|
vec![
|
||||||
|
INNER_EXPECT_ON_LIST.to_string(),
|
||||||
|
"__list_to_check".to_string(),
|
||||||
|
],
|
||||||
|
AirTree::call(
|
||||||
|
AirTree::local_var("__check_with", void()),
|
||||||
|
void(),
|
||||||
|
vec![
|
||||||
|
list_var.clone(),
|
||||||
|
AirTree::call(
|
||||||
|
inner_expect_on_list.clone(),
|
||||||
|
void(),
|
||||||
|
vec![inner_expect_on_list.clone()],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
AirTree::call(
|
||||||
|
inner_expect_on_list.clone(),
|
||||||
|
void(),
|
||||||
|
vec![inner_expect_on_list, list_var],
|
||||||
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5221,6 +5221,7 @@ fn expect_head3_cast_data_no_tail() {
|
||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn expect_head_cast_data_no_tail() {
|
fn expect_head_cast_data_no_tail() {
|
||||||
let src = r#"
|
let src = r#"
|
||||||
|
@ -5309,131 +5310,143 @@ fn expect_head_cast_data_with_tail() {
|
||||||
|
|
||||||
assert_uplc(
|
assert_uplc(
|
||||||
src,
|
src,
|
||||||
Term::var("unwrap_a")
|
Term::var("__val")
|
||||||
.choose_list(
|
.choose_data(
|
||||||
Term::var("expect[h,j,..]:List<Int>=a"),
|
Term::var("expect[h,j,..]:List<Int>=a"),
|
||||||
Term::var("tail_1")
|
Term::var("expect[h,j,..]:List<Int>=a"),
|
||||||
.choose_list(
|
Term::list_values(vec![
|
||||||
Term::var("expect[h,j,..]:List<Int>=a"),
|
Constant::Data(Data::integer(1.into())),
|
||||||
Term::equals_integer()
|
Constant::Data(Data::integer(2.into())),
|
||||||
.apply(Term::var("h"))
|
Constant::Data(Data::integer(3.into())),
|
||||||
.apply(Term::var("h"))
|
])
|
||||||
.delayed_if_then_else(
|
.choose_list(
|
||||||
Term::equals_integer()
|
Term::var("expect[h,j,..]:List<Int>=a"),
|
||||||
.apply(Term::var("j"))
|
Term::var("__val")
|
||||||
.apply(Term::var("j")),
|
.choose_data(
|
||||||
Term::bool(false),
|
Term::var("expect[h,j,..]:List<Int>=a"),
|
||||||
)
|
Term::var("expect[h,j,..]:List<Int>=a"),
|
||||||
.lambda("_")
|
Term::var("expect[h,j,..]:List<Int>=a"),
|
||||||
.apply(
|
Term::var("tail_1")
|
||||||
Term::var("expect_on_list")
|
.choose_list(
|
||||||
.lambda("expect_on_list")
|
Term::var("expect[h,j,..]:List<Int>=a"),
|
||||||
.apply(
|
Term::var("__val")
|
||||||
Term::var("expect_on_list")
|
.choose_data(
|
||||||
.apply(Term::var("expect_on_list"))
|
Term::var("expect[h,j,..]:List<Int>=a"),
|
||||||
.apply(Term::var("list_to_check"))
|
Term::var("expect[h,j,..]:List<Int>=a"),
|
||||||
.lambda("expect_on_list")
|
Term::var("expect[h,j,..]:List<Int>=a"),
|
||||||
.apply(
|
Term::var("expect_on_list")
|
||||||
Term::var("list_to_check")
|
.apply(Term::tail_list().apply(Term::var("tail_2")))
|
||||||
.delayed_choose_list(
|
.apply(
|
||||||
Term::unit(),
|
Term::var("__list")
|
||||||
Term::var("expect_on_list")
|
.choose_list(
|
||||||
.apply(Term::var("expect_on_list"))
|
Term::equals_integer()
|
||||||
.apply(
|
.apply(Term::var("h"))
|
||||||
Term::tail_list().apply(Term::var(
|
.apply(Term::var("h"))
|
||||||
"list_to_check",
|
.delayed_if_then_else(
|
||||||
)),
|
Term::equals_integer()
|
||||||
|
.apply(Term::var("j"))
|
||||||
|
.apply(Term::var("j")),
|
||||||
|
Term::bool(false),
|
||||||
|
),
|
||||||
|
Term::var("__head").choose_data(
|
||||||
|
Term::var(
|
||||||
|
"expect[h,j,..]:List<Int>=a",
|
||||||
|
),
|
||||||
|
Term::var(
|
||||||
|
"expect[h,j,..]:List<Int>=a",
|
||||||
|
),
|
||||||
|
Term::var(
|
||||||
|
"expect[h,j,..]:List<Int>=a",
|
||||||
|
),
|
||||||
|
Term::var(
|
||||||
|
"__curried_expect_on_list",
|
||||||
|
)
|
||||||
|
.apply(
|
||||||
|
Term::tail_list()
|
||||||
|
.apply(Term::var("__list")),
|
||||||
|
)
|
||||||
|
.lambda("_")
|
||||||
|
.apply(
|
||||||
|
Term::un_i_data()
|
||||||
|
.apply(Term::var("__head")),
|
||||||
|
),
|
||||||
|
Term::var(
|
||||||
|
"expect[h,j,..]:List<Int>=a",
|
||||||
|
),
|
||||||
)
|
)
|
||||||
.lambda("_")
|
.lambda("__head")
|
||||||
.apply(Term::var("check_with").apply(
|
.apply(Term::head_list().apply(Term::var("__list"))),
|
||||||
Term::head_list().apply(Term::var(
|
)
|
||||||
"list_to_check",
|
.lambda("__curried_expect_on_list")
|
||||||
)),
|
.lambda("__list"),
|
||||||
)),
|
)
|
||||||
)
|
.lambda("expect_on_list")
|
||||||
.lambda("list_to_check")
|
.apply(
|
||||||
.lambda("expect_on_list"),
|
Term::var("expect_on_list")
|
||||||
)
|
.apply(Term::var("expect_on_list"))
|
||||||
.lambda("check_with")
|
.lambda("expect_on_list")
|
||||||
.lambda("list_to_check"),
|
.apply(
|
||||||
)
|
Term::var("check_with")
|
||||||
.apply(Term::var("tail_2"))
|
.apply(Term::var("__list"))
|
||||||
.apply(
|
.apply(
|
||||||
Term::var("__val")
|
Term::var("expect_on_list")
|
||||||
.choose_data(
|
.apply(Term::var(
|
||||||
Term::var("expect[h,j,..]:List<Int>=a"),
|
"expect_on_list",
|
||||||
Term::var("expect[h,j,..]:List<Int>=a"),
|
)),
|
||||||
Term::var("expect[h,j,..]:List<Int>=a"),
|
)
|
||||||
Term::un_i_data().apply(Term::var("__val")).delay(),
|
.lambda("__list")
|
||||||
Term::var("expect[h,j,..]:List<Int>=a"),
|
.lambda("expect_on_list"),
|
||||||
)
|
)
|
||||||
.force()
|
.lambda("check_with")
|
||||||
.lambda("__val")
|
.lambda("__list"),
|
||||||
.apply(Term::var("list_item"))
|
)
|
||||||
.lambda("list_item"),
|
.lambda("j")
|
||||||
),
|
.apply(
|
||||||
)
|
Term::un_i_data()
|
||||||
.lambda("tail_2")
|
.apply(Term::var("__val"))
|
||||||
.apply(Term::tail_list().apply(Term::var("tail_1")))
|
.delay(),
|
||||||
.lambda("j")
|
),
|
||||||
.apply(
|
Term::var("expect[h,j,..]:List<Int>=a"),
|
||||||
Term::var("__val")
|
)
|
||||||
.choose_data(
|
.force()
|
||||||
Term::var("expect[h,j,..]:List<Int>=a"),
|
.lambda("__val")
|
||||||
Term::var("expect[h,j,..]:List<Int>=a"),
|
.apply(Term::head_list().apply(Term::var("tail_1")))
|
||||||
Term::var("expect[h,j,..]:List<Int>=a"),
|
.lambda("tail_2")
|
||||||
Term::un_i_data().apply(Term::var("__val")).delay(),
|
.apply(Term::tail_list().apply(Term::var("tail_1")))
|
||||||
Term::var("expect[h,j,..]:List<Int>=a"),
|
.delay(),
|
||||||
)
|
)
|
||||||
.force()
|
.force()
|
||||||
.lambda("__val")
|
.lambda("tail_1")
|
||||||
.apply(Term::head_list().apply(Term::var("tail_1"))),
|
.apply(Term::tail_list().apply(Term::list_values(vec![
|
||||||
)
|
Constant::Data(Data::integer(1.into())),
|
||||||
.delay(),
|
Constant::Data(Data::integer(2.into())),
|
||||||
)
|
Constant::Data(Data::integer(3.into())),
|
||||||
.force()
|
])))
|
||||||
.lambda("tail_1")
|
.lambda("h")
|
||||||
.apply(Term::tail_list().apply(Term::var("unwrap_a")))
|
.apply(Term::un_i_data().apply(Term::var("__val")))
|
||||||
.lambda("h")
|
.delay(),
|
||||||
.apply(
|
Term::var("expect[h,j,..]:List<Int>=a"),
|
||||||
Term::var("__val")
|
)
|
||||||
.choose_data(
|
.force()
|
||||||
Term::var("expect[h,j,..]:List<Int>=a"),
|
.lambda("__val")
|
||||||
Term::var("expect[h,j,..]:List<Int>=a"),
|
.apply(Term::head_list().apply(Term::list_values(vec![
|
||||||
Term::var("expect[h,j,..]:List<Int>=a"),
|
|
||||||
Term::un_i_data().apply(Term::var("__val")).delay(),
|
|
||||||
Term::var("expect[h,j,..]:List<Int>=a"),
|
|
||||||
)
|
|
||||||
.force()
|
|
||||||
.lambda("__val")
|
|
||||||
.apply(Term::head_list().apply(Term::var("unwrap_a"))),
|
|
||||||
)
|
|
||||||
.delay(),
|
|
||||||
)
|
|
||||||
.force()
|
|
||||||
.lambda("unwrap_a")
|
|
||||||
.apply(
|
|
||||||
Term::var("__val")
|
|
||||||
.choose_data(
|
|
||||||
Term::var("expect[h,j,..]:List<Int>=a"),
|
|
||||||
Term::var("expect[h,j,..]:List<Int>=a"),
|
|
||||||
Term::list_values(vec![
|
|
||||||
Constant::Data(Data::integer(1.into())),
|
Constant::Data(Data::integer(1.into())),
|
||||||
Constant::Data(Data::integer(2.into())),
|
Constant::Data(Data::integer(2.into())),
|
||||||
Constant::Data(Data::integer(3.into())),
|
Constant::Data(Data::integer(3.into())),
|
||||||
])
|
]))),
|
||||||
.delay(),
|
)
|
||||||
Term::var("expect[h,j,..]:List<Int>=a"),
|
.force()
|
||||||
Term::var("expect[h,j,..]:List<Int>=a"),
|
.delay(),
|
||||||
)
|
Term::var("expect[h,j,..]:List<Int>=a"),
|
||||||
.force()
|
Term::var("expect[h,j,..]:List<Int>=a"),
|
||||||
.lambda("__val")
|
|
||||||
.apply(Term::data(Data::list(vec![
|
|
||||||
Data::integer(1.into()),
|
|
||||||
Data::integer(2.into()),
|
|
||||||
Data::integer(3.into()),
|
|
||||||
]))),
|
|
||||||
)
|
)
|
||||||
|
.force()
|
||||||
|
.lambda("__val")
|
||||||
|
.apply(Term::data(Data::list(vec![
|
||||||
|
Data::integer(1.into()),
|
||||||
|
Data::integer(2.into()),
|
||||||
|
Data::integer(3.into()),
|
||||||
|
])))
|
||||||
.lambda("expect[h,j,..]:List<Int>=a")
|
.lambda("expect[h,j,..]:List<Int>=a")
|
||||||
.apply(
|
.apply(
|
||||||
Term::Error
|
Term::Error
|
||||||
|
|
|
@ -8,6 +8,7 @@ use std::rc::Rc;
|
||||||
pub const CONSTR_FIELDS_EXPOSER: &str = "__constr_fields_exposer";
|
pub const CONSTR_FIELDS_EXPOSER: &str = "__constr_fields_exposer";
|
||||||
pub const CONSTR_INDEX_EXPOSER: &str = "__constr_index_exposer";
|
pub const CONSTR_INDEX_EXPOSER: &str = "__constr_index_exposer";
|
||||||
pub const EXPECT_ON_LIST: &str = "__expect_on_list";
|
pub const EXPECT_ON_LIST: &str = "__expect_on_list";
|
||||||
|
pub const INNER_EXPECT_ON_LIST: &str = "__inner_expect_on_list";
|
||||||
|
|
||||||
impl<T> Term<T> {
|
impl<T> Term<T> {
|
||||||
// Terms
|
// Terms
|
||||||
|
@ -632,6 +633,7 @@ impl Term<Name> {
|
||||||
.delay(),
|
.delay(),
|
||||||
otherwise.clone(),
|
otherwise.clone(),
|
||||||
)
|
)
|
||||||
|
.force()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert an arbitrary 'term' into a pair and pass it into a 'callback'.
|
/// Convert an arbitrary 'term' into a pair and pass it into a 'callback'.
|
||||||
|
|
Loading…
Reference in New Issue