diff --git a/prqlc/prqlc/src/semantic/resolver/expr.rs b/prqlc/prqlc/src/semantic/resolver/expr.rs index 531c64490c49..47e042434978 100644 --- a/prqlc/prqlc/src/semantic/resolver/expr.rs +++ b/prqlc/prqlc/src/semantic/resolver/expr.rs @@ -189,7 +189,9 @@ impl pl::PlFold for Resolver<'_> { let func = name.try_cast(|n| n.into_func(), None, "a function")?; // fold function - let func = self.apply_args_to_closure(func, args, named_args)?; + let func = self + .apply_args_to_closure(func, args, named_args) + .with_span_fallback(span)?; self.fold_function(func, span)? } diff --git a/prqlc/prqlc/src/semantic/resolver/functions.rs b/prqlc/prqlc/src/semantic/resolver/functions.rs index e7dee639b7a0..f943689fb5d4 100644 --- a/prqlc/prqlc/src/semantic/resolver/functions.rs +++ b/prqlc/prqlc/src/semantic/resolver/functions.rs @@ -203,8 +203,8 @@ impl Resolver<'_> { if let Some((name, _)) = named_args.into_iter().next() { // TODO: report all remaining named_args as separate errors return Err(Error::new_simple(format!( - "unknown named argument `{name}` to closure {:?}", - closure.name_hint + "unknown named argument `{name}` to function `{}`", + closure.as_debug_name() ))); } diff --git a/prqlc/prqlc/tests/integration/bad_error_messages.rs b/prqlc/prqlc/tests/integration/bad_error_messages.rs index 6d76259f6432..2883a620d1a8 100644 --- a/prqlc/prqlc/tests/integration/bad_error_messages.rs +++ b/prqlc/prqlc/tests/integration/bad_error_messages.rs @@ -209,16 +209,6 @@ fn nested_groups() { "); } -#[test] -fn not_with_named_arg() { - // A named argument to `std.not` isn't column-exclusion syntax. Both of these - // used to panic — the first on `exactly_one`, the second on indexing - // `args[0]` with no positional args at all. They're errors now, but the - // message has no span and `Debug`-prints the ident. - assert_snapshot!(compile(r"from x | select (std.not {a} b:1)").unwrap_err(), @r#"Error: unknown named argument `b` to closure Some(["std", "not"])"#); - assert_snapshot!(compile(r"from x | select (std.not b:1)").unwrap_err(), @r#"Error: unknown named argument `b` to closure Some(["std", "not"])"#); -} - #[test] fn just_std() { assert_snapshot!(compile(r###" diff --git a/prqlc/prqlc/tests/integration/error_messages.rs b/prqlc/prqlc/tests/integration/error_messages.rs index 493c72c98f70..ab6f456e6bad 100644 --- a/prqlc/prqlc/tests/integration/error_messages.rs +++ b/prqlc/prqlc/tests/integration/error_messages.rs @@ -558,9 +558,7 @@ fn append_by_name_unnamed() { #[test] fn not_with_extra_args() { // A tuple argument to `std.not` is column-exclusion syntax, but only when - // it's the sole argument — extra args used to panic on `exactly_one`. The - // named-argument forms are in `bad_error_messages::not_with_named_arg`, - // since the message they produce still needs improving. + // it's the sole argument — extra args used to panic on `exactly_one`. assert_snapshot!(compile(r"from x | select (std.not {a} b)").unwrap_err(), @" Error: ╭─[ :1:18 ] @@ -580,3 +578,36 @@ fn not_with_extra_args() { ───╯ "); } + +#[test] +fn unknown_named_arg() { + // A named argument that no parameter matches names the function and points + // at the call site. + assert_snapshot!(compile(r"from x | select (std.not {a} b:1)").unwrap_err(), @" + Error: + ╭─[ :1:18 ] + │ + 1 │ from x | select (std.not {a} b:1) + │ ───────┬─────── + │ ╰───────── unknown named argument `b` to function `not` + ───╯ + "); + assert_snapshot!(compile(r"from x | select (std.not b:1)").unwrap_err(), @" + Error: + ╭─[ :1:18 ] + │ + 1 │ from x | select (std.not b:1) + │ ─────┬───── + │ ╰─────── unknown named argument `b` to function `not` + ───╯ + "); + assert_snapshot!(compile(r"from x | take 1 b:2").unwrap_err(), @" + Error: + ╭─[ :1:10 ] + │ + 1 │ from x | take 1 b:2 + │ ─────┬──── + │ ╰────── unknown named argument `b` to function `take` + ───╯ + "); +}