Use Delay error directly when casting from data without traces
This commit is contained in:
parent
575f0f9a9a
commit
2be76d7cda
|
@ -52,6 +52,11 @@ use uplc::{
|
||||||
optimize::{aiken_optimize_and_intern, interner::CodeGenInterner, shrinker::NO_INLINE},
|
optimize::{aiken_optimize_and_intern, interner::CodeGenInterner, shrinker::NO_INLINE},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type Otherwise = Option<AirTree>;
|
||||||
|
|
||||||
|
const DELAY_ERROR: fn() -> AirTree =
|
||||||
|
|| AirTree::anon_func(vec![], AirTree::error(Type::void(), false), true);
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct CodeGenerator<'a> {
|
pub struct CodeGenerator<'a> {
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
|
@ -974,7 +979,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
&mut index_map,
|
&mut index_map,
|
||||||
pattern.location(),
|
pattern.location(),
|
||||||
then,
|
then,
|
||||||
otherwise,
|
props.otherwise.clone(),
|
||||||
0,
|
0,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -1017,7 +1022,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
&mut index_map,
|
&mut index_map,
|
||||||
pattern.location(),
|
pattern.location(),
|
||||||
then,
|
then,
|
||||||
otherwise,
|
props.otherwise.clone(),
|
||||||
0,
|
0,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -1579,7 +1584,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
defined_data_types: &mut IndexMap<String, u64>,
|
defined_data_types: &mut IndexMap<String, u64>,
|
||||||
location: Span,
|
location: Span,
|
||||||
then: AirTree,
|
then: AirTree,
|
||||||
otherwise: AirTree,
|
otherwise: Otherwise,
|
||||||
depth: usize,
|
depth: usize,
|
||||||
) -> AirTree {
|
) -> AirTree {
|
||||||
assert!(
|
assert!(
|
||||||
|
@ -1689,7 +1694,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
AirTree::local_var(&pair_name, inner_list_type.clone()),
|
AirTree::local_var(&pair_name, inner_list_type.clone()),
|
||||||
true,
|
true,
|
||||||
expect_fst,
|
expect_fst,
|
||||||
otherwise.clone(),
|
otherwise.unwrap_or_else(DELAY_ERROR),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
true,
|
true,
|
||||||
|
@ -1783,7 +1788,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
AirTree::local_var(&tuple_name, tipo.clone()),
|
AirTree::local_var(&tuple_name, tipo.clone()),
|
||||||
true,
|
true,
|
||||||
then,
|
then,
|
||||||
otherwise,
|
otherwise.unwrap_or_else(DELAY_ERROR),
|
||||||
);
|
);
|
||||||
|
|
||||||
AirTree::let_assignment(&tuple_name, value, tuple_access)
|
AirTree::let_assignment(&tuple_name, value, tuple_access)
|
||||||
|
@ -1849,7 +1854,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
otherwise.clone(),
|
otherwise.clone(),
|
||||||
depth + 1,
|
depth + 1,
|
||||||
),
|
),
|
||||||
otherwise,
|
otherwise.unwrap_or_else(DELAY_ERROR),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
true,
|
true,
|
||||||
|
@ -1951,7 +1956,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
AirTree::local_var(&pair_name, tipo.clone()),
|
AirTree::local_var(&pair_name, tipo.clone()),
|
||||||
true,
|
true,
|
||||||
expect_fst,
|
expect_fst,
|
||||||
otherwise,
|
otherwise.unwrap_or_else(DELAY_ERROR),
|
||||||
);
|
);
|
||||||
|
|
||||||
AirTree::let_assignment(&pair_name, value, pair_access)
|
AirTree::let_assignment(&pair_name, value, pair_access)
|
||||||
|
@ -2000,12 +2005,14 @@ impl<'a> CodeGenerator<'a> {
|
||||||
vec![],
|
vec![],
|
||||||
);
|
);
|
||||||
|
|
||||||
let otherwise_delayed = AirTree::local_var("otherwise_delayed", Type::void());
|
let otherwise_delayed = otherwise
|
||||||
|
.as_ref()
|
||||||
|
.map(|_| AirTree::local_var("otherwise_delayed", Type::void()));
|
||||||
|
|
||||||
let is_never = data_type.is_never();
|
let is_never = data_type.is_never();
|
||||||
|
|
||||||
let constr_clauses = data_type.constructors.iter().enumerate().rfold(
|
let constr_clauses = data_type.constructors.iter().enumerate().rfold(
|
||||||
otherwise_delayed.clone(),
|
otherwise_delayed.clone().unwrap_or_else(DELAY_ERROR),
|
||||||
|acc, (index, constr)| {
|
|acc, (index, constr)| {
|
||||||
// NOTE: For the Never type, we have an placeholder first constructor
|
// NOTE: For the Never type, we have an placeholder first constructor
|
||||||
// that must be ignored. The Never type is considered to have only one
|
// that must be ignored. The Never type is considered to have only one
|
||||||
|
@ -2052,7 +2059,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
tipo.clone(),
|
tipo.clone(),
|
||||||
),
|
),
|
||||||
constr_then,
|
constr_then,
|
||||||
otherwise_delayed.clone(),
|
otherwise_delayed.clone().unwrap_or_else(DELAY_ERROR),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
AirTree::fields_expose(
|
AirTree::fields_expose(
|
||||||
|
@ -2066,7 +2073,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
),
|
),
|
||||||
true,
|
true,
|
||||||
constr_then,
|
constr_then,
|
||||||
otherwise_delayed.clone(),
|
otherwise_delayed.clone().unwrap_or_else(DELAY_ERROR),
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2119,11 +2126,15 @@ impl<'a> CodeGenerator<'a> {
|
||||||
|
|
||||||
let code_gen_func = CodeGenFunction::Function {
|
let code_gen_func = CodeGenFunction::Function {
|
||||||
body: func_body,
|
body: func_body,
|
||||||
params: vec![
|
params: if otherwise.is_some() {
|
||||||
|
vec![
|
||||||
"__param_0".to_string(),
|
"__param_0".to_string(),
|
||||||
"then_delayed".to_string(),
|
"then_delayed".to_string(),
|
||||||
"otherwise_delayed".to_string(),
|
"otherwise_delayed".to_string(),
|
||||||
],
|
]
|
||||||
|
} else {
|
||||||
|
vec!["__param_0".to_string(), "then_delayed".to_string()]
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
self.code_gen_functions
|
self.code_gen_functions
|
||||||
|
@ -2134,7 +2145,11 @@ impl<'a> CodeGenerator<'a> {
|
||||||
defined_data_types.insert(data_type_name.to_string(), 1);
|
defined_data_types.insert(data_type_name.to_string(), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
let args = vec![value, AirTree::anon_func(vec![], then, true), otherwise];
|
let args = if let Some(otherwise) = otherwise {
|
||||||
|
vec![value, AirTree::anon_func(vec![], then, true), otherwise]
|
||||||
|
} else {
|
||||||
|
vec![value, AirTree::anon_func(vec![], then, true)]
|
||||||
|
};
|
||||||
|
|
||||||
let module_fn = ValueConstructorVariant::ModuleFn {
|
let module_fn = ValueConstructorVariant::ModuleFn {
|
||||||
name: data_type_name.to_string(),
|
name: data_type_name.to_string(),
|
||||||
|
|
|
@ -981,7 +981,11 @@ 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::unwrap_void_or(term, |result| result, &Term::Error.delay()),
|
Some(UplcType::Unit) => Term::unwrap_void_or(
|
||||||
|
term.as_var("val", |val| Term::Var(val)),
|
||||||
|
|result| result,
|
||||||
|
&Term::Error.delay(),
|
||||||
|
),
|
||||||
|
|
||||||
Some(UplcType::Data) | None => term,
|
Some(UplcType::Data) | None => term,
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue