@@ -277,7 +277,108 @@ describe('d.ref', () => {
277277 - fn*:main
278278 - fn*:main()
279279 - fn*:foo(vec3f)
280- - fn:ref: d.ref(hello) is illegal, cannot take a reference of an argument. Copy the value locally first, and take a reference of the copy.]
280+ - fn:ref: d.ref(hello) is illegal, cannot take a reference of an argument. Copy the value first, and take a reference of the copy.]
281+ ` ) ;
282+ } ) ;
283+
284+ it ( 'fails when taking a reference of an naturally ephemeral local definition' , ( ) => {
285+ const myConst = tgpu . const ( d . vec2u , d . vec2u ( ) ) ;
286+
287+ function modify ( n : d . ref < number > ) {
288+ 'use gpu' ;
289+ n . $ ++ ;
290+ }
291+
292+ function good ( ) {
293+ 'use gpu' ;
294+ const a = d . f32 ( 1 ) ;
295+ const aRef = d . ref ( d . f32 ( a ) ) ; // we copy the value and create a new referencable value
296+ modify ( aRef ) ;
297+ }
298+
299+ function bad ( ) {
300+ 'use gpu' ;
301+ const a = d . f32 ( 1 ) ;
302+ const aRef = d . ref ( a ) ; // we try to reference a scalar
303+ modify ( aRef ) ;
304+ }
305+
306+ expect ( ( ) => tgpu . resolve ( [ good ] ) ) . not . toThrow ( ) ;
307+ expect ( ( ) => tgpu . resolve ( [ bad ] ) ) . toThrowErrorMatchingInlineSnapshot ( `
308+ [Error: Resolution of the following tree failed:
309+ - <root>
310+ - fn*:bad
311+ - fn*:bad()
312+ - fn:ref: d.ref(a) is illegal, cannot take a reference to a scalar value.
313+ -----
314+ - Try 'd.ref(f32(a));' instead to create a new referencable scalar.
315+ -----]
316+ ` ) ;
317+ } ) ;
318+
319+ it ( 'fails when taking a reference of a tgpu.const' , ( ) => {
320+ const myConst = tgpu . const ( d . vec2u , d . vec2u ( ) ) ;
321+
322+ function modify ( n : d . ref < d . v2u > ) {
323+ 'use gpu' ;
324+ n . $ . x ++ ;
325+ }
326+
327+ function good ( ) {
328+ 'use gpu' ;
329+ const aRef = d . ref ( d . vec2u ( myConst . $ ) ) ; // we copy the value and create a new referencable value
330+ modify ( aRef ) ;
331+ }
332+
333+ function bad ( ) {
334+ 'use gpu' ;
335+ const aRef = d . ref ( myConst . $ ) ; // we try to reference a constant
336+ modify ( aRef ) ;
337+ }
338+
339+ expect ( ( ) => tgpu . resolve ( [ good ] ) ) . not . toThrow ( ) ;
340+ expect ( ( ) => tgpu . resolve ( [ bad ] ) ) . toThrowErrorMatchingInlineSnapshot ( `
341+ [Error: Resolution of the following tree failed:
342+ - <root>
343+ - fn*:bad
344+ - fn*:bad()
345+ - fn:ref: d.ref(myConst) is illegal, cannot take a reference to a constant.
346+ -----
347+ - Try 'd.ref(vec2u(myConst));' instead to create a new referencable value.
348+ -----]
349+ ` ) ;
350+ } ) ;
351+
352+ it ( 'fails when taking a reference of an naturally ephemeral piece of tgpu.const' , ( ) => {
353+ const myConst = tgpu . const ( d . vec2u , d . vec2u ( ) ) ;
354+
355+ function modify ( n : d . ref < number > ) {
356+ 'use gpu' ;
357+ n . $ ++ ;
358+ }
359+
360+ function good ( ) {
361+ 'use gpu' ;
362+ const aRef = d . ref ( d . u32 ( myConst . $ . x ) ) ; // we copy the value and create a new referencable value
363+ modify ( aRef ) ;
364+ }
365+
366+ function bad ( ) {
367+ 'use gpu' ;
368+ const aRef = d . ref ( myConst . $ . x ) ; // we try to reference a constant
369+ modify ( aRef ) ;
370+ }
371+
372+ expect ( ( ) => tgpu . resolve ( [ good ] ) ) . not . toThrow ( ) ;
373+ expect ( ( ) => tgpu . resolve ( [ bad ] ) ) . toThrowErrorMatchingInlineSnapshot ( `
374+ [Error: Resolution of the following tree failed:
375+ - <root>
376+ - fn*:bad
377+ - fn*:bad()
378+ - fn:ref: d.ref(myConst.x) is illegal, cannot take a reference to a constant.
379+ -----
380+ - Try 'd.ref(u32(myConst.x));' instead to create a new referencable value.
381+ -----]
281382 ` ) ;
282383 } ) ;
283384
0 commit comments