fix: more test and issues with scoping/names

This commit is contained in:
rvcas 2024-08-08 14:37:14 -04:00 committed by KtorZ
parent cf3180996a
commit f94e40daf4
No known key found for this signature in database
GPG Key ID: 33173CB6F77F4277
6 changed files with 137 additions and 127 deletions

View File

@ -241,6 +241,10 @@ impl TypedExpr {
) )
} }
pub fn is_error_term(&self) -> bool {
matches!(self, Self::ErrorTerm { .. })
}
/// Returns `true` if the typed expr is [`Assignment`]. /// Returns `true` if the typed expr is [`Assignment`].
pub fn is_assignment(&self) -> bool { pub fn is_assignment(&self) -> bool {
matches!(self, Self::Assignment { .. }) matches!(self, Self::Assignment { .. })

View File

@ -318,19 +318,17 @@ fn mark_constructors_as_used_via_field_access() {
bar: Int, bar: Int,
} }
validator foo { fn spend(d: Datum, _r, _c) {
spend(d: Datum, _r, _c) {
when d is { when d is {
D0(params) -> params.foo == 1 D0(params) -> params.foo == 1
D1(_params) -> False D1(_params) -> False
} }
} }
}
"#; "#;
let (warnings, _) = check_validator(parse(source_code)).unwrap(); let (warnings, _) = check(parse(source_code)).unwrap();
assert_eq!(warnings.len(), 1) assert_eq!(warnings.len(), 2)
} }
#[test] #[test]
@ -2506,27 +2504,6 @@ fn validator_public() {
assert!(check_validator(parse(source_code)).is_ok()) assert!(check_validator(parse(source_code)).is_ok())
} }
#[test]
fn validator_private_everything() {
let source_code = r#"
type Datum {
foo: Int,
}
type Redeemer {
bar: Int,
}
validator bar {
spend(datum: Datum, redeemer: Redeemer, _ctx) {
datum.foo == redeemer.bar
}
}
"#;
assert!(check_validator(parse(source_code)).is_ok())
}
#[test] #[test]
fn tuple_access_on_call() { fn tuple_access_on_call() {
let source_code = r#" let source_code = r#"

View File

@ -309,29 +309,43 @@ impl<'a> Environment<'a> {
end_position, end_position,
handlers, handlers,
name, name,
fallback, mut fallback,
location, location,
params, params,
}) => { }) => {
let handlers = handlers let handlers = handlers
.into_iter() .into_iter()
.map(|fun| { .map(|mut fun| {
let Definition::Fn(fun) = let handler_name = format!("{}_{}", &name, &fun.name);
let old_name = fun.name;
fun.name = handler_name;
let Definition::Fn(mut fun) =
self.generalise_definition(Definition::Fn(fun), module_name) self.generalise_definition(Definition::Fn(fun), module_name)
else { else {
unreachable!() unreachable!()
}; };
fun.name = old_name;
fun fun
}) })
.collect(); .collect();
let Definition::Fn(fallback) = let fallback_name = format!("{}_{}", &name, &fallback.name);
let old_name = fallback.name;
fallback.name = fallback_name;
let Definition::Fn(mut fallback) =
self.generalise_definition(Definition::Fn(fallback), module_name) self.generalise_definition(Definition::Fn(fallback), module_name)
else { else {
unreachable!() unreachable!()
}; };
fallback.name = old_name;
Definition::Validator(Validator { Definition::Validator(Validator {
doc, doc,
name, name,

View File

@ -178,6 +178,11 @@ fn infer_definition(
}) => { }) => {
let params_length = params.len(); let params_length = params.len();
environment.in_new_scope(|environment| {
let fallback_name = format!("{}_{}", &name, &fallback.name);
put_params_in_scope(&fallback_name, environment, &params);
let mut typed_handlers = vec![]; let mut typed_handlers = vec![];
for mut handler in handlers { for mut handler in handlers {
@ -185,11 +190,16 @@ fn infer_definition(
let temp_params = params.iter().cloned().chain(handler.arguments); let temp_params = params.iter().cloned().chain(handler.arguments);
handler.arguments = temp_params.collect(); handler.arguments = temp_params.collect();
put_params_in_scope(&handler.name, environment, &params); let handler_name = format!("{}_{}", &name, &handler.name);
let old_name = handler.name;
handler.name = handler_name;
let mut typed_fun = let mut typed_fun =
infer_function(&handler, module_name, hydrators, environment, tracing)?; infer_function(&handler, module_name, hydrators, environment, tracing)?;
typed_fun.name = old_name;
if !typed_fun.return_type.is_bool() { if !typed_fun.return_type.is_bool() {
return Err(Error::ValidatorMustReturnBool { return Err(Error::ValidatorMustReturnBool {
return_type: typed_fun.return_type.clone(), return_type: typed_fun.return_type.clone(),
@ -224,12 +234,16 @@ fn infer_definition(
let temp_params = params.iter().cloned().chain(fallback.arguments); let temp_params = params.iter().cloned().chain(fallback.arguments);
fallback.arguments = temp_params.collect(); fallback.arguments = temp_params.collect();
put_params_in_scope(&fallback.name, environment, &params); let old_name = fallback.name;
fallback.name = fallback_name;
let mut typed_fallback = let mut typed_fallback =
infer_function(&fallback, module_name, hydrators, environment, tracing)?; infer_function(&fallback, module_name, hydrators, environment, tracing)?;
if !typed_fallback.return_type.is_bool() { typed_fallback.name = old_name;
if !typed_fallback.body.is_error_term() && !typed_fallback.return_type.is_bool()
{
return Err(Error::ValidatorMustReturnBool { return Err(Error::ValidatorMustReturnBool {
return_type: typed_fallback.return_type.clone(), return_type: typed_fallback.return_type.clone(),
location: typed_fallback.location, location: typed_fallback.location,
@ -274,6 +288,7 @@ fn infer_definition(
location, location,
params: typed_params, params: typed_params,
})) }))
})
} }
Definition::Test(f) => { Definition::Test(f) => {

View File

@ -550,8 +550,8 @@ mod tests {
type UUID { UUID } type UUID { UUID }
validator { validator opaque_singleton_variants {
fn opaque_singleton_variants(redeemer: Dict<UUID, Int>, ctx: Void) { spend(redeemer: Dict<UUID, Int>, ctx: Void) {
True True
} }
} }
@ -568,8 +568,8 @@ mod tests {
denominator: Int, denominator: Int,
} }
validator { validator opaque_singleton_multi_variants {
fn opaque_singleton_multi_variants(redeemer: Rational, ctx: Void) { spend(redeemer: Rational, ctx: Void) {
True True
} }
} }
@ -585,8 +585,8 @@ mod tests {
foo: Data foo: Data
} }
validator { validator nested_data {
fn nested_data(datum: Foo, redeemer: Int, ctx: Void) { spend(datum: Foo, redeemer: Int, ctx: Void) {
True True
} }
} }
@ -604,8 +604,8 @@ mod tests {
Mul(Expr, Expr) Mul(Expr, Expr)
} }
validator { validator recursive_types {
fn recursive_types(redeemer: Expr, ctx: Void) { spend(redeemer: Expr, ctx: Void) {
True True
} }
} }
@ -632,8 +632,8 @@ mod tests {
} }
} }
validator { validator recursive_generic_types {
fn recursive_generic_types(datum: Foo, redeemer: LinkedList<Int>, ctx: Void) { spend(datum: Foo, redeemer: LinkedList<Int>, ctx: Void) {
True True
} }
} }
@ -649,8 +649,8 @@ mod tests {
foo: Int foo: Int
} }
validator { validator annotated_data {
fn annotated_data(datum: Data<Foo>, redeemer: Data, ctx: Void) { spend(datum: Data<Foo>, redeemer: Data, ctx: Void) {
True True
} }
} }

View File

@ -3687,8 +3687,8 @@ fn when_tuple_deconstruction() {
Buy Buy
} }
validator { validator thing {
fn spend(dat: Datum, red: RedSpend, ctx: Data) { spend(dat: Datum, red: RedSpend, ctx: Data) {
when (dat, red) is { when (dat, red) is {
(A(a), Spend(x)) -> (A(a), Spend(x)) ->
(a.idx == x)? (a.idx == x)?
@ -4046,8 +4046,8 @@ fn generic_validator_type_test() {
something: Void, something: Void,
} }
validator { validator err_example {
fn err_example(r: A<B>, _ctx: Data) -> Bool { spend(r: A<B>, _ctx: Data) -> Bool {
when r is { when r is {
NoA -> NoA ->
False False
@ -5562,8 +5562,8 @@ fn opaque_value_in_datum() {
} }
validator { validator foo {
fn spend(dat: Dat, red: Data, ctx: Data) { spend(dat: Dat, red: Data, ctx: Data) {
let val = dat.a let val = dat.a
expect [Pair(_, amount)] = val.inner.inner expect [Pair(_, amount)] = val.inner.inner