blob: 44cc973bf498be45c835888662de3aec42af188d [file] [log] [blame]
Ryan Harrisondbc13af2022-02-21 15:19:07 +00001// Copyright 2021 The Tint Authors.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
dan sinclair3cbf3fc2023-01-21 19:16:15 +000015#include "gmock/gmock.h"
Ryan Harrisondbc13af2022-02-21 15:19:07 +000016#include "src/tint/resolver/resolver.h"
17#include "src/tint/resolver/resolver_test_helper.h"
dan sinclair3cbf3fc2023-01-21 19:16:15 +000018#include "src/tint/type/texture_dimension.h"
Ryan Harrisondbc13af2022-02-21 15:19:07 +000019
dan sinclaird2093792022-04-07 17:45:45 +000020namespace tint::resolver {
Ryan Harrisondbc13af2022-02-21 15:19:07 +000021namespace {
22
Ben Clayton138d5b72023-06-15 08:42:46 +000023using namespace tint::builtin::fluent_types; // NOLINT
24using namespace tint::number_suffixes; // NOLINT
25
Ben Clayton68ae36e2022-06-24 21:26:39 +000026struct ResolverVariableValidationTest : public resolver::TestHelper, public testing::Test {};
Ryan Harrisondbc13af2022-02-21 15:19:07 +000027
Ben Clayton68ae36e2022-06-24 21:26:39 +000028TEST_F(ResolverVariableValidationTest, VarNoInitializerNoType) {
dan sinclair41e4d9a2022-05-01 14:40:55 +000029 // var a;
Ben Clayton58794ae2022-08-19 17:28:53 +000030 WrapInFunction(Var(Source{{12, 34}}, "a"));
Ryan Harrisondbc13af2022-02-21 15:19:07 +000031
dan sinclair41e4d9a2022-05-01 14:40:55 +000032 EXPECT_FALSE(r()->Resolve());
Ben Claytonf9031332022-06-26 11:36:10 +000033 EXPECT_EQ(r()->error(), "12:34 error: var declaration requires a type or initializer");
Ryan Harrisondbc13af2022-02-21 15:19:07 +000034}
35
Ben Clayton68ae36e2022-06-24 21:26:39 +000036TEST_F(ResolverVariableValidationTest, GlobalVarNoInitializerNoType) {
dan sinclair41e4d9a2022-05-01 14:40:55 +000037 // var a;
Ben Clayton58794ae2022-08-19 17:28:53 +000038 GlobalVar(Source{{12, 34}}, "a");
Ryan Harrisondbc13af2022-02-21 15:19:07 +000039
dan sinclair41e4d9a2022-05-01 14:40:55 +000040 EXPECT_FALSE(r()->Resolve());
Ben Claytonf9031332022-06-26 11:36:10 +000041 EXPECT_EQ(r()->error(), "12:34 error: var declaration requires a type or initializer");
42}
43
Zhaoming Jiang659d58c2022-07-25 12:18:38 +000044TEST_F(ResolverVariableValidationTest, VarInitializerNoReturnValueBuiltin) {
45 // fn f() { var a = storageBarrier(); }
46 auto* NoReturnValueBuiltin = Call(Source{{12, 34}}, "storageBarrier");
Ben Clayton58794ae2022-08-19 17:28:53 +000047 WrapInFunction(Var("a", NoReturnValueBuiltin));
Zhaoming Jiang659d58c2022-07-25 12:18:38 +000048
49 EXPECT_FALSE(r()->Resolve());
50 EXPECT_EQ(r()->error(), "12:34 error: builtin 'storageBarrier' does not return a value");
51}
52
53TEST_F(ResolverVariableValidationTest, GlobalVarInitializerNoReturnValueBuiltin) {
54 // var a = storageBarrier();
55 auto* NoReturnValueBuiltin = Call(Source{{12, 34}}, "storageBarrier");
Ben Clayton58794ae2022-08-19 17:28:53 +000056 GlobalVar("a", NoReturnValueBuiltin);
Zhaoming Jiang659d58c2022-07-25 12:18:38 +000057
58 EXPECT_FALSE(r()->Resolve());
59 EXPECT_EQ(r()->error(), "12:34 error: builtin 'storageBarrier' does not return a value");
60}
61
Ben Claytoncd097f42023-03-10 13:10:52 +000062TEST_F(ResolverVariableValidationTest, GlobalVarNoAddressSpace) {
63 // var a : i32;
64 GlobalVar(Source{{12, 34}}, "a", ty.i32());
65
66 EXPECT_FALSE(r()->Resolve());
67 EXPECT_EQ(
68 r()->error(),
69 R"(12:34 error: module-scope 'var' declarations that are not of texture or sampler types must provide an address space)");
70}
71
72TEST_F(ResolverVariableValidationTest, GlobalVarWithInitializerNoAddressSpace) {
73 // var a = 1;
74 GlobalVar(Source{{12, 34}}, "a", Expr(1_a));
75
76 EXPECT_FALSE(r()->Resolve());
77 EXPECT_EQ(
78 r()->error(),
79 R"(12:34 error: module-scope 'var' declarations that are not of texture or sampler types must provide an address space)");
80}
81
Ben Claytonf9031332022-06-26 11:36:10 +000082TEST_F(ResolverVariableValidationTest, GlobalVarUsedAtModuleScope) {
83 // var<private> a : i32;
84 // var<private> b : i32 = a;
dan sinclair2a651632023-02-19 04:03:55 +000085 GlobalVar(Source{{12, 34}}, "a", ty.i32(), builtin::AddressSpace::kPrivate);
86 GlobalVar("b", ty.i32(), builtin::AddressSpace::kPrivate, Expr(Source{{56, 78}}, "a"));
Ben Claytonf9031332022-06-26 11:36:10 +000087
88 EXPECT_FALSE(r()->Resolve());
dan sinclair1662f552022-09-21 14:44:33 +000089 EXPECT_EQ(r()->error(), R"(56:78 error: var 'a' cannot be referenced at module-scope
Ben Claytonf9031332022-06-26 11:36:10 +00009012:34 note: var 'a' declared here)");
Ben Claytonee49b1e2022-06-20 15:30:41 +000091}
92
Ben Clayton68ae36e2022-06-24 21:26:39 +000093TEST_F(ResolverVariableValidationTest, OverrideNoInitializerNoType) {
Ben Claytonee49b1e2022-06-20 15:30:41 +000094 // override a;
Ben Clayton58794ae2022-08-19 17:28:53 +000095 Override(Source{{12, 34}}, "a");
Ben Claytonee49b1e2022-06-20 15:30:41 +000096
97 EXPECT_FALSE(r()->Resolve());
Ben Claytonf9031332022-06-26 11:36:10 +000098 EXPECT_EQ(r()->error(), "12:34 error: override declaration requires a type or initializer");
Ryan Harrisondbc13af2022-02-21 15:19:07 +000099}
100
Ben Clayton9a6acc42022-07-27 20:50:40 +0000101TEST_F(ResolverVariableValidationTest, OverrideExceedsIDLimit_LastUnreserved) {
102 // override o0 : i32;
103 // override o1 : i32;
104 // ...
105 // override bang : i32;
106 constexpr size_t kLimit = std::numeric_limits<decltype(OverrideId::value)>::max();
107 for (size_t i = 0; i <= kLimit; i++) {
Ben Clayton58794ae2022-08-19 17:28:53 +0000108 Override("o" + std::to_string(i), ty.i32());
Ben Clayton9a6acc42022-07-27 20:50:40 +0000109 }
Ben Clayton58794ae2022-08-19 17:28:53 +0000110 Override(Source{{12, 34}}, "bang", ty.i32());
Ben Clayton9a6acc42022-07-27 20:50:40 +0000111
112 EXPECT_FALSE(r()->Resolve());
113 EXPECT_EQ(r()->error(), "12:34 error: number of 'override' variables exceeded limit of 65535");
114}
115
116TEST_F(ResolverVariableValidationTest, OverrideExceedsIDLimit_LastReserved) {
117 // override o0 : i32;
118 // override o1 : i32;
119 // ...
120 // @id(N) override oN : i32;
121 constexpr size_t kLimit = std::numeric_limits<decltype(OverrideId::value)>::max();
dan sinclair5361d9e2022-08-31 13:39:48 +0000122 Override("reserved", ty.i32(), Id(AInt(kLimit)));
Ben Clayton9a6acc42022-07-27 20:50:40 +0000123 for (size_t i = 0; i < kLimit; i++) {
Ben Clayton58794ae2022-08-19 17:28:53 +0000124 Override("o" + std::to_string(i), ty.i32());
Ben Clayton9a6acc42022-07-27 20:50:40 +0000125 }
Ben Clayton58794ae2022-08-19 17:28:53 +0000126 Override(Source{{12, 34}}, "bang", ty.i32());
Ben Clayton9a6acc42022-07-27 20:50:40 +0000127
128 EXPECT_FALSE(r()->Resolve());
129 EXPECT_EQ(r()->error(), "12:34 error: number of 'override' variables exceeded limit of 65535");
130}
131
Ben Claytoncfe07a12022-07-15 13:01:49 +0000132TEST_F(ResolverVariableValidationTest, VarTypeNotConstructible) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000133 // var i : i32;
134 // var p : pointer<function, i32> = &v;
Ben Clayton58794ae2022-08-19 17:28:53 +0000135 auto* i = Var("i", ty.i32());
Ben Clayton66805b02023-06-14 22:00:01 +0000136 auto* p = Var("a", ty.ptr<function, i32>(Source{{56, 78}}), builtin::AddressSpace::kUndefined,
137 AddressOf(Source{{12, 34}}, "i"));
dan sinclair41e4d9a2022-05-01 14:40:55 +0000138 WrapInFunction(i, p);
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000139
dan sinclair41e4d9a2022-05-01 14:40:55 +0000140 EXPECT_FALSE(r()->Resolve());
Ben Claytoncfe07a12022-07-15 13:01:49 +0000141 EXPECT_EQ(r()->error(), "56:78 error: function-scope 'var' must have a constructible type");
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000142}
143
Ben Clayton68ae36e2022-06-24 21:26:39 +0000144TEST_F(ResolverVariableValidationTest, LetTypeNotConstructible) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000145 // @group(0) @binding(0) var t1 : texture_2d<f32>;
146 // let t2 : t1;
dan sinclair3cbf3fc2023-01-21 19:16:15 +0000147 auto* t1 = GlobalVar("t1", ty.sampled_texture(type::TextureDimension::k2d, ty.f32()),
148 Group(0_a), Binding(0_a));
Ben Clayton58794ae2022-08-19 17:28:53 +0000149 auto* t2 = Let(Source{{56, 78}}, "t2", Expr(t1));
dan sinclair41e4d9a2022-05-01 14:40:55 +0000150 WrapInFunction(t2);
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000151
dan sinclair41e4d9a2022-05-01 14:40:55 +0000152 EXPECT_FALSE(r()->Resolve());
Ben Claytonee49b1e2022-06-20 15:30:41 +0000153 EXPECT_EQ(r()->error(), "56:78 error: texture_2d<f32> cannot be used as the type of a 'let'");
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000154}
155
Ben Clayton68ae36e2022-06-24 21:26:39 +0000156TEST_F(ResolverVariableValidationTest, OverrideExplicitTypeNotScalar) {
Ben Claytone4e48542022-06-20 19:17:52 +0000157 // override o : vec3<f32>;
Ben Clayton58794ae2022-08-19 17:28:53 +0000158 Override(Source{{56, 78}}, "o", ty.vec3<f32>());
Ben Claytone4e48542022-06-20 19:17:52 +0000159
160 EXPECT_FALSE(r()->Resolve());
161 EXPECT_EQ(r()->error(), "56:78 error: vec3<f32> cannot be used as the type of a 'override'");
162}
163
Ben Clayton68ae36e2022-06-24 21:26:39 +0000164TEST_F(ResolverVariableValidationTest, OverrideInferedTypeNotScalar) {
Ben Claytone4e48542022-06-20 19:17:52 +0000165 // override o = vec3(1.0f);
Ben Clayton66805b02023-06-14 22:00:01 +0000166 Override(Source{{56, 78}}, "o", Call<vec3<f32>>(1.0_f));
Ben Claytone4e48542022-06-20 19:17:52 +0000167
168 EXPECT_FALSE(r()->Resolve());
169 EXPECT_EQ(r()->error(), "56:78 error: vec3<f32> cannot be used as the type of a 'override'");
170}
171
dan sinclair6e77b472022-10-20 13:38:28 +0000172TEST_F(ResolverVariableValidationTest, ConstInitializerWrongType) {
Ben Claytone3834c42022-06-25 23:21:39 +0000173 // const c : i32 = 2u
174 WrapInFunction(Const(Source{{3, 3}}, "c", ty.i32(), Expr(2_u)));
175
176 EXPECT_FALSE(r()->Resolve());
177 EXPECT_EQ(r()->error(),
178 R"(3:3 error: cannot initialize const of type 'i32' with value of type 'u32')");
179}
180
dan sinclair6e77b472022-10-20 13:38:28 +0000181TEST_F(ResolverVariableValidationTest, LetInitializerWrongType) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000182 // var v : i32 = 2u
Ben Clayton0ce9ab02022-05-05 20:23:40 +0000183 WrapInFunction(Let(Source{{3, 3}}, "v", ty.i32(), Expr(2_u)));
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000184
dan sinclair41e4d9a2022-05-01 14:40:55 +0000185 EXPECT_FALSE(r()->Resolve());
186 EXPECT_EQ(r()->error(),
187 R"(3:3 error: cannot initialize let of type 'i32' with value of type 'u32')");
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000188}
189
dan sinclair6e77b472022-10-20 13:38:28 +0000190TEST_F(ResolverVariableValidationTest, VarInitializerWrongType) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000191 // var v : i32 = 2u
Ben Clayton58794ae2022-08-19 17:28:53 +0000192 WrapInFunction(Var(Source{{3, 3}}, "v", ty.i32(), Expr(2_u)));
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000193
dan sinclair41e4d9a2022-05-01 14:40:55 +0000194 EXPECT_FALSE(r()->Resolve());
195 EXPECT_EQ(r()->error(),
196 R"(3:3 error: cannot initialize var of type 'i32' with value of type 'u32')");
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000197}
198
dan sinclair6e77b472022-10-20 13:38:28 +0000199TEST_F(ResolverVariableValidationTest, ConstInitializerWrongTypeViaAlias) {
Ben Claytone3834c42022-06-25 23:21:39 +0000200 auto* a = Alias("I32", ty.i32());
201 WrapInFunction(Const(Source{{3, 3}}, "v", ty.Of(a), Expr(2_u)));
202
203 EXPECT_FALSE(r()->Resolve());
204 EXPECT_EQ(r()->error(),
205 R"(3:3 error: cannot initialize const of type 'i32' with value of type 'u32')");
206}
207
dan sinclair6e77b472022-10-20 13:38:28 +0000208TEST_F(ResolverVariableValidationTest, LetInitializerWrongTypeViaAlias) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000209 auto* a = Alias("I32", ty.i32());
Ben Clayton0ce9ab02022-05-05 20:23:40 +0000210 WrapInFunction(Let(Source{{3, 3}}, "v", ty.Of(a), Expr(2_u)));
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000211
dan sinclair41e4d9a2022-05-01 14:40:55 +0000212 EXPECT_FALSE(r()->Resolve());
213 EXPECT_EQ(r()->error(),
214 R"(3:3 error: cannot initialize let of type 'i32' with value of type 'u32')");
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000215}
216
dan sinclair6e77b472022-10-20 13:38:28 +0000217TEST_F(ResolverVariableValidationTest, VarInitializerWrongTypeViaAlias) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000218 auto* a = Alias("I32", ty.i32());
Ben Clayton58794ae2022-08-19 17:28:53 +0000219 WrapInFunction(Var(Source{{3, 3}}, "v", ty.Of(a), Expr(2_u)));
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000220
dan sinclair41e4d9a2022-05-01 14:40:55 +0000221 EXPECT_FALSE(r()->Resolve());
222 EXPECT_EQ(r()->error(),
223 R"(3:3 error: cannot initialize var of type 'i32' with value of type 'u32')");
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000224}
225
Ben Clayton68ae36e2022-06-24 21:26:39 +0000226TEST_F(ResolverVariableValidationTest, LetOfPtrConstructedWithRef) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000227 // var a : f32;
228 // let b : ptr<function,f32> = a;
dan sinclair2a651632023-02-19 04:03:55 +0000229 const auto priv = builtin::AddressSpace::kFunction;
dan sinclair41e4d9a2022-05-01 14:40:55 +0000230 auto* var_a = Var("a", ty.f32(), priv);
Ben Clayton1a8a19d2023-06-13 17:01:16 +0000231 auto* var_b = Let(Source{{12, 34}}, "b", ty.ptr<f32>(priv), Expr("a"));
dan sinclair41e4d9a2022-05-01 14:40:55 +0000232 WrapInFunction(var_a, var_b);
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000233
dan sinclair41e4d9a2022-05-01 14:40:55 +0000234 ASSERT_FALSE(r()->Resolve());
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000235
dan sinclair41e4d9a2022-05-01 14:40:55 +0000236 EXPECT_EQ(
237 r()->error(),
238 R"(12:34 error: cannot initialize let of type 'ptr<function, f32, read_write>' with value of type 'f32')");
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000239}
240
Ben Clayton68ae36e2022-06-24 21:26:39 +0000241TEST_F(ResolverVariableValidationTest, LocalLetRedeclared) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000242 // let l : f32 = 1.;
243 // let l : i32 = 0;
Ben Clayton0a3cda92022-05-10 17:30:15 +0000244 auto* l1 = Let("l", ty.f32(), Expr(1_f));
Ben Clayton0ce9ab02022-05-05 20:23:40 +0000245 auto* l2 = Let(Source{{12, 34}}, "l", ty.i32(), Expr(0_i));
dan sinclair41e4d9a2022-05-01 14:40:55 +0000246 WrapInFunction(l1, l2);
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000247
dan sinclair41e4d9a2022-05-01 14:40:55 +0000248 EXPECT_FALSE(r()->Resolve());
249 EXPECT_EQ(r()->error(),
250 "12:34 error: redeclaration of 'l'\nnote: 'l' previously declared here");
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000251}
252
Ben Clayton68ae36e2022-06-24 21:26:39 +0000253TEST_F(ResolverVariableValidationTest, GlobalVarRedeclaredAsLocal) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000254 // var v : f32 = 2.1;
255 // fn my_func() {
256 // var v : f32 = 2.0;
257 // return 0;
258 // }
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000259
dan sinclair2a651632023-02-19 04:03:55 +0000260 GlobalVar("v", ty.f32(), builtin::AddressSpace::kPrivate, Expr(2.1_f));
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000261
Ben Clayton58794ae2022-08-19 17:28:53 +0000262 WrapInFunction(Var(Source{{12, 34}}, "v", ty.f32(), Expr(2_f)));
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000263
dan sinclair41e4d9a2022-05-01 14:40:55 +0000264 EXPECT_TRUE(r()->Resolve()) << r()->error();
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000265}
266
Ben Clayton68ae36e2022-06-24 21:26:39 +0000267TEST_F(ResolverVariableValidationTest, VarRedeclaredInInnerBlock) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000268 // {
269 // var v : f32;
270 // { var v : f32; }
271 // }
Ben Clayton58794ae2022-08-19 17:28:53 +0000272 auto* var_outer = Var("v", ty.f32());
273 auto* var_inner = Var(Source{{12, 34}}, "v", ty.f32());
dan sinclair41e4d9a2022-05-01 14:40:55 +0000274 auto* inner = Block(Decl(var_inner));
275 auto* outer_body = Block(Decl(var_outer), inner);
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000276
dan sinclair41e4d9a2022-05-01 14:40:55 +0000277 WrapInFunction(outer_body);
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000278
dan sinclair41e4d9a2022-05-01 14:40:55 +0000279 EXPECT_TRUE(r()->Resolve()) << r()->error();
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000280}
281
Ben Clayton68ae36e2022-06-24 21:26:39 +0000282TEST_F(ResolverVariableValidationTest, VarRedeclaredInIfBlock) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000283 // {
284 // var v : f32 = 3.14;
285 // if (true) { var v : f32 = 2.0; }
286 // }
Ben Clayton58794ae2022-08-19 17:28:53 +0000287 auto* var_a_float = Var("v", ty.f32(), Expr(3.1_f));
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000288
Ben Clayton58794ae2022-08-19 17:28:53 +0000289 auto* var = Var(Source{{12, 34}}, "v", ty.f32(), Expr(2_f));
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000290
dan sinclair41e4d9a2022-05-01 14:40:55 +0000291 auto* cond = Expr(true);
292 auto* body = Block(Decl(var));
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000293
dan sinclair41e4d9a2022-05-01 14:40:55 +0000294 auto* outer_body = Block(Decl(var_a_float), If(cond, body));
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000295
dan sinclair41e4d9a2022-05-01 14:40:55 +0000296 WrapInFunction(outer_body);
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000297
dan sinclair41e4d9a2022-05-01 14:40:55 +0000298 EXPECT_TRUE(r()->Resolve()) << r()->error();
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000299}
300
Ben Clayton68ae36e2022-06-24 21:26:39 +0000301TEST_F(ResolverVariableValidationTest, InferredPtrStorageAccessMismatch) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000302 // struct Inner {
303 // arr: array<i32, 4>;
304 // }
305 // struct S {
306 // inner: Inner;
307 // }
308 // @group(0) @binding(0) var<storage> s : S;
309 // fn f() {
Ben Clayton0ce9ab02022-05-05 20:23:40 +0000310 // let p : pointer<storage, i32, read_write> = &s.inner.arr[2i];
dan sinclair41e4d9a2022-05-01 14:40:55 +0000311 // }
Ben Clayton783b1692022-08-02 17:03:35 +0000312 auto* inner = Structure("Inner", utils::Vector{
313 Member("arr", ty.array<i32, 4>()),
314 });
315 auto* buf = Structure("S", utils::Vector{
316 Member("inner", ty.Of(inner)),
317 });
Ben Clayton66805b02023-06-14 22:00:01 +0000318 auto* var =
dan sinclair2a651632023-02-19 04:03:55 +0000319 GlobalVar("s", ty.Of(buf), builtin::AddressSpace::kStorage, Binding(0_a), Group(0_a));
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000320
Ben Clayton66805b02023-06-14 22:00:01 +0000321 auto* expr = IndexAccessor(MemberAccessor(MemberAccessor(var, "inner"), "arr"), 2_i);
322 auto* ptr = Let(Source{{12, 34}}, "p", ty.ptr<storage, i32, read_write>(), AddressOf(expr));
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000323
dan sinclair41e4d9a2022-05-01 14:40:55 +0000324 WrapInFunction(ptr);
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000325
dan sinclair41e4d9a2022-05-01 14:40:55 +0000326 EXPECT_FALSE(r()->Resolve());
327 EXPECT_EQ(r()->error(),
328 "12:34 error: cannot initialize let of type "
329 "'ptr<storage, i32, read_write>' with value of type "
330 "'ptr<storage, i32, read>'");
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000331}
332
Ben Clayton68ae36e2022-06-24 21:26:39 +0000333TEST_F(ResolverVariableValidationTest, NonConstructibleType_Atomic) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000334 auto* v = Var("v", ty.atomic(Source{{12, 34}}, ty.i32()));
335 WrapInFunction(v);
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000336
dan sinclair41e4d9a2022-05-01 14:40:55 +0000337 EXPECT_FALSE(r()->Resolve());
Ben Claytonee49b1e2022-06-20 15:30:41 +0000338 EXPECT_EQ(r()->error(), "12:34 error: function-scope 'var' must have a constructible type");
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000339}
340
Ben Clayton68ae36e2022-06-24 21:26:39 +0000341TEST_F(ResolverVariableValidationTest, NonConstructibleType_RuntimeArray) {
Ben Clayton783b1692022-08-02 17:03:35 +0000342 auto* s = Structure("S", utils::Vector{
Ben Claytond205b712022-11-30 01:13:35 +0000343 Member(Source{{12, 34}}, "m", ty.array<i32>()),
Ben Clayton783b1692022-08-02 17:03:35 +0000344 });
Ben Claytond205b712022-11-30 01:13:35 +0000345 auto* v = Var(Source{{56, 78}}, "v", ty.Of(s));
dan sinclair41e4d9a2022-05-01 14:40:55 +0000346 WrapInFunction(v);
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000347
dan sinclair41e4d9a2022-05-01 14:40:55 +0000348 EXPECT_FALSE(r()->Resolve());
349 EXPECT_EQ(r()->error(),
Ben Claytond205b712022-11-30 01:13:35 +0000350 R"(error: runtime-sized arrays can only be used in the <storage> address space
35112:34 note: while analyzing structure member S.m
35256:78 note: while instantiating 'var' v)");
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000353}
354
Ben Clayton68ae36e2022-06-24 21:26:39 +0000355TEST_F(ResolverVariableValidationTest, NonConstructibleType_Struct_WithAtomic) {
Ben Clayton783b1692022-08-02 17:03:35 +0000356 auto* s = Structure("S", utils::Vector{
357 Member("m", ty.atomic(ty.i32())),
358 });
dan sinclair41e4d9a2022-05-01 14:40:55 +0000359 auto* v = Var("v", ty.Of(s));
360 WrapInFunction(v);
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000361
dan sinclair41e4d9a2022-05-01 14:40:55 +0000362 EXPECT_FALSE(r()->Resolve());
Ben Claytonee49b1e2022-06-20 15:30:41 +0000363 EXPECT_EQ(r()->error(), "error: function-scope 'var' must have a constructible type");
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000364}
365
Ben Clayton68ae36e2022-06-24 21:26:39 +0000366TEST_F(ResolverVariableValidationTest, NonConstructibleType_InferredType) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000367 // @group(0) @binding(0) var s : sampler;
368 // fn foo() {
369 // var v = s;
370 // }
dan sinclair3085e232023-01-23 16:24:12 +0000371 GlobalVar("s", ty.sampler(type::SamplerKind::kSampler), Group(0_a), Binding(0_a));
Ben Clayton58794ae2022-08-19 17:28:53 +0000372 auto* v = Var(Source{{12, 34}}, "v", Expr("s"));
dan sinclair41e4d9a2022-05-01 14:40:55 +0000373 WrapInFunction(v);
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000374
dan sinclair41e4d9a2022-05-01 14:40:55 +0000375 EXPECT_FALSE(r()->Resolve());
Ben Claytonee49b1e2022-06-20 15:30:41 +0000376 EXPECT_EQ(r()->error(), "12:34 error: function-scope 'var' must have a constructible type");
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000377}
378
dan sinclairff7cf212022-10-03 14:05:23 +0000379TEST_F(ResolverVariableValidationTest, InvalidAddressSpaceForInitializer) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000380 // var<workgroup> v : f32 = 1.23;
dan sinclair2a651632023-02-19 04:03:55 +0000381 GlobalVar(Source{{12, 34}}, "v", ty.f32(), builtin::AddressSpace::kWorkgroup, Expr(1.23_f));
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000382
dan sinclair41e4d9a2022-05-01 14:40:55 +0000383 EXPECT_FALSE(r()->Resolve());
384 EXPECT_EQ(r()->error(),
dan sinclairff7cf212022-10-03 14:05:23 +0000385 "12:34 error: var of address space 'workgroup' cannot have "
dan sinclair41e4d9a2022-05-01 14:40:55 +0000386 "an initializer. var initializers are only supported for the "
Ben Claytond205b712022-11-30 01:13:35 +0000387 "address spaces 'private' and 'function'");
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000388}
389
Ben Claytone3834c42022-06-25 23:21:39 +0000390TEST_F(ResolverVariableValidationTest, VectorConstNoType) {
Ben Clayton971318f2023-02-14 13:52:43 +0000391 // const a vec3 = vec3<f32>();
Ben Clayton66805b02023-06-14 22:00:01 +0000392 WrapInFunction(Const("a", ty.vec3<Infer>(Source{{12, 34}}), Call<vec3<f32>>()));
Ben Claytone3834c42022-06-25 23:21:39 +0000393
394 EXPECT_FALSE(r()->Resolve());
Ben Clayton971318f2023-02-14 13:52:43 +0000395 EXPECT_EQ(r()->error(), "12:34 error: expected '<' for 'vec3'");
Ben Claytone3834c42022-06-25 23:21:39 +0000396}
397
Ben Clayton68ae36e2022-06-24 21:26:39 +0000398TEST_F(ResolverVariableValidationTest, VectorLetNoType) {
Ben Clayton971318f2023-02-14 13:52:43 +0000399 // let a : vec3 = vec3<f32>();
Ben Clayton66805b02023-06-14 22:00:01 +0000400 WrapInFunction(Let("a", ty.vec3<Infer>(Source{{12, 34}}), Call<vec3<f32>>()));
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000401
dan sinclair41e4d9a2022-05-01 14:40:55 +0000402 EXPECT_FALSE(r()->Resolve());
Ben Clayton971318f2023-02-14 13:52:43 +0000403 EXPECT_EQ(r()->error(), "12:34 error: expected '<' for 'vec3'");
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000404}
405
Ben Clayton68ae36e2022-06-24 21:26:39 +0000406TEST_F(ResolverVariableValidationTest, VectorVarNoType) {
Ben Clayton971318f2023-02-14 13:52:43 +0000407 // var a : vec3;
408 WrapInFunction(Var("a", ty.vec3<Infer>(Source{{12, 34}})));
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000409
dan sinclair41e4d9a2022-05-01 14:40:55 +0000410 EXPECT_FALSE(r()->Resolve());
Ben Clayton971318f2023-02-14 13:52:43 +0000411 EXPECT_EQ(r()->error(), "12:34 error: expected '<' for 'vec3'");
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000412}
413
Ben Claytone3834c42022-06-25 23:21:39 +0000414TEST_F(ResolverVariableValidationTest, MatrixConstNoType) {
415 // const a : mat3x3 = mat3x3<f32>();
Ben Clayton66805b02023-06-14 22:00:01 +0000416 WrapInFunction(Const("a", ty.mat3x3<Infer>(Source{{12, 34}}), Call<mat3x3<f32>>()));
Ben Claytone3834c42022-06-25 23:21:39 +0000417
418 EXPECT_FALSE(r()->Resolve());
Ben Clayton971318f2023-02-14 13:52:43 +0000419 EXPECT_EQ(r()->error(), "12:34 error: expected '<' for 'mat3x3'");
Ben Claytone3834c42022-06-25 23:21:39 +0000420}
421
Ben Clayton68ae36e2022-06-24 21:26:39 +0000422TEST_F(ResolverVariableValidationTest, MatrixLetNoType) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000423 // let a : mat3x3 = mat3x3<f32>();
Ben Clayton66805b02023-06-14 22:00:01 +0000424 WrapInFunction(Let("a", ty.mat3x3<Infer>(Source{{12, 34}}), Call<mat3x3<f32>>()));
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000425
dan sinclair41e4d9a2022-05-01 14:40:55 +0000426 EXPECT_FALSE(r()->Resolve());
Ben Clayton971318f2023-02-14 13:52:43 +0000427 EXPECT_EQ(r()->error(), "12:34 error: expected '<' for 'mat3x3'");
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000428}
429
Ben Clayton68ae36e2022-06-24 21:26:39 +0000430TEST_F(ResolverVariableValidationTest, MatrixVarNoType) {
dan sinclair41e4d9a2022-05-01 14:40:55 +0000431 // var a : mat3x3;
Ben Clayton971318f2023-02-14 13:52:43 +0000432 WrapInFunction(Var("a", ty.mat3x3<Infer>(Source{{12, 34}})));
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000433
dan sinclair41e4d9a2022-05-01 14:40:55 +0000434 EXPECT_FALSE(r()->Resolve());
Ben Clayton971318f2023-02-14 13:52:43 +0000435 EXPECT_EQ(r()->error(), "12:34 error: expected '<' for 'mat3x3'");
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000436}
437
Ben Clayton9535f722022-11-02 18:14:59 +0000438TEST_F(ResolverVariableValidationTest, GlobalConstWithRuntimeExpression) {
439 GlobalConst("c", Call(Source{{12, 34}}, "dpdx", 1._a));
Ben Claytone3834c42022-06-25 23:21:39 +0000440
441 EXPECT_FALSE(r()->Resolve());
Ben Claytonc84d06e2022-10-13 17:23:06 +0000442 EXPECT_EQ(
443 r()->error(),
444 R"(12:34 error: const initializer requires a const-expression, but expression is a runtime-expression)");
Ben Claytone3834c42022-06-25 23:21:39 +0000445}
446
Ben Clayton9535f722022-11-02 18:14:59 +0000447TEST_F(ResolverVariableValidationTest, ConstInitWithVar) {
448 auto* v = Var("v", Expr(1_i));
449 auto* c = Const("c", Expr(Source{{12, 34}}, v));
450 WrapInFunction(v, Decl(Source{{56, 78}}, c));
451
452 EXPECT_FALSE(r()->Resolve());
453 EXPECT_EQ(
454 r()->error(),
455 R"(12:34 error: const initializer requires a const-expression, but expression is a runtime-expression
45656:78 note: consider changing 'const' to 'let')");
457}
458
Ben Claytone3834c42022-06-25 23:21:39 +0000459TEST_F(ResolverVariableValidationTest, ConstInitWithOverride) {
Ben Clayton58794ae2022-08-19 17:28:53 +0000460 auto* o = Override("v", Expr(1_i));
461 auto* c = Const("c", Expr(Source{{12, 34}}, o));
Ben Clayton9535f722022-11-02 18:14:59 +0000462 WrapInFunction(Decl(Source{{56, 78}}, c));
Ben Claytone3834c42022-06-25 23:21:39 +0000463
464 EXPECT_FALSE(r()->Resolve());
Ben Claytonc84d06e2022-10-13 17:23:06 +0000465 EXPECT_EQ(
466 r()->error(),
Ben Clayton9535f722022-11-02 18:14:59 +0000467 R"(12:34 error: const initializer requires a const-expression, but expression is an override-expression
46856:78 note: consider changing 'const' to 'let')");
Ben Claytone3834c42022-06-25 23:21:39 +0000469}
470
471TEST_F(ResolverVariableValidationTest, ConstInitWithLet) {
Ben Clayton58794ae2022-08-19 17:28:53 +0000472 auto* l = Let("v", Expr(1_i));
473 auto* c = Const("c", Expr(Source{{12, 34}}, l));
Ben Clayton9535f722022-11-02 18:14:59 +0000474 WrapInFunction(l, Decl(Source{{56, 78}}, c));
Ben Claytone3834c42022-06-25 23:21:39 +0000475
476 EXPECT_FALSE(r()->Resolve());
Ben Claytonc84d06e2022-10-13 17:23:06 +0000477 EXPECT_EQ(
478 r()->error(),
Ben Clayton9535f722022-11-02 18:14:59 +0000479 R"(12:34 error: const initializer requires a const-expression, but expression is a runtime-expression
48056:78 note: consider changing 'const' to 'let')");
Ben Claytonc84d06e2022-10-13 17:23:06 +0000481}
482
483TEST_F(ResolverVariableValidationTest, ConstInitWithRuntimeExpr) {
484 // const c = clamp(2, dpdx(0.5), 3);
Ben Clayton9535f722022-11-02 18:14:59 +0000485 auto* c = Const("c", Call("clamp", 2_a, Call(Source{{12, 34}}, "dpdx", 0.5_a), 3_a));
486 WrapInFunction(Decl(Source{{56, 78}}, c));
Ben Claytonc84d06e2022-10-13 17:23:06 +0000487
488 EXPECT_FALSE(r()->Resolve());
489 EXPECT_EQ(
490 r()->error(),
Ben Clayton9535f722022-11-02 18:14:59 +0000491 R"(12:34 error: const initializer requires a const-expression, but expression is a runtime-expression
49256:78 note: consider changing 'const' to 'let')");
Ben Claytonc84d06e2022-10-13 17:23:06 +0000493}
494
495TEST_F(ResolverVariableValidationTest, ConstInitWithOverrideExpr) {
496 auto* o = Override("v", Expr(1_i));
497 auto* c = Const("c", Add(10_a, Expr(Source{{12, 34}}, o)));
Ben Clayton9535f722022-11-02 18:14:59 +0000498 WrapInFunction(Decl(Source{{56, 78}}, c));
Ben Claytonc84d06e2022-10-13 17:23:06 +0000499
500 EXPECT_FALSE(r()->Resolve());
501 EXPECT_EQ(
502 r()->error(),
Ben Clayton9535f722022-11-02 18:14:59 +0000503 R"(12:34 error: const initializer requires a const-expression, but expression is an override-expression
50456:78 note: consider changing 'const' to 'let')");
Ben Claytone3834c42022-06-25 23:21:39 +0000505}
506
Ben Claytond205b712022-11-30 01:13:35 +0000507TEST_F(ResolverVariableValidationTest, GlobalVariable_PushConstantWithInitializer) {
508 // enable chromium_experimental_push_constant;
509 // var<push_constant> a : u32 = 0u;
dan sinclaire4039c72023-02-17 21:58:59 +0000510 Enable(builtin::Extension::kChromiumExperimentalPushConstant);
dan sinclair2a651632023-02-19 04:03:55 +0000511 GlobalVar(Source{{1u, 2u}}, "a", ty.u32(), builtin::AddressSpace::kPushConstant,
Ben Claytond205b712022-11-30 01:13:35 +0000512 Expr(Source{{3u, 4u}}, u32(0)));
513
514 ASSERT_FALSE(r()->Resolve());
515 EXPECT_EQ(
516 r()->error(),
517 R"(1:2 error: var of address space 'push_constant' cannot have an initializer. var initializers are only supported for the address spaces 'private' and 'function')");
518}
519
Ryan Harrisondbc13af2022-02-21 15:19:07 +0000520} // namespace
dan sinclaird2093792022-04-07 17:45:45 +0000521} // namespace tint::resolver