diff --git a/crates/aiken-lang/src/expr.rs b/crates/aiken-lang/src/expr.rs index 0ae888d0..5062319d 100644 --- a/crates/aiken-lang/src/expr.rs +++ b/crates/aiken-lang/src/expr.rs @@ -1300,7 +1300,7 @@ impl UntypedExpr { } pub fn lambda( - names: Vec<(String, Span, Option)>, + names: Vec<(ArgName, Span, Option)>, expressions: Vec, location: Span, ) -> Self { @@ -1309,17 +1309,12 @@ impl UntypedExpr { fn_style: FnStyle::Plain, arguments: names .into_iter() - .map(|(name, location, annotation)| Arg { + .map(|(arg_name, location, annotation)| Arg { location, doc: None, annotation, tipo: (), - arg_name: ArgName::Named { - label: name.clone(), - name, - location, - is_validator_param: false, - }, + arg_name, }) .collect(), body: Self::Sequence { diff --git a/crates/aiken-lang/src/tests/check.rs b/crates/aiken-lang/src/tests/check.rs index 23501e35..431515d3 100644 --- a/crates/aiken-lang/src/tests/check.rs +++ b/crates/aiken-lang/src/tests/check.rs @@ -2008,3 +2008,25 @@ fn correct_span_for_backpassing_args() { matches!(&warnings[0], Warning::UnusedVariable { ref name, location } if name == "b" && location.start == 245 && location.end == 246) ); } + +#[test] +fn allow_discard_for_backpassing_args() { + let source_code = r#" + fn fold(list: List, acc: b, f: fn(a, b) -> b) -> b { + when list is { + [] -> acc + [x, ..xs] -> fold(xs, f(x, acc), f) + } + } + + pub fn sum(list: List) -> Int { + let a, _b <- fold(list, 0) + + a + 1 + } + "#; + + let (warnings, _ast) = check(parse(source_code)).unwrap(); + + assert_eq!(warnings.len(), 0); +} diff --git a/crates/aiken-lang/src/tipo/expr.rs b/crates/aiken-lang/src/tipo/expr.rs index 6ed64c7e..8875506a 100644 --- a/crates/aiken-lang/src/tipo/expr.rs +++ b/crates/aiken-lang/src/tipo/expr.rs @@ -1768,14 +1768,41 @@ impl<'a, 'b> ExprTyper<'a, 'b> { // in front of the continuation sequence. This is because we do not support patterns in function argument // (which is perhaps something we should support?). match pattern { - Pattern::Var { name, location: _ } | Pattern::Discard { name, location: _ } - if kind.is_let() => - { - names.push((name.clone(), assignment_pattern_location, annotation)); + Pattern::Var { + name, + location: var_location, + } if kind.is_let() => { + let name = ArgName::Named { + label: name.clone(), + name, + location: var_location, + is_validator_param: false, + }; + + names.push((name, assignment_pattern_location, annotation)); + } + Pattern::Discard { + name, + location: var_location, + } if kind.is_let() => { + let name = ArgName::Discarded { + label: name.clone(), + name, + location: var_location, + }; + + names.push((name, assignment_pattern_location, annotation)); } _ => { let name = format!("{}_{}", ast::BACKPASS_VARIABLE, index); + let arg_name = ArgName::Named { + label: name.clone(), + name: name.clone(), + location: pattern.location(), + is_validator_param: false, + }; + continuation.insert( 0, UntypedExpr::Assignment { @@ -1799,7 +1826,7 @@ impl<'a, 'b> ExprTyper<'a, 'b> { }, ); - names.push((name, assignment_pattern_location, annotation)); + names.push((arg_name, assignment_pattern_location, annotation)); } } }