From 9fb29e99fa6d5cd04ef88786fe188562d76f029d Mon Sep 17 00:00:00 2001 From: prql-bot <107324867+prql-bot@users.noreply.github.com> Date: Sat, 8 Aug 2026 06:49:51 +0000 Subject: [PATCH] fix: backtick parameter names in transform argument errors --- .../prqlc/src/semantic/resolver/transforms.rs | 8 ++-- .../prqlc/tests/integration/error_messages.rs | 46 ++++++++++++++++++- 2 files changed, 49 insertions(+), 5 deletions(-) diff --git a/prqlc/prqlc/src/semantic/resolver/transforms.rs b/prqlc/prqlc/src/semantic/resolver/transforms.rs index 1026f3c0aca2..6860a565c8c4 100644 --- a/prqlc/prqlc/src/semantic/resolver/transforms.rs +++ b/prqlc/prqlc/src/semantic/resolver/transforms.rs @@ -101,7 +101,7 @@ impl Resolver<'_> { let span = side.span; let ident = side.clone().try_cast( ExprKind::into_literal, - Some("side"), + Some("`side`"), "inner, left, right or full", )?; @@ -242,7 +242,7 @@ impl Resolver<'_> { let span = by.span; let ident = by.clone().try_cast( ExprKind::into_literal, - Some("by"), + Some("`by`"), "position or name", )?; @@ -431,7 +431,7 @@ impl Resolver<'_> { let span = take.span; let ident = take.clone().try_cast( ExprKind::into_literal, - Some("take"), + Some("`take`"), "early or late", )?; @@ -526,7 +526,7 @@ impl Resolver<'_> { let res = { let span = format.span; let format = format - .try_cast(ExprKind::into_literal, Some("format"), "csv or json")? + .try_cast(ExprKind::into_literal, Some("`format`"), "csv or json")? .to_string(); match format.as_str() { "\"csv\"" => from_text::parse_csv(&text) diff --git a/prqlc/prqlc/tests/integration/error_messages.rs b/prqlc/prqlc/tests/integration/error_messages.rs index d77fb0180a16..fb898550bbd9 100644 --- a/prqlc/prqlc/tests/integration/error_messages.rs +++ b/prqlc/prqlc/tests/integration/error_messages.rs @@ -562,11 +562,55 @@ fn tuple_uniq_take_wrong() { │ 3 │ select (tuple_uniq take:bar this) │ ─┬─ - │ ╰─── take expected early or late, but found `this.foo.bar` + │ ╰─── `take` expected early or late, but found `this.foo.bar` ───╯ "); } +/// The other three transforms that resolve a parameter to a literal report the +/// parameter name the same way. An s-string reaches the cast without being a +/// literal, which is the path that produces these. +#[test] +fn transform_param_not_a_literal() { + assert_snapshot!(compile(r###" + from x + join y (==id) side:s"left" + "###).unwrap_err(), @r#" + Error: + ╭─[ :3:24 ] + │ + 3 │ join y (==id) side:s"left" + │ ───┬─── + │ ╰───── `side` expected inner, left, right or full, but found `s"left"` + ───╯ + "#); + + assert_snapshot!(compile(r###" + from foo + append by:s"name" baz + "###).unwrap_err(), @r#" + Error: + ╭─[ :3:15 ] + │ + 3 │ append by:s"name" baz + │ ───┬─── + │ ╰───── `by` expected position or name, but found `s"name"` + ───╯ + "#); + + assert_snapshot!(compile(r###" + from_text format:s"csv" "a,b" + "###).unwrap_err(), @r#" + Error: + ╭─[ :2:22 ] + │ + 2 │ from_text format:s"csv" "a,b" + │ ───┬── + │ ╰──── `format` expected csv or json, but found `s"csv"` + ───╯ + "#); +} + #[test] fn append_by_name_wildcard() { assert_snapshot!(compile(r"from foo | append by:name (from bar)").unwrap_err(), @"