Skip to content

Commit eef9852

Browse files
authored
fix: Accessor type inference (#1695)
1 parent 1be642c commit eef9852

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+468
-431
lines changed
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
<div class="result">Wait for the tests to finish running...</div>;
1+
<div class="result">Wait for the tests to finish running...</div>

packages/typegpu/src/core/buffer/bufferShorthand.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
$getNameForward,
77
$gpuValueOf,
88
$internal,
9+
$resolve,
910
} from '../../shared/symbols.ts';
1011
import type { ResolutionCtx, SelfResolvable } from '../../types.ts';
1112
import type { TgpuBuffer, UniformFlag } from './buffer.ts';
@@ -25,7 +26,7 @@ interface TgpuBufferShorthandBase<TData extends BaseData> extends TgpuNamable {
2526
// ---
2627

2728
// Accessible on the GPU
28-
[$gpuValueOf](ctx: ResolutionCtx): InferGPU<TData>;
29+
readonly [$gpuValueOf]: InferGPU<TData>;
2930
// ---
3031
}
3132

@@ -113,7 +114,7 @@ export class TgpuBufferShorthandImpl<
113114
return this.buffer.read();
114115
}
115116

116-
[$gpuValueOf](ctx: ResolutionCtx): InferGPU<TData> {
117+
get [$gpuValueOf](): InferGPU<TData> {
117118
return this.#usage.$;
118119
}
119120

@@ -125,7 +126,7 @@ export class TgpuBufferShorthandImpl<
125126
return this.$;
126127
}
127128

