Skip to content

feat: Simple Object destructuring in GPU functions - #2913

Draft
vende11s wants to merge 11 commits into
mainfrom
feat/destructuring-objects
Draft

vende11s wants to merge 11 commits into
mainfrom
feat/destructuring-objects

Conversation

@vende11s

@vende11s vende11s commented Aug 24, 2026 •

Copy link
Copy Markdown
Collaborator

Adds #2318

Allows simple object destructuring like:

 const { a, b: renamed } = createPair();

or

const pair = Pair({ a: 2, b: 3 });
const { a, b: c } = pair;

which generates:

let destructured = createPair();
let a = destructured.a;
let renamed = destructured.b;

and

let pair = Pair(2i, 3i);
let a = pair.a;
let c = pair.b;

This PR introduces a breaking change for FuncParameters in tinyest-for-wgsl:

// Before
params: [{ type: 'i', name: 'x' }]

// After
params: ['x']

In tinyest, FuncParameter accepts both legacy parameters and BindingPattern during the transition. typegpu normalizes legacy metadata, but users of tinyest-for-wgsl parser need to handle the new representation

@github-actions

github-actions Bot commented Aug 24, 2026 •

Copy link
Copy Markdown

pkg.pr.new

packages
Ready to be installed by your favorite package manager ⬇️

https://pkg.pr.new/software-mansion/TypeGPU/eslint-plugin-typegpu@817b32b6b1bf972e7527c44df1978d9a66584330
https://pkg.pr.new/software-mansion/TypeGPU/tgpu-gen@817b32b6b1bf972e7527c44df1978d9a66584330
https://pkg.pr.new/software-mansion/TypeGPU/tinyest@817b32b6b1bf972e7527c44df1978d9a66584330
https://pkg.pr.new/software-mansion/TypeGPU/tinyest-for-wgsl@817b32b6b1bf972e7527c44df1978d9a66584330
https://pkg.pr.new/software-mansion/TypeGPU/typegpu@817b32b6b1bf972e7527c44df1978d9a66584330
https://pkg.pr.new/software-mansion/TypeGPU/@typegpu/cli@817b32b6b1bf972e7527c44df1978d9a66584330
https://pkg.pr.new/software-mansion/TypeGPU/@typegpu/gl@817b32b6b1bf972e7527c44df1978d9a66584330
https://pkg.pr.new/software-mansion/TypeGPU/unplugin-typegpu@817b32b6b1bf972e7527c44df1978d9a66584330

benchmark
view benchmark

commit
view commit

@github-actions

github-actions Bot commented Aug 24, 2026 •

Copy link
Copy Markdown

Bundle size comparison (import * as ... in PR vs import * as ... in target):

🟢 Decreased (max -12.36%) ➖ Unchanged 🔴 Increased (max 1.26%) ❔ Unknown
1 38 316 0

import * as ... in PR vs import * as ... in target (did bundle size increase?):

