diff --git a/crates/aiken-lang/src/ast.rs b/crates/aiken-lang/src/ast.rs index c5ffd510..23cf2925 100644 --- a/crates/aiken-lang/src/ast.rs +++ b/crates/aiken-lang/src/ast.rs @@ -691,6 +691,7 @@ pub struct ArgVia { pub location: Span, pub via: Expr, pub tipo: T, + pub annotation: Option, } impl From> for Arg { diff --git a/crates/aiken-lang/src/parser/definition/snapshots/def_invalid_property_test.snap b/crates/aiken-lang/src/parser/definition/snapshots/def_invalid_property_test.snap index 66cabfe5..e7c37498 100644 --- a/crates/aiken-lang/src/parser/definition/snapshots/def_invalid_property_test.snap +++ b/crates/aiken-lang/src/parser/definition/snapshots/def_invalid_property_test.snap @@ -12,12 +12,13 @@ Test( location: 9..10, is_validator_param: false, }, - location: 9..16, + location: 9..10, via: Var { location: 15..16, name: "f", }, tipo: (), + annotation: None, }, ArgVia { arg_name: Named { @@ -26,12 +27,13 @@ Test( location: 18..19, is_validator_param: false, }, - location: 18..25, + location: 18..19, via: Var { location: 24..25, name: "g", }, tipo: (), + annotation: None, }, ], body: Var { diff --git a/crates/aiken-lang/src/parser/definition/snapshots/def_property_test.snap b/crates/aiken-lang/src/parser/definition/snapshots/def_property_test.snap index b159b1f5..db3b686e 100644 --- a/crates/aiken-lang/src/parser/definition/snapshots/def_property_test.snap +++ b/crates/aiken-lang/src/parser/definition/snapshots/def_property_test.snap @@ -12,7 +12,7 @@ Test( location: 9..10, is_validator_param: false, }, - location: 9..27, + location: 9..10, via: FieldAccess { location: 15..27, label: "any_int", @@ -22,6 +22,7 @@ Test( }, }, tipo: (), + annotation: None, }, ], body: Var { diff --git a/crates/aiken-lang/src/parser/definition/snapshots/def_property_test_annotated_fuzzer.snap b/crates/aiken-lang/src/parser/definition/snapshots/def_property_test_annotated_fuzzer.snap new file mode 100644 index 00000000..295bde81 --- /dev/null +++ b/crates/aiken-lang/src/parser/definition/snapshots/def_property_test_annotated_fuzzer.snap @@ -0,0 +1,55 @@ +--- +source: crates/aiken-lang/src/parser/definition/test.rs +description: "Code:\n\ntest foo(x: Int via foo()) {\n True\n}\n" +--- +Test( + Function { + arguments: [ + ArgVia { + arg_name: Named { + name: "x", + label: "x", + location: 9..10, + is_validator_param: false, + }, + location: 9..15, + via: Call { + arguments: [], + fun: Var { + location: 20..23, + name: "foo", + }, + location: 20..25, + }, + tipo: (), + annotation: Some( + Constructor { + location: 12..15, + module: None, + name: "Int", + arguments: [], + }, + ), + }, + ], + body: Var { + location: 33..37, + name: "True", + }, + doc: None, + location: 0..26, + name: "foo", + public: false, + return_annotation: Some( + Constructor { + location: 0..39, + module: None, + name: "Bool", + arguments: [], + }, + ), + return_type: (), + end_position: 38, + can_error: false, + }, +) diff --git a/crates/aiken-lang/src/parser/definition/test.rs b/crates/aiken-lang/src/parser/definition/test.rs index 748c187e..cbd57a23 100644 --- a/crates/aiken-lang/src/parser/definition/test.rs +++ b/crates/aiken-lang/src/parser/definition/test.rs @@ -4,6 +4,7 @@ use crate::{ ast, expr::UntypedExpr, parser::{ + annotation, chain::{call::parser as call, field_access, tuple_index::parser as tuple_index, Chain}, error::ParseError, expr::{self, var}, @@ -67,11 +68,13 @@ pub fn via() -> impl Parser { } }), )) + .then(just(Token::Colon).ignore_then(annotation()).or_not()) .then_ignore(just(Token::Via)) .then(fuzzer()) - .map_with_span(|(arg_name, via), location| ast::ArgVia { + .map_with_span(|((arg_name, annotation), via), location| ast::ArgVia { arg_name, via, + annotation, tipo: (), location, }) @@ -144,4 +147,15 @@ mod tests { "# ); } + + #[test] + fn def_property_test_annotated_fuzzer() { + assert_definition!( + r#" + test foo(x: Int via foo()) { + True + } + "# + ); + } } diff --git a/crates/aiken-lang/src/tipo/infer.rs b/crates/aiken-lang/src/tipo/infer.rs index 10027676..5c02eb94 100644 --- a/crates/aiken-lang/src/tipo/infer.rs +++ b/crates/aiken-lang/src/tipo/infer.rs @@ -344,9 +344,16 @@ fn infer_definition( let typed_via = ExprTyper::new(environment, lines, tracing).infer(arg.via.clone())?; - let (annotation, inner_type) = infer_fuzzer(&typed_via.tipo(), &arg.location)?; + let (inferred_annotation, inner_type) = + infer_fuzzer(&typed_via.tipo(), &arg.location)?; - Ok((Some((typed_via, inner_type)), Some(annotation))) + if let Some(ref provided_annotation) = arg.annotation { + if !provided_annotation.is_logically_equal(&inferred_annotation) { + todo!("Inferred annotation doesn't match actual annotation.") + } + } + + Ok((Some((typed_via, inner_type)), Some(inferred_annotation))) } None => Ok((None, None)), }?; @@ -401,6 +408,7 @@ fn infer_definition( .to_owned(); vec![ArgVia { + annotation, arg_name, location, tipo,