fix: Discard not taken into account in backpassing

closes #890

Co-authored-by: Kasey White <kwhitemsg@gmail.com>
This commit is contained in:
rvcas 2024-03-20 17:53:17 -04:00
parent 898ef74457
commit 4f8e900aac
No known key found for this signature in database
GPG Key ID: C09B64E263F7D68C
3 changed files with 57 additions and 13 deletions

View File

@ -1300,7 +1300,7 @@ impl UntypedExpr {
}
pub fn lambda(
names: Vec<(String, Span, Option<Annotation>)>,
names: Vec<(ArgName, Span, Option<Annotation>)>,
expressions: Vec<UntypedExpr>,
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 {

View File

@ -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<a>, 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>) -> Int {
let a, _b <- fold(list, 0)
a + 1
}
"#;
let (warnings, _ast) = check(parse(source_code)).unwrap();
assert_eq!(warnings.len(), 0);
}

View File

@ -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));
}
}
}