Click to reveal the results table (306 entries).
Test tsdown
d_bool.ts 20.29 kB ($${\color{red}+1.3\%}$$)
d_f16.ts 20.29 kB ($${\color{red}+1.3\%}$$)
d_f32.ts 20.29 kB ($${\color{red}+1.3\%}$$)
d_i32.ts 20.29 kB ($${\color{red}+1.3\%}$$)
d_u32.ts 20.29 kB ($${\color{red}+1.3\%}$$)
d_ref.ts 20.30 kB ($${\color{red}+1.3\%}$$)
d_u16.ts 20.31 kB ($${\color{red}+1.3\%}$$)
d_abstractInt.ts 20.37 kB ($${\color{red}+1.3\%}$$)
d_abstractFloat.ts 20.37 kB ($${\color{red}+1.3\%}$$)
d_textureDepth2d.ts 20.74 kB ($${\color{red}+1.2\%}$$)
d_textureDepthCube.ts 20.74 kB ($${\color{red}+1.2\%}$$)
d_texture1d.ts 20.75 kB ($${\color{red}+1.2\%}$$)
d_texture2d.ts 20.75 kB ($${\color{red}+1.2\%}$$)
d_texture3d.ts 20.75 kB ($${\color{red}+1.2\%}$$)
d_textureCube.ts 20.75 kB ($${\color{red}+1.2\%}$$)
d_textureDepth2dArray.ts 20.75 kB ($${\color{red}+1.2\%}$$)
d_textureDepthCubeArray.ts 20.76 kB ($${\color{red}+1.2\%}$$)
d_textureDepthMultisampled2d.ts 20.76 kB ($${\color{red}+1.2\%}$$)
d_texture2dArray.ts 20.76 kB ($${\color{red}+1.2\%}$$)
d_textureCubeArray.ts 20.77 kB ($${\color{red}+1.2\%}$$)
d_textureMultisampled2d.ts 20.77 kB ($${\color{red}+1.2\%}$$)
std_isKnownAtComptime.ts 20.91 kB ($${\color{red}+1.2\%}$$)
std_subgroupElect.ts 21.48 kB ($${\color{red}+1.2\%}$$)
std_subgroupAll.ts 21.49 kB ($${\color{red}+1.2\%}$$)
std_subgroupAny.ts 21.49 kB ($${\color{red}+1.2\%}$$)
std_quadSwapX.ts 21.49 kB ($${\color{red}+1.2\%}$$)
std_quadSwapY.ts 21.49 kB ($${\color{red}+1.2\%}$$)
std_subgroupOr.ts 21.49 kB ($${\color{red}+1.2\%}$$)
std_subgroupAdd.ts 21.49 kB ($${\color{red}+1.2\%}$$)
std_subgroupAnd.ts 21.49 kB ($${\color{red}+1.2\%}$$)
std_subgroupMax.ts 21.49 kB ($${\color{red}+1.2\%}$$)
std_subgroupMin.ts 21.49 kB ($${\color{red}+1.2\%}$$)
std_subgroupMul.ts 21.49 kB ($${\color{red}+1.2\%}$$)
std_subgroupXor.ts 21.49 kB ($${\color{red}+1.2\%}$$)
std_quadSwapDiagonal.ts 21.50 kB ($${\color{red}+1.2\%}$$)
std_subgroupExclusiveAdd.ts 21.51 kB ($${\color{red}+1.2\%}$$)
std_subgroupExclusiveMul.ts 21.51 kB ($${\color{red}+1.2\%}$$)
std_subgroupInclusiveAdd.ts 21.51 kB ($${\color{red}+1.2\%}$$)
std_subgroupInclusiveMul.ts 21.51 kB ($${\color{red}+1.2\%}$$)
std_subgroupBroadcastFirst.ts 21.51 kB ($${\color{red}+1.2\%}$$)
std_storageBarrier.ts 21.53 kB ($${\color{red}+1.2\%}$$)
std_textureBarrier.ts 21.53 kB ($${\color{red}+1.2\%}$$)
std_workgroupBarrier.ts 21.54 kB ($${\color{red}+1.2\%}$$)
std_discard.ts 21.55 kB ($${\color{red}+1.2\%}$$)
std_textureNumLayers.ts 21.56 kB ($${\color{red}+1.2\%}$$)
std_textureNumLevels.ts 21.56 kB ($${\color{red}+1.2\%}$$)
std_textureNumSamples.ts 21.57 kB ($${\color{red}+1.2\%}$$)
std_textureSampleCompare.ts 21.59 kB ($${\color{red}+1.2\%}$$)
std_textureSampleCompareLevel.ts 21.61 kB ($${\color{red}+1.2\%}$$)
std_textureStore.ts 21.61 kB ($${\color{red}+1.2\%}$$)
std_workgroupUniformLoad.ts 21.63 kB ($${\color{red}+1.2\%}$$)
tgpu_comptime.ts 21.65 kB ($${\color{red}+1.2\%}$$)
std_atomicLoad.ts 21.67 kB ($${\color{red}+1.2\%}$$)
std_atomicOr.ts 21.71 kB ($${\color{red}+1.2\%}$$)
std_atomicAdd.ts 21.71 kB ($${\color{red}+1.2\%}$$)
std_atomicAnd.ts 21.71 kB ($${\color{red}+1.2\%}$$)
std_atomicMax.ts 21.71 kB ($${\color{red}+1.2\%}$$)
std_atomicMin.ts 21.71 kB ($${\color{red}+1.2\%}$$)
std_atomicSub.ts 21.71 kB ($${\color{red}+1.2\%}$$)
std_atomicXor.ts 21.71 kB ($${\color{red}+1.2\%}$$)
std_atomicExchange.ts 21.72 kB ($${\color{red}+1.2\%}$$)
std_atomicStore.ts 21.76 kB ($${\color{red}+1.2\%}$$)
std_quadBroadcast.ts 21.76 kB ($${\color{red}+1.2\%}$$)
std_arrayLength.ts 21.76 kB ($${\color{red}+1.2\%}$$)
std_subgroupShuffleUp.ts 21.76 kB ($${\color{red}+1.2\%}$$)
std_subgroupShuffle.ts 21.76 kB ($${\color{red}+1.2\%}$$)
std_subgroupShuffleXor.ts 21.76 kB ($${\color{red}+1.2\%}$$)
std_subgroupShuffleDown.ts 21.77 kB ($${\color{red}+1.2\%}$$)
std_subgroupBroadcast.ts 21.77 kB ($${\color{red}+1.2\%}$$)
std_copy.ts 21.79 kB ($${\color{red}+1.2\%}$$)
std_extensionEnabled.ts 21.86 kB ($${\color{red}+1.2\%}$$)
std_range.ts 22.13 kB ($${\color{red}+1.2\%}$$)
std_isBeingTranspiled.ts 22.17 kB ($${\color{red}+1.2\%}$$)
std_getShaderStage.ts 22.23 kB ($${\color{red}+1.2\%}$$)
std_getTargetShaderLanguage.ts 22.24 kB ($${\color{red}+1.2\%}$$)
std_typeOf.ts 22.28 kB ($${\color{red}+1.1\%}$$)
d_disarrayOf.ts 22.35 kB ($${\color{red}+1.1\%}$$)
d_deepEqual.ts 23.00 kB ($${\color{red}+1.1\%}$$)
d_schemasEqualNominally.ts 23.00 kB ($${\color{red}+1.1\%}$$)
d_schemasEqualStructurally.ts 23.00 kB ($${\color{red}+1.1\%}$$)
std_atomicCompareExchangeWeak.ts 24.31 kB ($${\color{red}+1.1\%}$$)
tgpu_computeFn.ts 46.64 kB ($${\color{red}+1.0\%}$$)
tgpu_vertexFn.ts 47.19 kB ($${\color{red}+1.0\%}$$)
tgpu_fragmentFn.ts 47.37 kB ($${\color{red}+1.0\%}$$)
tgpu_fn.ts 47.49 kB ($${\color{red}+1.0\%}$$)
common_fullScreenTriangle.ts 49.19 kB ($${\color{red}+0.9\%}$$)
std_subgroupBallot.ts 27.96 kB ($${\color{red}+0.9\%}$$)
std_textureSampleBaseClampToEdge.ts 28.05 kB ($${\color{red}+0.9\%}$$)
std_textureSampleGrad.ts 28.06 kB ($${\color{red}+0.9\%}$$)
std_textureSampleBias.ts 28.11 kB ($${\color{red}+0.9\%}$$)
std_textureSample.ts 28.13 kB ($${\color{red}+0.9\%}$$)
std_textureSampleLevel.ts 28.14 kB ($${\color{red}+0.9\%}$$)
std_textureGatherCompare.ts 28.18 kB ($${\color{red}+0.9\%}$$)
std_textureDimensions.ts 28.20 kB ($${\color{red}+0.9\%}$$)
d_uint8.ts 28.25 kB ($${\color{red}+0.9\%}$$)
d_float16.ts 28.25 kB ($${\color{red}+0.9\%}$$)
d_float16x2.ts 28.25 kB ($${\color{red}+0.9\%}$$)
d_float16x4.ts 28.25 kB ($${\color{red}+0.9\%}$$)
d_float32.ts 28.25 kB ($${\color{red}+0.9\%}$$)
d_float32x2.ts 28.25 kB ($${\color{red}+0.9\%}$$)
d_float32x3.ts 28.25 kB ($${\color{red}+0.9\%}$$)
d_float32x4.ts 28.25 kB ($${\color{red}+0.9\%}$$)
d_sint16.ts 28.25 kB ($${\color{red}+0.9\%}$$)
d_sint16x2.ts 28.25 kB ($${\color{red}+0.9\%}$$)
d_sint16x4.ts 28.25 kB ($${\color{red}+0.9\%}$$)
d_sint32.ts 28.25 kB ($${\color{red}+0.9\%}$$)
d_sint32x2.ts 28.25 kB ($${\color{red}+0.9\%}$$)
d_sint32x3.ts 28.25 kB ($${\color{red}+0.9\%}$$)
d_sint32x4.ts 28.25 kB ($${\color{red}+0.9\%}$$)
d_sint8.ts 28.25 kB ($${\color{red}+0.9\%}$$)
d_sint8x2.ts 28.25 kB ($${\color{red}+0.9\%}$$)
d_sint8x4.ts 28.25 kB ($${\color{red}+0.9\%}$$)
d_snorm16.ts 28.25 kB ($${\color{red}+0.9\%}$$)
d_snorm16x2.ts 28.25 kB ($${\color{red}+0.9\%}$$)
d_snorm16x4.ts 28.25 kB ($${\color{red}+0.9\%}$$)
d_snorm8.ts 28.25 kB ($${\color{red}+0.9\%}$$)
d_snorm8x2.ts 28.25 kB ($${\color{red}+0.9\%}$$)
d_snorm8x4.ts 28.25 kB ($${\color{red}+0.9\%}$$)
d_uint16.ts 28.25 kB ($${\color{red}+0.9\%}$$)
d_uint16x2.ts 28.25 kB ($${\color{red}+0.9\%}$$)
d_uint16x4.ts 28.25 kB ($${\color{red}+0.9\%}$$)
d_uint32.ts 28.25 kB ($${\color{red}+0.9\%}$$)
d_uint32x2.ts 28.25 kB ($${\color{red}+0.9\%}$$)
d_uint32x3.ts 28.25 kB ($${\color{red}+0.9\%}$$)
d_uint32x4.ts 28.25 kB ($${\color{red}+0.9\%}$$)
d_uint8x2.ts 28.25 kB ($${\color{red}+0.9\%}$$)
d_uint8x4.ts 28.25 kB ($${\color{red}+0.9\%}$$)
d_unorm10_10_10_2.ts 28.25 kB ($${\color{red}+0.9\%}$$)
d_unorm16.ts 28.25 kB ($${\color{red}+0.9\%}$$)
d_unorm16x2.ts 28.25 kB ($${\color{red}+0.9\%}$$)
d_unorm16x4.ts 28.25 kB ($${\color{red}+0.9\%}$$)
d_unorm8.ts 28.25 kB ($${\color{red}+0.9\%}$$)
d_unorm8x2.ts 28.25 kB ($${\color{red}+0.9\%}$$)
d_unorm8x4.ts 28.25 kB ($${\color{red}+0.9\%}$$)
d_unorm8x4_bgra.ts 28.25 kB ($${\color{red}+0.9\%}$$)
d_formatToWGSLType.ts 28.25 kB ($${\color{red}+0.9\%}$$)
std_textureGather.ts 28.37 kB ($${\color{red}+0.9\%}$$)
d_packedFormats.ts 28.27 kB ($${\color{red}+0.9\%}$$)
d_isPackedData.ts 28.32 kB ($${\color{red}+0.9\%}$$)
std_textureLoad.ts 29.99 kB ($${\color{red}+0.9\%}$$)
d_alignmentOf.ts 30.11 kB ($${\color{red}+0.9\%}$$)
std_bitcast.ts 30.77 kB ($${\color{red}+0.8\%}$$)
STATIC_common.ts 56.74 kB ($${\color{red}+0.8\%}$$)
std_pack2x16float.ts 31.78 kB ($${\color{red}+0.8\%}$$)
std_unpack2x16unorm.ts 31.78 kB ($${\color{red}+0.8\%}$$)
std_unpack2x16float.ts 31.79 kB ($${\color{red}+0.8\%}$$)
std_pack4xI8.ts 31.80 kB ($${\color{red}+0.8\%}$$)
std_unpack4xI8.ts 31.80 kB ($${\color{red}+0.8\%}$$)
std_pack4xU8.ts 31.80 kB ($${\color{red}+0.8\%}$$)
std_unpack4xU8.ts 31.80 kB ($${\color{red}+0.8\%}$$)
std_unpack2x16snorm.ts 31.81 kB ($${\color{red}+0.8\%}$$)
std_unpack4x8unorm.ts 31.83 kB ($${\color{red}+0.8\%}$$)
std_unpack4x8snorm.ts 31.87 kB ($${\color{red}+0.8\%}$$)
std_pack2x16snorm.ts 31.96 kB ($${\color{red}+0.8\%}$$)
std_pack2x16unorm.ts 31.96 kB ($${\color{red}+0.8\%}$$)
std_pack4xU8Clamp.ts 31.97 kB ($${\color{red}+0.8\%}$$)
std_pack4xI8Clamp.ts 31.98 kB ($${\color{red}+0.8\%}$$)
std_pack4x8snorm.ts 32.04 kB ($${\color{red}+0.8\%}$$)
std_pack4x8unorm.ts 32.04 kB ($${\color{red}+0.8\%}$$)
d_sizeOf.ts 32.90 kB ($${\color{red}+0.8\%}$$)
d_isContiguous.ts 32.91 kB ($${\color{red}+0.8\%}$$)
d_getLongestContiguousPrefix.ts 32.92 kB ($${\color{red}+0.8\%}$$)
d_isBuiltin.ts 33.00 kB ($${\color{red}+0.8\%}$$)
d_arrayOf.ts 33.79 kB ($${\color{red}+0.8\%}$$)
std_identity2.ts 34.46 kB ($${\color{red}+0.7\%}$$)
std_identity3.ts 34.46 kB ($${\color{red}+0.7\%}$$)
std_identity4.ts 34.46 kB ($${\color{red}+0.7\%}$$)
std_rotationX4.ts 34.46 kB ($${\color{red}+0.7\%}$$)
std_rotationY4.ts 34.46 kB ($${\color{red}+0.7\%}$$)
std_rotationZ4.ts 34.46 kB ($${\color{red}+0.7\%}$$)
std_scaling4.ts 34.46 kB ($${\color{red}+0.7\%}$$)
std_translation4.ts 34.46 kB ($${\color{red}+0.7\%}$$)
d_matToArray.ts 34.60 kB ($${\color{red}+0.7\%}$$)
d_size.ts 34.66 kB ($${\color{red}+0.7\%}$$)
d_align.ts 34.66 kB ($${\color{red}+0.7\%}$$)
d_location.ts 34.67 kB ($${\color{red}+0.7\%}$$)
d_interpolate.ts 34.67 kB ($${\color{red}+0.7\%}$$)
tgpu_vertexLayout.ts 34.93 kB ($${\color{red}+0.7\%}$$)
d_invariant.ts 35.04 kB ($${\color{red}+0.7\%}$$)
common_writeSoA.ts 35.52 kB ($${\color{red}+0.7\%}$$)
std_dot4I8Packed.ts 35.85 kB ($${\color{red}+0.7\%}$$)
std_dot4U8Packed.ts 35.85 kB ($${\color{red}+0.7\%}$$)
std_firstLeadingBit.ts 35.86 kB ($${\color{red}+0.7\%}$$)
std_determinant.ts 35.94 kB ($${\color{red}+0.7\%}$$)
std_dpdxFine.ts 35.94 kB ($${\color{red}+0.7\%}$$)
std_dpdyFine.ts 35.94 kB ($${\color{red}+0.7\%}$$)
std_dpdxCoarse.ts 35.94 kB ($${\color{red}+0.7\%}$$)
std_dpdyCoarse.ts 35.94 kB ($${\color{red}+0.7\%}$$)
std_fwidthFine.ts 35.94 kB ($${\color{red}+0.7\%}$$)
std_dpdx.ts 35.94 kB ($${\color{red}+0.7\%}$$)
std_dpdy.ts 35.94 kB ($${\color{red}+0.7\%}$$)
std_fwidthCoarse.ts 35.94 kB ($${\color{red}+0.7\%}$$)
std_fwidth.ts 35.95 kB ($${\color{red}+0.7\%}$$)
std_refract.ts 35.95 kB ($${\color{red}+0.7\%}$$)
std_trunc.ts 36.00 kB ($${\color{red}+0.7\%}$$)
std_reverseBits.ts 36.01 kB ($${\color{red}+0.7\%}$$)
std_quantizeToF16.ts 36.01 kB ($${\color{red}+0.7\%}$$)
std_countOneBits.ts 36.01 kB ($${\color{red}+0.7\%}$$)
std_extractBits.ts 36.02 kB ($${\color{red}+0.7\%}$$)
std_firstTrailingBit.ts 36.02 kB ($${\color{red}+0.7\%}$$)
std_countLeadingZeros.ts 36.03 kB ($${\color{red}+0.7\%}$$)
std_countTrailingZeros.ts 36.03 kB ($${\color{red}+0.7\%}$$)
std_insertBits.ts 36.03 kB ($${\color{red}+0.7\%}$$)
std_faceForward.ts 36.03 kB ($${\color{red}+0.7\%}$$)
std_intdiv.ts 36.04 kB ($${\color{red}+0.7\%}$$)
std_tan.ts 36.08 kB ($${\color{red}+0.7\%}$$)
std_degrees.ts 36.09 kB ($${\color{red}+0.7\%}$$)
std_radians.ts 36.09 kB ($${\color{red}+0.7\%}$$)
std_inverseSqrt.ts 36.12 kB ($${\color{red}+0.7\%}$$)
std_round.ts 36.13 kB ($${\color{red}+0.7\%}$$)
std_step.ts 36.26 kB ($${\color{red}+0.7\%}$$)
std_ldexp.ts 36.26 kB ($${\color{red}+0.7\%}$$)
std_fma.ts 36.27 kB ($${\color{red}+0.7\%}$$)
std_transpose.ts 36.33 kB ($${\color{red}+0.7\%}$$)
d_builtin.ts 36.31 kB ($${\color{red}+0.7\%}$$)
std_not.ts 36.49 kB ($${\color{red}+0.7\%}$$)
d_memoryLayoutOf.ts 36.49 kB ($${\color{red}+0.7\%}$$)
std_abs.ts 36.50 kB ($${\color{red}+0.7\%}$$)
std_neg.ts 36.55 kB ($${\color{red}+0.7\%}$$)
std_or.ts 36.56 kB ($${\color{red}+0.7\%}$$)
std_and.ts 36.64 kB ($${\color{red}+0.7\%}$$)
std_lt.ts 36.65 kB ($${\color{red}+0.7\%}$$)
std_eq.ts 36.65 kB ($${\color{red}+0.7\%}$$)
std_cos.ts 36.67 kB ($${\color{red}+0.7\%}$$)
std_exp.ts 36.67 kB ($${\color{red}+0.7\%}$$)
std_log.ts 36.67 kB ($${\color{red}+0.7\%}$$)
std_sin.ts 36.67 kB ($${\color{red}+0.7\%}$$)
std_exp2.ts 36.67 kB ($${\color{red}+0.7\%}$$)
std_sign.ts 36.67 kB ($${\color{red}+0.7\%}$$)
std_acos.ts 36.67 kB ($${\color{red}+0.7\%}$$)
std_asin.ts 36.67 kB ($${\color{red}+0.7\%}$$)
std_atan.ts 36.67 kB ($${\color{red}+0.7\%}$$)
std_ceil.ts 36.67 kB ($${\color{red}+0.7\%}$$)
std_cosh.ts 36.67 kB ($${\color{red}+0.7\%}$$)
std_log2.ts 36.67 kB ($${\color{red}+0.7\%}$$)
std_sinh.ts 36.67 kB ($${\color{red}+0.7\%}$$)
std_sqrt.ts 36.67 kB ($${\color{red}+0.7\%}$$)
std_tanh.ts 36.67 kB ($${\color{red}+0.7\%}$$)
std_acosh.ts 36.68 kB ($${\color{red}+0.7\%}$$)
std_asinh.ts 36.68 kB ($${\color{red}+0.7\%}$$)
std_atanh.ts 36.68 kB ($${\color{red}+0.7\%}$$)
std_floor.ts 36.68 kB ($${\color{red}+0.7\%}$$)
std_fract.ts 36.68 kB ($${\color{red}+0.7\%}$$)
std_ge.ts 36.71 kB ($${\color{red}+0.7\%}$$)
std_ne.ts 36.72 kB ($${\color{red}+0.7\%}$$)
std_gt.ts 36.87 kB ($${\color{red}+0.7\%}$$)
std_le.ts 36.79 kB ($${\color{red}+0.7\%}$$)
std_saturate.ts 36.82 kB ($${\color{red}+0.7\%}$$)
std_pow.ts 36.85 kB ($${\color{red}+0.7\%}$$)
std_atan2.ts 36.86 kB ($${\color{red}+0.7\%}$$)
std_clamp.ts 36.95 kB ($${\color{red}+0.7\%}$$)
tgpu_accessor.ts 68.40 kB ($${\color{red}+0.7\%}$$)
std_max.ts 36.97 kB ($${\color{red}+0.7\%}$$)
std_min.ts 36.97 kB ($${\color{red}+0.7\%}$$)
tgpu_mutableAccessor.ts 68.40 kB ($${\color{red}+0.7\%}$$)
std_smoothstep.ts 37.07 kB ($${\color{red}+0.7\%}$$)
std_mix.ts 37.22 kB ($${\color{red}+0.7\%}$$)
std_mod.ts 37.50 kB ($${\color{red}+0.7\%}$$)
std_div.ts 37.55 kB ($${\color{red}+0.7\%}$$)
std_select.ts 37.47 kB ($${\color{red}+0.7\%}$$)
std_add.ts 37.62 kB ($${\color{red}+0.7\%}$$)
tgpu_resolveWithContext.ts 161.49 kB ($${\color{red}+0.7\%}$$)
tgpu_resolve.ts 161.56 kB ($${\color{red}+0.7\%}$$)
std_frexp.ts 38.58 kB ($${\color{red}+0.7\%}$$)
std_modf.ts 38.71 kB ($${\color{red}+0.7\%}$$)
std_bitShiftLeft.ts 39.81 kB ($${\color{red}+0.6\%}$$)
std_bitShiftRight.ts 39.81 kB ($${\color{red}+0.6\%}$$)
std_all.ts 39.82 kB ($${\color{red}+0.6\%}$$)
std_length.ts 40.20 kB ($${\color{red}+0.6\%}$$)
std_dot.ts 40.10 kB ($${\color{red}+0.6\%}$$)
std_cross.ts 40.31 kB ($${\color{red}+0.6\%}$$)
std_any.ts 40.64 kB ($${\color{red}+0.6\%}$$)
std_allEq.ts 40.85 kB ($${\color{red}+0.6\%}$$)
std_isCloseTo.ts 41.13 kB ($${\color{red}+0.6\%}$$)
std_normalize.ts 41.22 kB ($${\color{red}+0.6\%}$$)
std_bitcastF32toU32.ts 42.01 kB ($${\color{red}+0.6\%}$$)
std_bitcastU32toF32.ts 42.01 kB ($${\color{red}+0.6\%}$$)
std_bitcastU32toI32.ts 42.01 kB ($${\color{red}+0.6\%}$$)
std_mul.ts 42.24 kB ($${\color{red}+0.6\%}$$)
std_rotateZ4.ts 42.50 kB ($${\color{red}+0.6\%}$$)
std_translate4.ts 42.50 kB ($${\color{red}+0.6\%}$$)
std_scale4.ts 42.50 kB ($${\color{red}+0.6\%}$$)
std_rotateX4.ts 42.51 kB ($${\color{red}+0.6\%}$$)
std_rotateY4.ts 42.51 kB ($${\color{red}+0.6\%}$$)
std_sub.ts 42.62 kB ($${\color{red}+0.6\%}$$)
std_reflect.ts 43.30 kB ($${\color{red}+0.6\%}$$)
std_distance.ts 43.39 kB ($${\color{red}+0.6\%}$$)
d_mat4x4f.ts 47.76 kB ($${\color{red}+0.5\%}$$)
d_vec2b.ts 47.76 kB ($${\color{red}+0.5\%}$$)
d_vec2u.ts 47.76 kB ($${\color{red}+0.5\%}$$)
d_vec3b.ts 47.76 kB ($${\color{red}+0.5\%}$$)
d_vec3f.ts 47.76 kB ($${\color{red}+0.5\%}$$)
d_vec3u.ts 47.76 kB ($${\color{red}+0.5\%}$$)
d_vec4b.ts 47.76 kB ($${\color{red}+0.5\%}$$)
d_vec4u.ts 47.76 kB ($${\color{red}+0.5\%}$$)
d_mat2x2f.ts 47.76 kB ($${\color{red}+0.5\%}$$)
d_mat3x3f.ts 47.76 kB ($${\color{red}+0.5\%}$$)
d_vec2h.ts 47.76 kB ($${\color{red}+0.5\%}$$)
d_vec3h.ts 47.76 kB ($${\color{red}+0.5\%}$$)
d_vec4h.ts 47.76 kB ($${\color{red}+0.5\%}$$)
d_vec3i.ts 47.76 kB ($${\color{red}+0.5\%}$$)
d_vec4f.ts 47.76 kB ($${\color{red}+0.5\%}$$)
d_vec4i.ts 47.76 kB ($${\color{red}+0.5\%}$$)
d_vec2f.ts 47.76 kB ($${\color{red}+0.5\%}$$)
d_vec2i.ts 47.76 kB ($${\color{red}+0.5\%}$$)
STATIC_useGpuFunction.ts 227 B ($${\color{green}-12.4\%}$$)

