| export const description = ` |
| Validation tests for structure access expressions. |
| |
| * Correct result type |
| * Identifier matching |
| `; |
| |
| import { makeTestGroup } from '../../../../../common/framework/test_group.js'; |
| import { ShaderValidationTest } from '../../shader_validation_test.js'; |
| |
| export const g = makeTestGroup(ShaderValidationTest); |
| |
| g.test('identifier_mismatch') |
| .desc('Tests that the member identifier must match a member in the declaration') |
| .params(u => u.combine('decl', ['value', 'ref'] as const)) |
| .fn(t => { |
| const code = ` |
| struct S { |
| x : u32 |
| } |
| fn foo() { |
| ${t.params.decl === 'value' ? 'let' : 'var'} v : S = S(); |
| _ = v.y; |
| }`; |
| t.expectCompileResult(false, code); |
| }); |
| |
| g.test('shadowed_member') |
| .desc('Tests that other declarations do not interfere with member determination') |
| .params(u => u.combine('decl', ['value', 'ref'] as const)) |
| .fn(t => { |
| const code = ` |
| struct S { |
| x : u32 |
| } |
| fn foo() { |
| var x : i32; |
| ${t.params.decl === 'value' ? 'let' : 'var'} v : S = S(); |
| let tmp : u32 = v.x; |
| }`; |
| t.expectCompileResult(true, code); |
| }); |
| |
| g.test('result_type') |
| .desc('Tests correct result types are returned') |
| .params(u => u.combine('decl', ['value', 'ref'] as const)) |
| .fn(t => { |
| const types = [ |
| 'i32', |
| 'u32', |
| 'f32', |
| 'bool', |
| 'array<u32, 4>', |
| 'array<T, 2>', |
| 'vec2f', |
| 'vec3u', |
| 'vec4i', |
| 'mat2x2f', |
| 'T', |
| ]; |
| let code = ` |
| struct T { |
| a : f32 |
| } |
| struct S {\n`; |
| |
| for (let i = 0; i < types.length; i++) { |
| code += `m${i} : ${types[i]},\n`; |
| } |
| |
| code += `} |
| fn foo() { |
| var x : i32; |
| ${t.params.decl === 'value' ? 'let' : 'var'} v : S = S();\n`; |
| |
| for (let i = 0; i < types.length; i++) { |
| code += `let tmp${i} : ${types[i]} = v.m${i};\n`; |
| } |
| |
| code += `}`; |
| t.expectCompileResult(true, code); |
| }); |
| |
| g.test('result_type_f16') |
| .desc('Tests correct type is returned for f16') |
| .params(u => u.combine('decl', ['value', 'ref'] as const)) |
| .fn(t => { |
| const code = ` |
| enable f16; |
| struct S { |
| x : f16 |
| } |
| fn foo() { |
| ${t.params.decl === 'value' ? 'let' : 'var'} v : S = S(); |
| let tmp : f16 = v.x; |
| }`; |
| t.expectCompileResult(true, code); |
| }); |
| |
| g.test('result_type_runtime_array') |
| .desc('Tests correct type is returned for runtime arrays') |
| .fn(t => { |
| const code = ` |
| struct S { |
| x : array<u32> |
| } |
| @group(0) @binding(0) var<storage> v : S; |
| fn foo() { |
| let tmp : u32 = v.x[0]; |
| let tmp_ptr : ptr<storage, array<u32>> = &v.x; |
| }`; |
| t.expectCompileResult(true, code); |
| }); |