Repository: polarity-lang/polarity (rust)

Issue:
Missing Argument for parameter error message appears in the wrong spot
```
codata Stream(a : Type) { Stream(a).head(a : Type): a, Stream(a).tail(a : Type): Stream(a) }

codef Ones: Stream {
    .head => S(Z),
    .tail => Ones
}
```

The missing argument for `Stream` in the `codef` appears on the `codata` declaration. instead, it should appear on the `codef` and maybe hint at the type parameter. 

Pull request:
Point to correct location for missing arguments
Fixes #408

Patch:
diff --git a/lang/lowering/src/lower/exp/mod.rs b/lang/lowering/src/lower/exp/mod.rs
index 700e5c32..3811374e 100644
--- a/lang/lowering/src/lower/exp/mod.rs
+++ b/lang/lowering/src/lower/exp/mod.rs
@@ -135,6 +135,7 @@ fn lower_args(
     ///
     /// # Parameters
     ///
+    /// - `span`: The source span of the given argument list.
     /// - `given`: A mutable iterator over the given arguments.
     /// - `expected_bs`: The binding site of the expected parameter.
     /// - `args_out`: A mutable vector to collect the lowered arguments.
@@ -145,6 +146,7 @@ fn lower_args(
     /// - `Ok(())`: The argument was successfully processed and added to `args_out`.
     /// - `Err(LoweringError)`: An error occurred while processing the argument.
     fn pop_arg<'a>(
+        span: Span,
         given: &mut impl Iterator<Item = &'a cst::exp::Arg>,
         expected_bs: &BindingSite,
         args_out: &mut Vec<ast::Arg>,
@@ -153,7 +155,7 @@ fn lower_args(
         let Some(arg) = given.next() else {
             return Err(LoweringError::MissingArgForParam {
                 expected: bs_to_name(expected_bs).to_owned(),
-                span: bs_to_span(expected_bs).to_miette(),
+                span: span.to_miette(),
             });
         };
         match arg {
@@ -197,7 +199,7 @@ fn lower_args(
                         });
                     };
                     if expected_name == given_name {
-                        pop_arg(&mut given_iter, expected_bs, &mut args_out, ctx)?;
+                        pop_arg(span, &mut given_iter, expected_bs, &mut args_out, ctx)?;
                         continue;
                     }
                 }
@@ -216,7 +218,7 @@ fn lower_args(
 
                 args_out.push(ast::Arg::InsertedImplicitArg(hole));
             } else {
-                pop_arg(&mut given_iter, expected_bs, &mut args_out, ctx)?;
+                pop_arg(span, &mut given_iter, expected_bs, &mut args_out, ctx)?;
             }
         }
     }


Test patch:
diff --git a/test/suites/fail-lower/Regr-408.expected b/test/suites/fail-lower/Regr-408.expected
new file mode 100644
index 00000000..2994f356
--- /dev/null
+++ b/test/suites/fail-lower/Regr-408.expected
@@ -0,0 +1,9 @@
+L-013
+
+  × Missing argument for parameter a
+   ╭─[Regr-408.pol:3:13]
+ 2 │ 
+ 3 │ codef Ones: Stream {
+   ·             ───────
+ 4 │     .head => S(Z),
+   ╰────
diff --git a/test/suites/fail-lower/Regr-408.pol b/test/suites/fail-lower/Regr-408.pol
new file mode 100644
index 00000000..9372d26d
--- /dev/null
+++ b/test/suites/fail-lower/Regr-408.pol
@@ -0,0 +1,6 @@
+codata Stream(a : Type) { Stream(a).head(a : Type): a, Stream(a).tail(a : Type): Stream(a) }
+
+codef Ones: Stream {
+    .head => S(Z),
+    .tail => Ones
+}