If you wish to run a comparison for other, slower bundlers, run the 'Tree-shake test' from the GitHub Actions menu.

@github-actions

github-actions Bot commented Aug 24, 2026 •

Copy link
Copy Markdown

Resolution Time Benchmark

---
config:
  themeVariables:
    xyChart:
      plotColorPalette: "#E63946, #3B82F6, #059669"
---
xychart
  title "Random Branching (🔴 PR | 🔵 main | 🟢 release)"
  x-axis "max depth" [1, 2, 3, 4, 5, 6, 7, 8]
  y-axis "time (ms)"
  line [1.11, 2.34, 5.05, 7.55, 9.04, 13.30, 28.84, 30.15]
  line [1.10, 2.25, 5.07, 7.29, 9.24, 14.81, 27.56, 29.33]
  line [1.14, 2.21, 4.68, 7.47, 8.34, 13.56, 27.59, 29.63]
Loading
---
config:
  themeVariables:
    xyChart:
      plotColorPalette: "#E63946, #3B82F6, #059669"
---
xychart
  title "Linear Recursion (🔴 PR | 🔵 main | 🟢 release)"
  x-axis "max depth" [1, 2, 3, 4, 5, 6, 7, 8]
  y-axis "time (ms)"
  line [0.37, 0.58, 0.77, 0.93, 1.24, 1.37, 1.61, 1.75]
  line [0.32, 0.61, 0.75, 0.90, 1.31, 1.31, 1.64, 1.76]
  line [0.33, 0.60, 0.77, 0.97, 1.23, 1.30, 1.56, 1.73]