128-
'~resolve'(ctx: ResolutionCtx): string {
129+
[$resolve](ctx: ResolutionCtx): string {
129130
return ctx.resolve(this.#usage);
130131
}
131132
}

packages/typegpu/src/core/buffer/bufferUsage.ts

Lines changed: 48 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import type { AnyData } from '../../data/dataTypes.ts';
22
import { schemaCallWrapper } from '../../data/schemaCallWrapper.ts';
3+
import { snip } from '../../data/snippet.ts';
34
import type { AnyWgslData, BaseData } from '../../data/wgslTypes.ts';
45
import { IllegalBufferAccessError } from '../../errors.ts';
56
import { getExecMode, inCodegenMode, isInsideTgpuFn } from '../../execMode.ts';
@@ -11,9 +12,9 @@ import {
1112
$getNameForward,
1213
$gpuValueOf,
1314
$internal,
15+
$ownSnippet,
1416
$repr,
15-
$runtimeResource,
16-
$wgslDataType,
17+
$resolve,
1718
} from '../../shared/symbols.ts';
1819
import { assertExhaustive } from '../../shared/utilityTypes.ts';
1920
import type { LayoutMembership } from '../../tgpuBindGroupLayout.ts';
@@ -37,7 +38,7 @@ export interface TgpuBufferUsage<
3738
readonly usage: TUsage;
3839
readonly [$repr]: Infer<TData>;
3940

40-
[$gpuValueOf](ctx: ResolutionCtx): InferGPU<TData>;
41+
readonly [$gpuValueOf]: InferGPU<TData>;
4142
value: InferGPU<TData>;
4243
$: InferGPU<TData>;
4344

@@ -90,10 +91,10 @@ class TgpuFixedBufferImpl<
9091
SelfResolvable,
9192
TgpuFixedBufferUsage<TData> {
9293
/** Type-token, not available at runtime */
93-
declare public readonly [$repr]: Infer<TData>;
94-
public readonly resourceType = 'buffer-usage' as const;
95-
public readonly [$internal]: { readonly dataType: TData };
96-
public readonly [$getNameForward]: TgpuBuffer<TData>;
94+
declare readonly [$repr]: Infer<TData>;
95+
readonly resourceType = 'buffer-usage' as const;
96+
readonly [$internal]: { readonly dataType: TData };
97+
readonly [$getNameForward]: TgpuBuffer<TData>;
9798

9899
constructor(
99100
public readonly usage: TUsage,
@@ -108,21 +109,20 @@ class TgpuFixedBufferImpl<
108109
return this;
109110
}
110111

111-
'~resolve'(ctx: ResolutionCtx): string {
112+
[$resolve](ctx: ResolutionCtx): string {
113+
const dataType = this.buffer.dataType;
112114
const id = ctx.getUniqueName(this);
113115
const { group, binding } = ctx.allocateFixedEntry(
114116
this.usage === 'uniform'
115-
? { uniform: this.buffer.dataType }
116-
: { storage: this.buffer.dataType, access: this.usage },
117+
? { uniform: dataType }
118+
: { storage: dataType, access: this.usage },
117119
this.buffer,
118120
);
119-
const usage = usageToVarTemplateMap[this.usage];
121+
const usageTemplate = usageToVarTemplateMap[this.usage];
120122

121123
ctx.addDeclaration(
122-
`@group(${group}) @binding(${binding}) var<${usage}> ${id}: ${
123-
ctx.resolve(
124-
this.buffer.dataType,
125-
)
124+
`@group(${group}) @binding(${binding}) var<${usageTemplate}> ${id}: ${
125+
ctx.resolve(dataType)
126126
};`,
127127
);
128128

@@ -133,17 +133,18 @@ class TgpuFixedBufferImpl<
133133
return `${this.usage}:${getName(this) ?? '<unnamed>'}`;
134134
}
135135

136-
[$gpuValueOf](): InferGPU<TData> {
137-
return new Proxy(
138-
{
139-
[$internal]: true,
140-
[$runtimeResource]: true,
141-
[$wgslDataType]: this.buffer.dataType,
142-
'~resolve': (ctx: ResolutionCtx) => ctx.resolve(this),
143-
toString: () => `.value:${getName(this) ?? '<unnamed>'}`,
136+
get [$gpuValueOf](): InferGPU<TData> {
137+
const dataType = this.buffer.dataType;
138+
const name = getName(this);
139+
140+
return new Proxy({
141+
[$internal]: true,
142+
get [$ownSnippet]() {
143+
return snip(this, dataType);
144144
},
145-
valueProxyHandler,
146-
) as InferGPU<TData>;
145+
[$resolve]: (ctx) => ctx.resolve(this),
146+
toString: () => `${this.usage}:${name ?? '<unnamed>'}.$`,
147+
}, valueProxyHandler) as InferGPU<TData>;
147148
}
148149

149150
get $(): InferGPU<TData> {
@@ -161,7 +162,7 @@ class TgpuFixedBufferImpl<
161162
}
162163

163164
if (mode.type === 'codegen') {
164-
return this[$gpuValueOf]();
165+
return this[$gpuValueOf];
165166
}
166167

167168
if (mode.type === 'simulate') {
@@ -219,26 +220,28 @@ export class TgpuLaidOutBufferImpl<
219220
TUsage extends BindableBufferUsage,
220221
> implements TgpuBufferUsage<TData, TUsage>, SelfResolvable {
221222
/** Type-token, not available at runtime */
222-
declare public readonly [$repr]: Infer<TData>;
223-
public readonly resourceType = 'buffer-usage' as const;
224-
public readonly [$internal]: { readonly dataType: TData };
223+
declare readonly [$repr]: Infer<TData>;
224+
readonly [$internal]: { readonly dataType: TData };
225+
readonly resourceType = 'buffer-usage' as const;
226+
readonly #membership: LayoutMembership;
225227

226228
constructor(
227229
public readonly usage: TUsage,
228230
public readonly dataType: TData,
229-
private readonly _membership: LayoutMembership,
231+
membership: LayoutMembership,
230232
) {
231233
this[$internal] = { dataType };
232-
setName(this, _membership.key);
234+
this.#membership = membership;
235+
setName(this, membership.key);
233236
}
234237

235-
'~resolve'(ctx: ResolutionCtx): string {
238+
[$resolve](ctx: ResolutionCtx): string {
236239
const id = ctx.getUniqueName(this);
237-
const group = ctx.allocateLayoutEntry(this._membership.layout);
240+
const group = ctx.allocateLayoutEntry(this.#membership.layout);
238241
const usage = usageToVarTemplateMap[this.usage];
239242

240243
ctx.addDeclaration(
241-
`@group(${group}) @binding(${this._membership.idx}) var<${usage}> ${id}: ${
244+
`@group(${group}) @binding(${this.#membership.idx}) var<${usage}> ${id}: ${
242245
ctx.resolve(this.dataType)
243246
};`,
244247
);
@@ -250,22 +253,22 @@ export class TgpuLaidOutBufferImpl<
250253
return `${this.usage}:${getName(this) ?? '<unnamed>'}`;
251254
}
252255

253-
[$gpuValueOf](): InferGPU<TData> {
254-
return new Proxy(
255-
{
256-
[$internal]: true,
257-
[$runtimeResource]: true,
258-
[$wgslDataType]: this.dataType,
259-
'~resolve': (ctx: ResolutionCtx) => ctx.resolve(this),
260-
toString: () => `.value:${getName(this) ?? '<unnamed>'}`,
256+
get [$gpuValueOf](): InferGPU<TData> {
257+
const schema = this.dataType as unknown as AnyData;
258+
259+
return new Proxy({
260+
[$internal]: true,
261+
get [$ownSnippet]() {
262+
return snip(this, schema);
261263
},
262-
valueProxyHandler,
263-
) as InferGPU<TData>;
264+
[$resolve]: (ctx) => ctx.resolve(this),
265+
toString: () => `${this.usage}:${getName(this) ?? '<unnamed>'}.$`,
266+
}, valueProxyHandler) as InferGPU<TData>;
264267
}
265268

266269
get $(): InferGPU<TData> {
267270
if (inCodegenMode()) {
268-
return this[$gpuValueOf]();
271+
return this[$gpuValueOf];
269272
}
270273

271274
throw new Error(

packages/typegpu/src/core/constant/tgpuConstant.ts

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { snip } from '../../data/snippet.ts';
12
import type { AnyWgslData } from '../../data/wgslTypes.ts';
23
import { inCodegenMode } from '../../execMode.ts';
34
import type { TgpuNamable } from '../../shared/meta.ts';
@@ -6,8 +7,8 @@ import type { InferGPU } from '../../shared/repr.ts';
67
import {
78
$gpuValueOf,
89
$internal,
9-
$runtimeResource,
10-
$wgslDataType,
10+
$ownSnippet,
11+
$resolve,
1112
} from '../../shared/symbols.ts';
1213
import type { ResolutionCtx, SelfResolvable } from '../../types.ts';
1314
import { valueProxyHandler } from '../valueProxyUtils.ts';
@@ -18,7 +19,7 @@ import { valueProxyHandler } from '../valueProxyUtils.ts';
1819

1920
export interface TgpuConst<TDataType extends AnyWgslData = AnyWgslData>
2021
extends TgpuNamable {
21-
[$gpuValueOf](): InferGPU<TDataType>;
22+
readonly [$gpuValueOf]: InferGPU<TDataType>;
2223
readonly value: InferGPU<TDataType>;
2324
readonly $: InferGPU<TDataType>;
2425

@@ -45,7 +46,7 @@ export function constant<TDataType extends AnyWgslData>(
4546
class TgpuConstImpl<TDataType extends AnyWgslData>
4647
implements TgpuConst<TDataType>, SelfResolvable {
4748
readonly [$internal] = {};
48-
#value: InferGPU<TDataType>;
49+
readonly #value: InferGPU<TDataType>;
4950

5051
constructor(
5152
public readonly dataType: TDataType,
@@ -59,10 +60,10 @@ class TgpuConstImpl<TDataType extends AnyWgslData>
5960
return this;
6061
}
6162

62-
'~resolve'(ctx: ResolutionCtx): string {
63+
[$resolve](ctx: ResolutionCtx) {
6364
const id = ctx.getUniqueName(this);
64-
const resolvedValue = ctx.resolve(this.#value, this.dataType);
6565
const resolvedDataType = ctx.resolve(this.dataType);
66+
const resolvedValue = ctx.resolve(this.#value, this.dataType);
6667

6768
ctx.addDeclaration(`const ${id}: ${resolvedDataType} = ${resolvedValue};`);
6869

@@ -73,22 +74,22 @@ class TgpuConstImpl<TDataType extends AnyWgslData>
7374
return `const:${getName(this) ?? '<unnamed>'}`;
7475
}
7576

76-
[$gpuValueOf](): InferGPU<TDataType> {
77-
return new Proxy(
78-
{
79-
[$internal]: true,
80-
[$runtimeResource]: true,
81-
[$wgslDataType]: this.dataType,
82-
'~resolve': (ctx: ResolutionCtx) => ctx.resolve(this),
83-
toString: () => `.value:${getName(this) ?? '<unnamed>'}`,
77+
get [$gpuValueOf](): InferGPU<TDataType> {
78+
const dataType = this.dataType;
79+
80+
return new Proxy({
81+
[$internal]: true,
82+
get [$ownSnippet]() {
83+
return snip(this, dataType);
8484
},
85-
valueProxyHandler,
86-
) as InferGPU<TDataType>;
85+
[$resolve]: (ctx) => ctx.resolve(this),
86+
toString: () => `const:${getName(this) ?? '<unnamed>'}.$`,
87+
}, valueProxyHandler) as InferGPU<TDataType>;
8788
}
8889

8990
get value(): InferGPU<TDataType> {
9091
if (inCodegenMode()) {
91-
return this[$gpuValueOf]();
92+
return this[$gpuValueOf];
9293
}
9394

9495
return this.#value;

packages/typegpu/src/core/declare/tgpuDeclare.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { $internal } from '../../shared/symbols.ts';
1+
import { $internal, $resolve } from '../../shared/symbols.ts';
22
import type { ResolutionCtx, SelfResolvable } from '../../types.ts';
33
import {
44
applyExternals,
@@ -44,7 +44,7 @@ class TgpuDeclareImpl implements TgpuDeclare, SelfResolvable {
4444
return this;
4545
}
4646

47-
'~resolve'(ctx: ResolutionCtx): string {
47+
[$resolve](ctx: ResolutionCtx): string {
4848
const externalMap: ExternalMap = {};
4949

5050
for (const externals of this.externalsToApply) {

packages/typegpu/src/core/function/dualImpl.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,16 @@ import {
55
type Snippet,
66
} from '../../data/snippet.ts';
77
import { inCodegenMode } from '../../execMode.ts';
8-
import type { FnArgsConversionHint } from '../../types.ts';
8+
import { type FnArgsConversionHint, getOwnSnippet } from '../../types.ts';
99
import { setName } from '../../shared/meta.ts';
10-
import { $internal, isRuntimeResource } from '../../shared/symbols.ts';
10+
import { $internal } from '../../shared/symbols.ts';
1111
import { tryConvertSnippet } from '../../tgsl/conversion.ts';
1212
import type { AnyData } from '../../data/dataTypes.ts';
1313

14+
function isKnownAtComptime(value: unknown): boolean {
15+
return typeof value !== 'string' && getOwnSnippet(value) === undefined;
16+
}
17+
1418
export function createDualImpl<T extends (...args: never[]) => unknown>(
1519
jsImpl: T,
1620
gpuImpl: (...args: MapValueToSnippet<Parameters<T>>) => Snippet,
@@ -70,11 +74,7 @@ export function dualImpl<T extends (...args: never[]) => unknown>(
7074
)
7175
) as MapValueToSnippet<Parameters<T>>;
7276

73-
if (
74-
converted.every((s) =>
75-
typeof s.value !== 'string' && !isRuntimeResource(s.value)
76-
)
77-
) {
77+
if (converted.every((s) => isKnownAtComptime(s.value))) {
7878
return snip(
7979
options.normalImpl(...converted.map((s) => s.value) as never[]),
8080
returnType,

packages/typegpu/src/core/function/tgpuComputeFn.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
setName,
77
type TgpuNamable,
88
} from '../../shared/meta.ts';
9-
import { $getNameForward, $internal } from '../../shared/symbols.ts';
9+
import { $getNameForward, $internal, $resolve } from '../../shared/symbols.ts';
1010
import type { ResolutionCtx, SelfResolvable } from '../../types.ts';
1111
import { createFnCore, type FnCore } from './fnCore.ts';
1212
import type { Implementation, InferIO, IORecord } from './fnTypes.ts';
@@ -177,7 +177,7 @@ function createComputeFn<ComputeIn extends IORecord<AnyComputeBuiltin>>(
177177
return this;
178178
},
179179

180-
'~resolve'(ctx: ResolutionCtx): string {
180+
[$resolve](ctx: ResolutionCtx): string {
181181
return core.resolve(
182182
ctx,
183183
shell.argTypes,

0 commit comments

Comments
 (0)