From bbb0a7b9599da15e4f9fd75115c3112ef7078f43 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 25 Mar 2026 11:38:47 +0000 Subject: [PATCH 1/4] fix: preserve parentheses for single-element type packs in explicit type instantiation Fixes #1089. `f<<(number)>>(10)` was incorrectly formatted to `f<>(10)`, changing the semantics from a type pack to a plain type, which is a type error. The fix applies `within_generic` context when formatting types inside `<<...>>` type instantiation syntax, matching the same parentheses-preservation logic used for generic type parameters (e.g. `Foo<(string)>`). https://claude.ai/code/session_01TtJr824SDTbkw5ZEmYGQNm --- src/formatters/luau.rs | 10 +++++++++- .../type-instantiation-type-pack.lua | 14 +++++++++++++ ...luau@type-instantiation-type-pack.lua.snap | 20 +++++++++++++++++++ 3 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 tests/inputs-luau/type-instantiation-type-pack.lua create mode 100644 tests/snapshots/tests__luau@type-instantiation-type-pack.lua.snap diff --git a/src/formatters/luau.rs b/src/formatters/luau.rs index bfc09dc5..7ca95d17 100644 --- a/src/formatters/luau.rs +++ b/src/formatters/luau.rs @@ -1505,7 +1505,15 @@ pub fn format_type_instantiation( ) -> TypeInstantiation { let outer_arrows = format_contained_span(ctx, type_instantiation.outer_arrows(), shape); let inner_arrows = format_contained_span(ctx, type_instantiation.inner_arrows(), shape); - let types = format_punctuated(ctx, type_instantiation.types(), shape, format_type_info); + // Use within_generic context so single-element type packs like `(number)` preserve + // their parentheses (e.g. `f<<(number)>>(10)` must not become `f<>(10)`) + let context = TypeInfoContext::new().mark_within_generic(); + let types = format_punctuated( + ctx, + type_instantiation.types(), + shape, + |ctx, type_info, shape| format_type_info_internal(ctx, type_info, context, shape), + ); type_instantiation .to_owned() diff --git a/tests/inputs-luau/type-instantiation-type-pack.lua b/tests/inputs-luau/type-instantiation-type-pack.lua new file mode 100644 index 00000000..6f178ba8 --- /dev/null +++ b/tests/inputs-luau/type-instantiation-type-pack.lua @@ -0,0 +1,14 @@ +-- https://github.com/JohnnyMorganz/StyLua/issues/1089 +-- Single-element type packs in explicit type instantiation should preserve parentheses + +local function f(...: T...) end + +-- Single type pack: parentheses must be preserved (otherwise it becomes a type error) +f<<(number)>>(10) + +-- Multi-element type packs already work, but test for completeness +f<<(string, number)>>(10, "a") + +-- Method call variant +local t = {} +t:method<<(number)>>(10) diff --git a/tests/snapshots/tests__luau@type-instantiation-type-pack.lua.snap b/tests/snapshots/tests__luau@type-instantiation-type-pack.lua.snap new file mode 100644 index 00000000..4ea3a4e5 --- /dev/null +++ b/tests/snapshots/tests__luau@type-instantiation-type-pack.lua.snap @@ -0,0 +1,20 @@ +--- +source: tests/tests.rs +expression: "format(&contents, LuaVersion::Luau)" +input_file: tests/inputs-luau/type-instantiation-type-pack.lua +--- +-- https://github.com/JohnnyMorganz/StyLua/issues/1089 +-- Single-element type packs in explicit type instantiation should preserve parentheses + +local function f(...: T...) end + +-- Single type pack: parentheses must be preserved (otherwise it becomes a type error) +f<<(number)>>(10) + +-- Multi-element type packs already work, but test for completeness +f<<(string, number)>>(10, "a") + +-- Method call variant +local t = {} +t:method<<(number)>>(10) + From 489a82bac96d044f2bc09eca9362a5c9c7e50535 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 25 Mar 2026 11:46:48 +0000 Subject: [PATCH 2/4] test: remove explanatory comments from type-instantiation-type-pack test https://claude.ai/code/session_01TtJr824SDTbkw5ZEmYGQNm --- tests/inputs-luau/type-instantiation-type-pack.lua | 5 ----- .../tests__luau@type-instantiation-type-pack.lua.snap | 5 ----- 2 files changed, 10 deletions(-) diff --git a/tests/inputs-luau/type-instantiation-type-pack.lua b/tests/inputs-luau/type-instantiation-type-pack.lua index 6f178ba8..c62057cb 100644 --- a/tests/inputs-luau/type-instantiation-type-pack.lua +++ b/tests/inputs-luau/type-instantiation-type-pack.lua @@ -1,14 +1,9 @@ -- https://github.com/JohnnyMorganz/StyLua/issues/1089 --- Single-element type packs in explicit type instantiation should preserve parentheses local function f(...: T...) end --- Single type pack: parentheses must be preserved (otherwise it becomes a type error) f<<(number)>>(10) - --- Multi-element type packs already work, but test for completeness f<<(string, number)>>(10, "a") --- Method call variant local t = {} t:method<<(number)>>(10) diff --git a/tests/snapshots/tests__luau@type-instantiation-type-pack.lua.snap b/tests/snapshots/tests__luau@type-instantiation-type-pack.lua.snap index 4ea3a4e5..e11ec69a 100644 --- a/tests/snapshots/tests__luau@type-instantiation-type-pack.lua.snap +++ b/tests/snapshots/tests__luau@type-instantiation-type-pack.lua.snap @@ -4,17 +4,12 @@ expression: "format(&contents, LuaVersion::Luau)" input_file: tests/inputs-luau/type-instantiation-type-pack.lua --- -- https://github.com/JohnnyMorganz/StyLua/issues/1089 --- Single-element type packs in explicit type instantiation should preserve parentheses local function f(...: T...) end --- Single type pack: parentheses must be preserved (otherwise it becomes a type error) f<<(number)>>(10) - --- Multi-element type packs already work, but test for completeness f<<(string, number)>>(10, "a") --- Method call variant local t = {} t:method<<(number)>>(10) From 8c428790129524a305839f1b56d2c0c9a816b12a Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 25 Mar 2026 19:53:41 +0000 Subject: [PATCH 3/4] style: remove comment from format_type_instantiation https://claude.ai/code/session_01TtJr824SDTbkw5ZEmYGQNm --- src/formatters/luau.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/formatters/luau.rs b/src/formatters/luau.rs index 7ca95d17..39ee231a 100644 --- a/src/formatters/luau.rs +++ b/src/formatters/luau.rs @@ -1505,8 +1505,6 @@ pub fn format_type_instantiation( ) -> TypeInstantiation { let outer_arrows = format_contained_span(ctx, type_instantiation.outer_arrows(), shape); let inner_arrows = format_contained_span(ctx, type_instantiation.inner_arrows(), shape); - // Use within_generic context so single-element type packs like `(number)` preserve - // their parentheses (e.g. `f<<(number)>>(10)` must not become `f<>(10)`) let context = TypeInfoContext::new().mark_within_generic(); let types = format_punctuated( ctx, From e8dabf58e621674eda868ea9a66a10b4a327ac97 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 25 Mar 2026 20:02:30 +0000 Subject: [PATCH 4/4] chore: update changelog for #1089 fix https://claude.ai/code/session_01TtJr824SDTbkw5ZEmYGQNm --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0fbe20f0..09183009 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - Luau: Fixed panic when formatting explicit type instantiation (`f<>()`) inside a nested function call argument (e.g. as a callback) ([#1088](https://github.com/JohnnyMorganz/StyLua/issues/1088)) +- Luau: Fixed parentheses being incorrectly removed from single-element type packs in explicit type instantiation, e.g. `f<<(number)>>(10)` becoming `f<>(10)` ([#1089](https://github.com/JohnnyMorganz/StyLua/issues/1089)) ## [2.4.0] - 2026-03-07