Loading
---
config:
  themeVariables:
    xyChart:
      plotColorPalette: "#E63946, #3B82F6, #059669"
---
xychart
  title "Full Tree (🔴 PR | 🔵 main | 🟢 release)"
  x-axis "max depth" [1, 2, 3, 4, 5, 6, 7, 8]
  y-axis "time (ms)"
  line [1.02, 2.32, 4.32, 8.50, 15.32, 29.24, 65.11, 131.86]
  line [1.23, 2.65, 4.77, 9.76, 15.79, 30.08, 63.57, 125.92]
  line [1.13, 2.42, 4.01, 8.15, 14.90, 30.95, 63.17, 127.38]
Loading

@vende11s
vende11s marked this pull request as ready for review August 26, 2026 16:04
Copilot AI lite review requested due to automatic review settings August 26, 2026 16:04

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds support for simple object destructuring inside 'use gpu' functions by extending the Tinyest AST to represent variable bindings as a BindingPattern (identifier vs. destructured object), then updating parsing, WGSL generation, linting, obfuscation, and tests accordingly.

Changes:

  • Extend Tinyest let/const declarations to use BindingPattern and introduce BindingPatternType (with compatibility aliases for existing FuncParameter* naming).
  • Parse simple object destructuring for variable declarations / parameters in tinyest-for-wgsl, and generate corresponding WGSL declarations in WgslGenerator.
  • Update ESLint rule coverage and test snapshots across packages to reflect the new AST shape and supported destructuring subset.

Reviewed changes

Copilot reviewed 18 out of 18 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
packages/unplugin-typegpu/test/use-gpu-directive.test.ts Updates expected Tinyest AST snapshots for let/const bindings.
packages/unplugin-typegpu/test/tgsl-transpiling.test.ts Updates transpilation snapshots to the new binding pattern representation.
packages/unplugin-typegpu/test/parser-options.test.ts Adjusts parser option snapshot to the new BindingPattern form.
packages/unplugin-typegpu/test/obfuscation.test.ts Adds coverage for obfuscating destructured variable declarations + updates snapshots.
packages/unplugin-typegpu/test/aliasing.test.ts Updates alias-gathering snapshots to new binding representation.
packages/unplugin-typegpu/src/core/obfuscate.ts Refactors binding obfuscation to support identifier vs destructured object patterns.
packages/typegpu/tests/tgsl/wgslGenerator.test.ts Adds WGSL generator tests for object destructuring (const/let, single-eval, name conflicts).
packages/typegpu/tests/internal/tseynit.test.ts Adds stringify coverage for destructured binding declarations.
packages/typegpu/tests/internal/metadata.test.ts Updates metadata normalization tests to handle legacy vs new binding forms.
packages/typegpu/src/tgsl/wgslGenerator.ts Implements object destructuring statement lowering and updates let/const handling to BindingPattern.
packages/typegpu/src/shared/tseynit.ts Adds BindingPattern stringification for debugging/printing.
packages/typegpu/src/shared/normalizeMetadata.ts Normalizes legacy metadata by converting string bindings into identifier BindingPatterns.
packages/typegpu/src/resolutionCtx.ts Updates parameter pattern checks to use BindingPatternType.
packages/tinyest/src/nodes.ts Introduces BindingPatternType/BindingPattern, updates Let/Const to use them, keeps compatibility aliases.
packages/tinyest-for-wgsl/tests/parsers.test.ts Adds parser coverage for destructured declarations and unsupported patterns + snapshot updates.
packages/tinyest-for-wgsl/src/parsers.ts Adds parsing for BindingPattern (identifier/object destructuring), rejects unsupported destructuring contexts.
packages/eslint-plugin/tests/rules/noUnsupportedSyntax.test.ts Expands valid/invalid coverage for supported destructuring + unsupported binding patterns / loop headers.
packages/eslint-plugin/src/rules/noUnsupportedSyntax.ts Allows supported simple object binding patterns, adds checks for destructuring assignment and loop-header destructuring.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread packages/typegpu/src/tgsl/wgslGenerator.ts
Comment thread packages/typegpu/src/tgsl/wgslGenerator.ts

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No outstanding changes needed.

Reviewed changes

  • tinyest Let/Const binding overhaul — The 2nd tuple element changed from a string to a structured BindingPattern (identifier / destructuredObject); FuncParameter/FuncParameterType kept as aliases of the new names for backward source compatibility, and every consumer of the shared node shape was updated in lockstep.
  • TGSL parser (tinyest-for-wgsl) — New parseBindingPattern (shared by variable declarations and function parameters) replaces the previous per-parameter inline mapping, and now hard-rejects nested/computed/default/rest/array patterns, destructuring assignments, and destructuring in for-loop init / for...of headers with clear errors.
  • WGSL lowering (wgslGenerator) — _objectDestructuringStatement lowers a destructured const/let into an internal temporary (guaranteeing single evaluation of the source expression) plus one const/let per alias; temporary names are uniquified via the existing makeUniqueIdentifier machinery, and mutable destructured let correctly lowers to var. The GLSL generator inherits the same lowering.
  • Metadata migration (normalizeMetadata) — normalizeLegacyBindings recursively rewrites legacy v1/v2 metadata where a let/const binding was a plain string into the new identifier BindingPattern shape, and is idempotent on the new object form; the internal metadata tests exercise real end-to-end resolve on legacy-shaped metadata as well as the new format.
  • ESLint rule (noUnsupportedSyntax) — Now allows simple object-pattern variable declarations and destructured parameters while rejecting everything else; its support predicate matches what the parser accepts, so lint and transpile stay in agreement.
  • Obfuscation (obfuscate.ts) — obfuscateBindingPattern renames identifier bindings and destructured aliases while leaving property names intact (they must survive into the generated member access).
  • Tests across the parser, generator, metadata migration, obfuscation, and eslint rule layers, including single-evaluation, name-collision, and mutation cases.

⚠️ Pre-existing silent-drop now fails loudly (improvement, but a behavior change)

On the old code path, destructured function-parameter sub-properties that weren't the simple key: alias shape were silently dropped (props.flatMap((prop) => condition ? [entry] : [])), which could route an argument into the wrong struct field — a correctness bug. The new parseBindingPattern throws for these. That hard error is strictly better and the eslint rule now reports it earlier with a helpful message, but it is a behavioral change for any code that previously transpiled-but-mishandled such params — worth a line in the changelog/release notes.

I verified the changed packages independently: all targeted unit tests pass (tinyest-for-wgsl parsers, unplugin obfuscation, typegpu wgslGenerator/metadata/tseynit, eslint noUnsupportedSyntax) and the core typegpu typecheck (pnpm --filter typegpu test:types) is clean.

ℹ️ Nitpicks

  • wgslGenerator.#destructuringIndex is an instance-global counter that is never reset, so temporary names are numbered monotonically across every function in a resolve rather than per function. Harmless (each name is further uniquified in its own scope) but slightly inconsistent with how other names are scoped.
  • The generated temporary for a non-identifier destructing source is emitted as a mutable let (struct values take the deferred var-type path even though the temp is never reassigned). Cosmetic; const could be used, but there's no behavioral impact.

Pullfrog  | View workflow run | Using DeepSeek Flash (free via Pullfrog for OSS) | 𝕏

@vende11s
vende11s force-pushed the feat/destructuring-objects branch 2 times, most recently from d0a6a3d to 6d9418f Compare September 10, 2026 14:10
@pullfrog

pullfrog Bot commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

Run failed. View the logs →

Pullfrog  | Rerun failed job ➔ | View workflow run | via Pullfrog | Using DeepSeek Flash (free via Pullfrog for OSS) | 𝕏

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes

  • Single evaluation of external destructuring sources — a dotted external access such as source.value reaches _objectDestructuringStatement as a string, so the previous code generated one property read per alias by re-resolving the source each time. The source expression is now resolved once and cached in block externals under #destructured_source, so a JS getter fires once per declaration.
  • Regression test for the above — new reads an external object getter once per destructuring declaration case pins both the JS read count and the folded WGSL constants; verified it fails against the pre-fix branch (reads all advance: y=2, a=3, b=4).
  • Prior-review cleanup — removed the never-reset #destructuringIndex counter and switched the temp primer to a fixed #destructured, sanitized and uniquified by makeUniqueIdentifier; snapshots updated accordingly.
  • Collision coverage refreshed — the name-conflict test now covers an external function named destructured plus a user identifier destructured_1, and the stale parser snapshot was corrected to the new binding-pattern shape.

ℹ️ Plain-identifier sources are exercised only indirectly

The new test drives the else branch through a dotted external (source.value), but the more common const pair = Pair(...); const { a, b: c } = pair; form from the PR description also routes through that branch and has no test pinning its output.

Technical details
# Missing coverage for the bare-identifier source path

## Affected sites
- `packages/typegpu/src/tgsl/wgslGenerator.ts:1344` — the `else` branch in `_objectDestructuringStatement`.
- `packages/typegpu/tests/tgsl/wgslGenerator.test.ts:2059` — `destructures an identifier without a temporary` actually passes a constructor call (`Pair({...})`), so it exercises the temp branch despite its name.

## Required outcome
- A test that destructures a previously declared local identifier and asserts the emitted `let a = pair.a; let c = pair.b;` with no temporary.

## Open questions for the human
- Is the mismatch between the test name at line 2059 and its body intentional, or was a bare-identifier case meant to live there?

Pullfrog  | View workflow run | Using DeepSeek Flash (free via Pullfrog for OSS) | 𝕏

Comment thread packages/eslint-plugin/src/rules/noUnsupportedSyntax.ts

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes

  • ESLint rule consolidated into one ObjectPattern visitor — Object-pattern logic no longer lives across several visitors. The new visitor reports by default and allows a pattern only when it is a block-level declaration (VariableDeclarator → VariableDeclaration → BlockStatement) or a direct parameter of the enclosing 'use gpu' function, and the pattern has the supported simple shape. The previous loop-header special case and the inline parameter sub-pattern check are gone, so a newly supported destination must be registered explicitly or CI flags it.
  • Function-parameter validation extracted — A shared validateFunctionParameters helper is called from the arrow, function-expression, and function-declaration visitors; it still permits Identifier/AssignmentPattern/ObjectPattern and reports array/rest/other patterns as unsupported function parameter binding pattern.
  • Messages unified and coverage expanded — Destructuring assignments, nested/computed/default/rest patterns, and loop-header destructuring all now report object destructuring; tests add the let, nested-block, all-three-function-forms-with-destructured-params, for-header, assignment, and array/rest-param cases. The full eslint-plugin suite passes (146 tests).

Pullfrog  | View workflow run | Using DeepSeek Flash (free via Pullfrog for OSS) | 𝕏

@vende11s
vende11s force-pushed the feat/destructuring-objects branch from cbdfdb6 to d7af0a3 Compare September 22, 2026 10:58

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes

Since the prior pullfrog review, the branch was rebased onto current main (absorbing the tinyest-for-wgsl parser split from #2932 and computed object-property support from #2950) and adds one authorial commit, d7af0a3d3:

  • Empty destructuring no longer forces a block scope — _objectDestructuringStatement now derives definesInNearestScope from whether any generated declaration actually emits code. const {} = source; (identifier source: no temp, no aliases) produces nothing, so the enclosing block inlines instead of introducing braces; a function-call source still emits the let destructured = ... temp, so evaluation and scoping are retained.
  • for...of error message normalized — the destructuring guard in the for...of path no longer says for..of.
  • Two regression tests in wgslGenerator.test.ts — one pins inlining of empty destructuring of an identifier, the other pins that empty destructuring of a call keeps the temp and the block.

I verified the new tests pass at head, and confirmed the first one fails against the pre-fix definesInNearestScope: true (the block braces reappear in the snapshot), so it is real coverage rather than a tautology.

Pullfrog  | View workflow run | Using DeepSeek Flash (free via Pullfrog for OSS) | 𝕏

Comment thread packages/tinyest/src/nodes.ts
Comment thread packages/tinyest/src/nodes.ts
Comment thread packages/tinyest/src/nodes.ts
Comment thread packages/tinyest/src/nodes.ts Outdated
};

export type FuncParameter = BindingPattern;
export const FuncParameterType = BindingPatternType;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea with merging these two types, but I don't think we can do that just yet.

I'm not sure what our policy on non-backwards-compatible changes in tinyest is, it would probably be best to ask @iwoplaza, but I think that it would be fine to update FuncParameter to either be as it is now, or BindingPattern (updated to be for example Identifier | [name: number, alias?: number][]), and then drop the original type in a couple of versions and bump the metadata version.

Actually, not related to this PR, RawMetadataV1 depending on tinyest may not have been the greatest idea, tinyest updates may change what we think RawMetadataV1 is... Can you depend on multiple versions of the same package?

Comment thread packages/typegpu/tests/tgsl/wgslGenerator.test.ts

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that this might be a pretty common usage. Also, it will probably require non-tirvial new infrastructure, so I think that this should be delegated to another PR. Could you create an issue for that?

  it('allows for destructuring bind group layouts', () => {
    const layout = tgpu.bindGroupLayout({
      buf: { uniform: d.u32 },
    });

    const fn = () => {
      'use gpu';
      const { buf } = layout.$;
    };

    expect(tgpu.resolve([fn])).toMatchInlineSnapshot();
  });

Comment thread packages/typegpu/tests/tgsl/wgslGenerator.test.ts
@vende11s
vende11s marked this pull request as draft September 24, 2026 13:19
@vende11s
vende11s force-pushed the feat/destructuring-objects branch from d7af0a3 to ff4dc2b Compare October 15, 2026 10:06
@vende11s
vende11s force-pushed the feat/destructuring-objects branch from ff4dc2b to fcde66a Compare October 15, 2026 10:11

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants