feat(validator): parsing and typechecking for double validators
This commit is contained in:
parent
3eccc349aa
commit
ed92869fb9
|
@ -322,6 +322,7 @@ pub struct Validator<T, Expr> {
|
||||||
pub doc: Option<String>,
|
pub doc: Option<String>,
|
||||||
pub end_position: usize,
|
pub end_position: usize,
|
||||||
pub fun: Function<T, Expr>,
|
pub fun: Function<T, Expr>,
|
||||||
|
pub other_fun: Option<Function<T, Expr>>,
|
||||||
pub location: Span,
|
pub location: Span,
|
||||||
pub params: Vec<Arg<T>>,
|
pub params: Vec<Arg<T>>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -504,12 +504,17 @@ impl<'comments> Formatter<'comments> {
|
||||||
&mut self,
|
&mut self,
|
||||||
params: &'a [UntypedArg],
|
params: &'a [UntypedArg],
|
||||||
fun: &'a UntypedFunction,
|
fun: &'a UntypedFunction,
|
||||||
|
other_fun: &'a Option<UntypedFunction>,
|
||||||
end_position: usize,
|
end_position: usize,
|
||||||
) -> Document<'a> {
|
) -> Document<'a> {
|
||||||
// Fn and args
|
// Fn and args
|
||||||
let head = "fn".to_doc().append(wrap_args(
|
let head = "fn"
|
||||||
fun.arguments.iter().map(|e| (self.fn_arg(e), false)),
|
.to_doc()
|
||||||
));
|
.append(" ")
|
||||||
|
.append(fun.name.to_doc())
|
||||||
|
.append(wrap_args(
|
||||||
|
fun.arguments.iter().map(|e| (self.fn_arg(e), false)),
|
||||||
|
));
|
||||||
|
|
||||||
// Add return annotation
|
// Add return annotation
|
||||||
let head = match &fun.return_annotation {
|
let head = match &fun.return_annotation {
|
||||||
|
@ -528,15 +533,11 @@ impl<'comments> Formatter<'comments> {
|
||||||
};
|
};
|
||||||
|
|
||||||
// validator name(params)
|
// validator name(params)
|
||||||
let v_head = "validator"
|
let v_head = "validator".to_doc().append(if !params.is_empty() {
|
||||||
.to_doc()
|
wrap_args(params.iter().map(|e| (self.fn_arg(e), false)))
|
||||||
.append(" ")
|
} else {
|
||||||
.append(fun.name.as_str())
|
"".to_doc()
|
||||||
.append(if !params.is_empty() {
|
});
|
||||||
wrap_args(params.iter().map(|e| (self.fn_arg(e), false)))
|
|
||||||
} else {
|
|
||||||
"".to_doc()
|
|
||||||
});
|
|
||||||
|
|
||||||
// Stick it all together
|
// Stick it all together
|
||||||
let inner_fn = head
|
let inner_fn = head
|
||||||
|
|
|
@ -242,9 +242,43 @@ pub fn type_alias_parser() -> impl Parser<Token, ast::UntypedDefinition, Error =
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn validator_parser() -> impl Parser<Token, ast::UntypedDefinition, Error = ParseError> {
|
pub fn validator_parser() -> impl Parser<Token, ast::UntypedDefinition, Error = ParseError> {
|
||||||
just(Token::Validator)
|
let func_parser = just(Token::Fn)
|
||||||
.ignore_then(select! {Token::Name {name} => name}.map_with_span(|name, span| (name, span)))
|
.ignore_then(select! {Token::Name {name} => name})
|
||||||
.then(
|
.then(
|
||||||
|
fn_param_parser()
|
||||||
|
.separated_by(just(Token::Comma))
|
||||||
|
.allow_trailing()
|
||||||
|
.delimited_by(just(Token::LeftParen), just(Token::RightParen))
|
||||||
|
.map_with_span(|arguments, span| (arguments, span)),
|
||||||
|
)
|
||||||
|
.then(just(Token::RArrow).ignore_then(type_parser()).or_not())
|
||||||
|
.then(
|
||||||
|
expr_seq_parser()
|
||||||
|
.or_not()
|
||||||
|
.delimited_by(just(Token::LeftBrace), just(Token::RightBrace)),
|
||||||
|
)
|
||||||
|
.map_with_span(
|
||||||
|
|(((name, (arguments, args_span)), return_annotation), body), span| ast::Function {
|
||||||
|
arguments,
|
||||||
|
body: body.unwrap_or_else(|| expr::UntypedExpr::todo(span, None)),
|
||||||
|
doc: None,
|
||||||
|
location: Span {
|
||||||
|
start: span.start,
|
||||||
|
end: return_annotation
|
||||||
|
.as_ref()
|
||||||
|
.map(|l| l.location().end)
|
||||||
|
.unwrap_or_else(|| args_span.end),
|
||||||
|
},
|
||||||
|
end_position: span.end - 1,
|
||||||
|
name,
|
||||||
|
public: false,
|
||||||
|
return_annotation,
|
||||||
|
return_type: (),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
just(Token::Validator)
|
||||||
|
.ignore_then(
|
||||||
fn_param_parser()
|
fn_param_parser()
|
||||||
.separated_by(just(Token::Comma))
|
.separated_by(just(Token::Comma))
|
||||||
.allow_trailing()
|
.allow_trailing()
|
||||||
|
@ -253,51 +287,32 @@ pub fn validator_parser() -> impl Parser<Token, ast::UntypedDefinition, Error =
|
||||||
.or_not(),
|
.or_not(),
|
||||||
)
|
)
|
||||||
.then(
|
.then(
|
||||||
just(Token::Fn)
|
func_parser
|
||||||
.ignore_then(
|
.repeated()
|
||||||
fn_param_parser()
|
.at_least(1)
|
||||||
.separated_by(just(Token::Comma))
|
.at_most(2)
|
||||||
.allow_trailing()
|
.delimited_by(just(Token::LeftBrace), just(Token::RightBrace))
|
||||||
.delimited_by(just(Token::LeftParen), just(Token::RightParen))
|
.map(IntoIterator::into_iter),
|
||||||
.map_with_span(|arguments, span| (arguments, span)),
|
|
||||||
)
|
|
||||||
.then(just(Token::RArrow).ignore_then(type_parser()).or_not())
|
|
||||||
.then(
|
|
||||||
expr_seq_parser()
|
|
||||||
.or_not()
|
|
||||||
.delimited_by(just(Token::LeftBrace), just(Token::RightBrace)),
|
|
||||||
)
|
|
||||||
.map_with_span(
|
|
||||||
|(((arguments, args_span), return_annotation), body), span| ast::Function {
|
|
||||||
arguments,
|
|
||||||
body: body.unwrap_or_else(|| expr::UntypedExpr::todo(span, None)),
|
|
||||||
doc: None,
|
|
||||||
location: Span {
|
|
||||||
start: span.start,
|
|
||||||
end: return_annotation
|
|
||||||
.as_ref()
|
|
||||||
.map(|l| l.location().end)
|
|
||||||
.unwrap_or_else(|| args_span.end),
|
|
||||||
},
|
|
||||||
end_position: span.end - 1,
|
|
||||||
name: "".to_string(),
|
|
||||||
public: false,
|
|
||||||
return_annotation,
|
|
||||||
return_type: (),
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.delimited_by(just(Token::LeftBrace), just(Token::RightBrace)),
|
|
||||||
)
|
)
|
||||||
.map_with_span(|((name, opt_extra_params), mut fun), span| {
|
.map_with_span(|(opt_extra_params, mut functions), span| {
|
||||||
fun.name = name.0;
|
let (params, params_span) = opt_extra_params.unwrap_or((
|
||||||
|
vec![],
|
||||||
let (params, params_span) = opt_extra_params.unwrap_or((vec![], name.1));
|
Span {
|
||||||
|
start: 0,
|
||||||
|
// just needs to be the word `validator` at this point
|
||||||
|
end: span.start + 9,
|
||||||
|
},
|
||||||
|
));
|
||||||
|
|
||||||
ast::UntypedDefinition::Validator(ast::Validator {
|
ast::UntypedDefinition::Validator(ast::Validator {
|
||||||
doc: None,
|
doc: None,
|
||||||
fun,
|
// unwrap is safe to do here because
|
||||||
|
// above we use `.at_least(1)`
|
||||||
|
fun: functions.next().unwrap(),
|
||||||
|
other_fun: functions.next(),
|
||||||
location: Span {
|
location: Span {
|
||||||
start: span.start,
|
start: span.start,
|
||||||
|
// capture the span from the optional params
|
||||||
end: params_span.end,
|
end: params_span.end,
|
||||||
},
|
},
|
||||||
params,
|
params,
|
||||||
|
|
|
@ -53,8 +53,8 @@ fn check_validator(
|
||||||
#[test]
|
#[test]
|
||||||
fn validator_illegal_return_type() {
|
fn validator_illegal_return_type() {
|
||||||
let source_code = r#"
|
let source_code = r#"
|
||||||
validator foo {
|
validator {
|
||||||
fn(d, r, c) {
|
fn foo(d, r, c) {
|
||||||
1
|
1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -69,8 +69,8 @@ fn validator_illegal_return_type() {
|
||||||
#[test]
|
#[test]
|
||||||
fn validator_illegal_arity() {
|
fn validator_illegal_arity() {
|
||||||
let source_code = r#"
|
let source_code = r#"
|
||||||
validator foo {
|
validator {
|
||||||
fn(c) {
|
fn foo(c) {
|
||||||
True
|
True
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -85,8 +85,8 @@ fn validator_illegal_arity() {
|
||||||
#[test]
|
#[test]
|
||||||
fn validator_correct_form() {
|
fn validator_correct_form() {
|
||||||
let source_code = r#"
|
let source_code = r#"
|
||||||
validator foo {
|
validator {
|
||||||
fn(d, r, c) {
|
fn foo(d, r, c) {
|
||||||
True
|
True
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -98,8 +98,8 @@ fn validator_correct_form() {
|
||||||
#[test]
|
#[test]
|
||||||
fn validator_in_lib_warning() {
|
fn validator_in_lib_warning() {
|
||||||
let source_code = r#"
|
let source_code = r#"
|
||||||
validator foo {
|
validator {
|
||||||
fn(c) {
|
fn foo(c) {
|
||||||
True
|
True
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,16 +58,16 @@ fn test_format_if() {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_format_validator() {
|
fn test_format_validator() {
|
||||||
let src = indoc! {r#"
|
let src = indoc! {r#"
|
||||||
validator foo ( ) {
|
validator ( ) {
|
||||||
fn(d: Datum, r: Redeemer, ctx: ScriptContext) -> Bool {
|
fn foo (d: Datum, r: Redeemer, ctx: ScriptContext) -> Bool {
|
||||||
True
|
True
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"#};
|
"#};
|
||||||
|
|
||||||
let expected = indoc! {r#"
|
let expected = indoc! {r#"
|
||||||
validator foo {
|
validator {
|
||||||
fn(d: Datum, r: Redeemer, ctx: ScriptContext) -> Bool {
|
fn foo(d: Datum, r: Redeemer, ctx: ScriptContext) -> Bool {
|
||||||
True
|
True
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,8 +41,8 @@ fn windows_newline() {
|
||||||
#[test]
|
#[test]
|
||||||
fn validator() {
|
fn validator() {
|
||||||
let code = indoc! {r#"
|
let code = indoc! {r#"
|
||||||
validator foo {
|
validator {
|
||||||
fn(datum, rdmr, ctx) {
|
fn foo(datum, rdmr, ctx) {
|
||||||
True
|
True
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -91,14 +91,120 @@ fn validator() {
|
||||||
name: "True".to_string(),
|
name: "True".to_string(),
|
||||||
},
|
},
|
||||||
doc: None,
|
doc: None,
|
||||||
location: Span::new((), 18..38),
|
location: Span::new((), 14..38),
|
||||||
name: "foo".to_string(),
|
name: "foo".to_string(),
|
||||||
public: false,
|
public: false,
|
||||||
return_annotation: None,
|
return_annotation: None,
|
||||||
return_type: (),
|
return_type: (),
|
||||||
end_position: 52,
|
end_position: 52,
|
||||||
},
|
},
|
||||||
location: Span::new((), 0..13),
|
other_fun: None,
|
||||||
|
location: Span::new((), 0..9),
|
||||||
|
params: vec![],
|
||||||
|
})],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn double_validator() {
|
||||||
|
let code = indoc! {r#"
|
||||||
|
validator {
|
||||||
|
fn foo(datum, rdmr, ctx) {
|
||||||
|
True
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bar(rdmr, ctx) {
|
||||||
|
True
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"#};
|
||||||
|
|
||||||
|
assert_definitions(
|
||||||
|
code,
|
||||||
|
vec![ast::UntypedDefinition::Validator(ast::Validator {
|
||||||
|
doc: None,
|
||||||
|
end_position: 90,
|
||||||
|
fun: Function {
|
||||||
|
arguments: vec![
|
||||||
|
ast::Arg {
|
||||||
|
arg_name: ast::ArgName::Named {
|
||||||
|
name: "datum".to_string(),
|
||||||
|
label: "datum".to_string(),
|
||||||
|
location: Span::new((), 21..26),
|
||||||
|
},
|
||||||
|
location: Span::new((), 21..26),
|
||||||
|
annotation: None,
|
||||||
|
tipo: (),
|
||||||
|
},
|
||||||
|
ast::Arg {
|
||||||
|
arg_name: ast::ArgName::Named {
|
||||||
|
name: "rdmr".to_string(),
|
||||||
|
label: "rdmr".to_string(),
|
||||||
|
location: Span::new((), 28..32),
|
||||||
|
},
|
||||||
|
location: Span::new((), 28..32),
|
||||||
|
annotation: None,
|
||||||
|
tipo: (),
|
||||||
|
},
|
||||||
|
ast::Arg {
|
||||||
|
arg_name: ast::ArgName::Named {
|
||||||
|
name: "ctx".to_string(),
|
||||||
|
label: "ctx".to_string(),
|
||||||
|
location: Span::new((), 34..37),
|
||||||
|
},
|
||||||
|
location: Span::new((), 34..37),
|
||||||
|
annotation: None,
|
||||||
|
tipo: (),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
body: expr::UntypedExpr::Var {
|
||||||
|
location: Span::new((), 45..49),
|
||||||
|
name: "True".to_string(),
|
||||||
|
},
|
||||||
|
doc: None,
|
||||||
|
location: Span::new((), 14..38),
|
||||||
|
name: "foo".to_string(),
|
||||||
|
public: false,
|
||||||
|
return_annotation: None,
|
||||||
|
return_type: (),
|
||||||
|
end_position: 52,
|
||||||
|
},
|
||||||
|
other_fun: Some(Function {
|
||||||
|
arguments: vec![
|
||||||
|
ast::Arg {
|
||||||
|
arg_name: ast::ArgName::Named {
|
||||||
|
name: "rdmr".to_string(),
|
||||||
|
label: "rdmr".to_string(),
|
||||||
|
location: Span::new((), 64..68),
|
||||||
|
},
|
||||||
|
location: Span::new((), 64..68),
|
||||||
|
annotation: None,
|
||||||
|
tipo: (),
|
||||||
|
},
|
||||||
|
ast::Arg {
|
||||||
|
arg_name: ast::ArgName::Named {
|
||||||
|
name: "ctx".to_string(),
|
||||||
|
label: "ctx".to_string(),
|
||||||
|
location: Span::new((), 70..73),
|
||||||
|
},
|
||||||
|
location: Span::new((), 70..73),
|
||||||
|
annotation: None,
|
||||||
|
tipo: (),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
body: expr::UntypedExpr::Var {
|
||||||
|
location: Span::new((), 81..85),
|
||||||
|
name: "True".to_string(),
|
||||||
|
},
|
||||||
|
doc: None,
|
||||||
|
location: Span::new((), 57..74),
|
||||||
|
name: "bar".to_string(),
|
||||||
|
public: false,
|
||||||
|
return_annotation: None,
|
||||||
|
return_type: (),
|
||||||
|
end_position: 88,
|
||||||
|
}),
|
||||||
|
location: Span::new((), 0..9),
|
||||||
params: vec![],
|
params: vec![],
|
||||||
})],
|
})],
|
||||||
)
|
)
|
||||||
|
|
|
@ -3,8 +3,8 @@ use std::collections::HashMap;
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::{
|
ast::{
|
||||||
DataType, Definition, Function, Layer, ModuleConstant, ModuleKind, RecordConstructor,
|
DataType, Definition, Function, Layer, ModuleConstant, ModuleKind, RecordConstructor,
|
||||||
RecordConstructorArg, Span, Tracing, TypeAlias, TypedDefinition, TypedModule,
|
RecordConstructorArg, Span, Tracing, TypeAlias, TypedDefinition, TypedFunction,
|
||||||
UntypedDefinition, UntypedModule, Use, Validator,
|
TypedModule, UntypedDefinition, UntypedModule, Use, Validator,
|
||||||
},
|
},
|
||||||
builtins,
|
builtins,
|
||||||
builtins::function,
|
builtins::function,
|
||||||
|
@ -255,11 +255,12 @@ fn infer_definition(
|
||||||
location,
|
location,
|
||||||
end_position,
|
end_position,
|
||||||
mut fun,
|
mut fun,
|
||||||
mut params,
|
other_fun,
|
||||||
|
params,
|
||||||
}) => {
|
}) => {
|
||||||
let params_length = params.len();
|
let params_length = params.len();
|
||||||
params.append(&mut fun.arguments);
|
let temp_params = params.iter().cloned().chain(fun.arguments);
|
||||||
fun.arguments = params;
|
fun.arguments = temp_params.collect();
|
||||||
|
|
||||||
if let Definition::Fn(mut typed_fun) = infer_definition(
|
if let Definition::Fn(mut typed_fun) = infer_definition(
|
||||||
Definition::Fn(fun),
|
Definition::Fn(fun),
|
||||||
|
@ -285,10 +286,51 @@ fn infer_definition(
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let typed_other_fun = other_fun
|
||||||
|
.map(|mut other| -> Result<TypedFunction, Error> {
|
||||||
|
let params = params.into_iter().chain(other.arguments);
|
||||||
|
other.arguments = params.collect();
|
||||||
|
|
||||||
|
if let Definition::Fn(mut other_typed_fun) = infer_definition(
|
||||||
|
Definition::Fn(other),
|
||||||
|
module_name,
|
||||||
|
hydrators,
|
||||||
|
environment,
|
||||||
|
tracing,
|
||||||
|
kind,
|
||||||
|
)? {
|
||||||
|
if !other_typed_fun.return_type.is_bool() {
|
||||||
|
return Err(Error::ValidatorMustReturnBool {
|
||||||
|
return_type: other_typed_fun.return_type.clone(),
|
||||||
|
location: other_typed_fun.location,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
other_typed_fun.arguments.drain(0..params_length);
|
||||||
|
|
||||||
|
if other_typed_fun.arguments.len() < 2
|
||||||
|
|| other_typed_fun.arguments.len() > 3
|
||||||
|
{
|
||||||
|
return Err(Error::IncorrectValidatorArity {
|
||||||
|
count: typed_fun.arguments.len() as u32,
|
||||||
|
location: typed_fun.location,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(other_typed_fun)
|
||||||
|
} else {
|
||||||
|
unreachable!(
|
||||||
|
"validator definition inferred as something other than a function?"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.transpose();
|
||||||
|
|
||||||
Ok(Definition::Validator(Validator {
|
Ok(Definition::Validator(Validator {
|
||||||
doc,
|
doc,
|
||||||
end_position,
|
end_position,
|
||||||
fun: typed_fun,
|
fun: typed_fun,
|
||||||
|
other_fun: typed_other_fun?,
|
||||||
location,
|
location,
|
||||||
params: typed_params,
|
params: typed_params,
|
||||||
}))
|
}))
|
||||||
|
|
|
@ -272,8 +272,8 @@ mod test {
|
||||||
fn mint_basic() {
|
fn mint_basic() {
|
||||||
assert_validator(
|
assert_validator(
|
||||||
r#"
|
r#"
|
||||||
validator mint {
|
validator {
|
||||||
fn(redeemer: Data, ctx: Data) {
|
fn mint(redeemer: Data, ctx: Data) {
|
||||||
True
|
True
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -302,8 +302,8 @@ mod test {
|
||||||
fn mint_parameterized() {
|
fn mint_parameterized() {
|
||||||
assert_validator(
|
assert_validator(
|
||||||
r#"
|
r#"
|
||||||
validator mint(utxo_ref: Int) {
|
validator(utxo_ref: Int) {
|
||||||
fn(redeemer: Data, ctx: Data) {
|
fn mint(redeemer: Data, ctx: Data) {
|
||||||
True
|
True
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -373,8 +373,8 @@ mod test {
|
||||||
Abort
|
Abort
|
||||||
}
|
}
|
||||||
|
|
||||||
validator simplified_hydra {
|
validator {
|
||||||
fn(datum: State, redeemer: Input, ctx: Data) {
|
fn simplified_hydra(datum: State, redeemer: Input, ctx: Data) {
|
||||||
True
|
True
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -485,8 +485,8 @@ mod test {
|
||||||
fn tuples() {
|
fn tuples() {
|
||||||
assert_validator(
|
assert_validator(
|
||||||
r#"
|
r#"
|
||||||
validator tuples {
|
validator {
|
||||||
fn(datum: (Int, ByteArray), redeemer: (Int, Int, Int), ctx: Void) {
|
fn tuples(datum: (Int, ByteArray), redeemer: (Int, Int, Int), ctx: Void) {
|
||||||
True
|
True
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -560,8 +560,8 @@ mod test {
|
||||||
Infinite
|
Infinite
|
||||||
}
|
}
|
||||||
|
|
||||||
validator generics {
|
validator {
|
||||||
fn(redeemer: Either<ByteArray, Interval<Int>>, ctx: Void) {
|
fn generics(redeemer: Either<ByteArray, Interval<Int>>, ctx: Void) {
|
||||||
True
|
True
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -644,8 +644,8 @@ mod test {
|
||||||
|
|
||||||
type UUID { UUID }
|
type UUID { UUID }
|
||||||
|
|
||||||
validator list_2_tuples_as_map {
|
validator {
|
||||||
fn(redeemer: Dict<UUID, Int>, ctx: Void) {
|
fn list_2_tuples_as_map(redeemer: Dict<UUID, Int>, ctx: Void) {
|
||||||
True
|
True
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -707,8 +707,8 @@ mod test {
|
||||||
|
|
||||||
type UUID { UUID }
|
type UUID { UUID }
|
||||||
|
|
||||||
validator opaque_singleton_variants {
|
validator {
|
||||||
fn(redeemer: Dict<UUID, Int>, ctx: Void) {
|
fn opaque_singleton_variants(redeemer: Dict<UUID, Int>, ctx: Void) {
|
||||||
True
|
True
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -753,8 +753,8 @@ mod test {
|
||||||
foo: Data
|
foo: Data
|
||||||
}
|
}
|
||||||
|
|
||||||
validator nested_data {
|
validator {
|
||||||
fn(datum: Foo, redeemer: Int, ctx: Void) {
|
fn nested_data(datum: Foo, redeemer: Int, ctx: Void) {
|
||||||
True
|
True
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -814,8 +814,8 @@ mod test {
|
||||||
Mul(Expr, Expr)
|
Mul(Expr, Expr)
|
||||||
}
|
}
|
||||||
|
|
||||||
validator recursive_types {
|
validator {
|
||||||
fn(redeemer: Expr, ctx: Void) {
|
fn recursive_types(redeemer: Expr, ctx: Void) {
|
||||||
True
|
True
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -899,8 +899,8 @@ mod test {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
validator recursive_generic_types {
|
validator {
|
||||||
fn(datum: Foo, redeemer: LinkedList<Int>, ctx: Void) {
|
fn recursive_generic_types(datum: Foo, redeemer: LinkedList<Int>, ctx: Void) {
|
||||||
True
|
True
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue