blob: 5d213c0e7612d3ccc2cdbfa3203a1fa3f88c1bb6 [file] [log] [blame]
Ben Clayton2c41f4f2021-03-09 15:12:57 +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
15#include "src/resolver/resolver.h"
16
17#include "gmock/gmock.h"
18#include "src/ast/assignment_statement.h"
19#include "src/ast/bitcast_expression.h"
20#include "src/ast/break_statement.h"
21#include "src/ast/call_statement.h"
22#include "src/ast/continue_statement.h"
23#include "src/ast/if_statement.h"
24#include "src/ast/intrinsic_texture_helper_test.h"
25#include "src/ast/loop_statement.h"
26#include "src/ast/return_statement.h"
27#include "src/ast/stage_decoration.h"
28#include "src/ast/switch_statement.h"
29#include "src/ast/unary_op_expression.h"
30#include "src/ast/variable_decl_statement.h"
31#include "src/resolver/resolver_test_helper.h"
Antonio Maioranoaea9c682021-04-19 22:54:43 +000032#include "src/sem/access_control_type.h"
Antonio Maiorano5cd71b82021-04-16 19:07:51 +000033#include "src/sem/call.h"
34#include "src/sem/function.h"
35#include "src/sem/member_accessor_expression.h"
Antonio Maioranoaea9c682021-04-19 22:54:43 +000036#include "src/sem/sampled_texture_type.h"
Antonio Maiorano5cd71b82021-04-16 19:07:51 +000037#include "src/sem/statement.h"
38#include "src/sem/variable.h"
Ben Clayton2c41f4f2021-03-09 15:12:57 +000039
40using ::testing::ElementsAre;
41using ::testing::HasSubstr;
42
43namespace tint {
44namespace resolver {
45namespace {
46
47using ResolverValidationTest = ResolverTest;
48
49class FakeStmt : public ast::Statement {
50 public:
Ben Claytone6995de2021-04-13 23:27:27 +000051 FakeStmt(ProgramID program_id, Source source)
52 : ast::Statement(program_id, source) {}
Ben Clayton2c41f4f2021-03-09 15:12:57 +000053 FakeStmt* Clone(CloneContext*) const override { return nullptr; }
Antonio Maiorano5cd71b82021-04-16 19:07:51 +000054 void to_str(const sem::Info&, std::ostream& out, size_t) const override {
Ben Clayton2c41f4f2021-03-09 15:12:57 +000055 out << "Fake";
56 }
57};
58
59class FakeExpr : public ast::Expression {
60 public:
Ben Claytone6995de2021-04-13 23:27:27 +000061 FakeExpr(ProgramID program_id, Source source)
62 : ast::Expression(program_id, source) {}
Ben Clayton2c41f4f2021-03-09 15:12:57 +000063 FakeExpr* Clone(CloneContext*) const override { return nullptr; }
Antonio Maiorano5cd71b82021-04-16 19:07:51 +000064 void to_str(const sem::Info&, std::ostream&, size_t) const override {}
Ben Clayton2c41f4f2021-03-09 15:12:57 +000065};
66
67TEST_F(ResolverValidationTest, Error_WithEmptySource) {
68 auto* s = create<FakeStmt>();
69 WrapInFunction(s);
70
71 EXPECT_FALSE(r()->Resolve());
72
73 EXPECT_EQ(r()->error(),
74 "error: unknown statement type for type determination: Fake");
75}
76
77TEST_F(ResolverValidationTest, Stmt_Error_Unknown) {
78 auto* s = create<FakeStmt>(Source{Source::Location{2, 30}});
79 WrapInFunction(s);
80
81 EXPECT_FALSE(r()->Resolve());
82
83 EXPECT_EQ(r()->error(),
84 "2:30 error: unknown statement type for type determination: Fake");
85}
86
87TEST_F(ResolverValidationTest, Stmt_Call_undeclared) {
Ben Clayton9328d942021-04-08 14:39:47 +000088 // fn main() {func(); return; }
89 // fn func() { return; }
Ben Clayton2c41f4f2021-03-09 15:12:57 +000090
91 SetSource(Source::Location{12, 34});
92 auto* call_expr = Call("func");
93 ast::VariableList params0;
94
95 Func("main", params0, ty.f32(),
96 ast::StatementList{
97 create<ast::CallStatement>(call_expr),
Ben Clayton43073d82021-04-22 13:50:53 +000098 Return(),
Ben Clayton2c41f4f2021-03-09 15:12:57 +000099 },
James Price95d40772021-03-11 17:39:32 +0000100 ast::DecorationList{});
Ben Clayton2c41f4f2021-03-09 15:12:57 +0000101
102 Func("func", params0, ty.f32(),
103 ast::StatementList{
Ben Clayton43073d82021-04-22 13:50:53 +0000104 Return(),
Ben Clayton2c41f4f2021-03-09 15:12:57 +0000105 },
James Price95d40772021-03-11 17:39:32 +0000106 ast::DecorationList{});
Ben Clayton2c41f4f2021-03-09 15:12:57 +0000107
108 EXPECT_FALSE(r()->Resolve());
109
110 EXPECT_EQ(r()->error(),
111 "12:34 error: v-0006: unable to find called function: func");
112}
113
114TEST_F(ResolverValidationTest, Stmt_Call_recursive) {
Ben Clayton9328d942021-04-08 14:39:47 +0000115 // fn main() {main(); }
Ben Clayton2c41f4f2021-03-09 15:12:57 +0000116
117 SetSource(Source::Location{12, 34});
118 auto* call_expr = Call("main");
119 ast::VariableList params0;
120
Antonio Maiorano03c01b52021-03-19 14:04:51 +0000121 Func("main", params0, ty.void_(),
Ben Clayton2c41f4f2021-03-09 15:12:57 +0000122 ast::StatementList{
123 create<ast::CallStatement>(call_expr),
124 },
James Price95d40772021-03-11 17:39:32 +0000125 ast::DecorationList{
Ben Clayton43073d82021-04-22 13:50:53 +0000126 Stage(ast::PipelineStage::kVertex),
Ben Clayton2c41f4f2021-03-09 15:12:57 +0000127 });
128
129 EXPECT_FALSE(r()->Resolve());
130
131 EXPECT_EQ(r()->error(),
Antonio Maiorano06feb3f2021-03-22 17:42:06 +0000132 "12:34 error v-0004: recursion is not permitted. 'main' attempted "
133 "to call "
Ben Clayton2c41f4f2021-03-09 15:12:57 +0000134 "itself.");
135}
136
Ben Clayton5fb87dd2021-03-09 15:17:28 +0000137TEST_F(ResolverValidationTest, Stmt_If_NonBool) {
138 // if (1.23f) {}
139
140 WrapInFunction(If(create<ast::ScalarConstructorExpression>(Source{{12, 34}},
141 Literal(1.23f)),
142 Block()));
143
144 EXPECT_FALSE(r()->Resolve());
145
146 EXPECT_EQ(r()->error(),
147 "12:34 error: if statement condition must be bool, got f32");
148}
149
Ben Clayton2c41f4f2021-03-09 15:12:57 +0000150TEST_F(ResolverValidationTest,
151 Stmt_VariableDecl_MismatchedTypeScalarConstructor) {
152 u32 unsigned_value = 2u; // Type does not match variable type
153 auto* var =
154 Var("my_var", ty.i32(), ast::StorageClass::kNone, Expr(unsigned_value));
155
Ben Clayton43073d82021-04-22 13:50:53 +0000156 auto* decl = Decl(Source{{{3, 3}, {3, 22}}}, var);
Ben Clayton2c41f4f2021-03-09 15:12:57 +0000157 WrapInFunction(decl);
158
159 EXPECT_FALSE(r()->Resolve());
160 EXPECT_EQ(
161 r()->error(),
Ben Clayton6b2fc052021-03-18 21:14:44 +0000162 R"(3:3 error: variable of type 'i32' cannot be initialized with a value of type 'u32')");
Ben Clayton2c41f4f2021-03-09 15:12:57 +0000163}
164
165TEST_F(ResolverValidationTest,
166 Stmt_VariableDecl_MismatchedTypeScalarConstructor_Alias) {
Ben Claytone204f272021-04-22 14:40:23 +0000167 auto my_int = ty.alias("MyInt", ty.i32());
Ben Clayton2c41f4f2021-03-09 15:12:57 +0000168 u32 unsigned_value = 2u; // Type does not match variable type
169 auto* var =
170 Var("my_var", my_int, ast::StorageClass::kNone, Expr(unsigned_value));
171
Ben Clayton43073d82021-04-22 13:50:53 +0000172 auto* decl = Decl(Source{{{3, 3}, {3, 22}}}, var);
Ben Clayton2c41f4f2021-03-09 15:12:57 +0000173 WrapInFunction(decl);
174
175 EXPECT_FALSE(r()->Resolve());
176 EXPECT_EQ(
177 r()->error(),
Ben Clayton6b2fc052021-03-18 21:14:44 +0000178 R"(3:3 error: variable of type 'MyInt' cannot be initialized with a value of type 'u32')");
Ben Clayton2c41f4f2021-03-09 15:12:57 +0000179}
180
181TEST_F(ResolverValidationTest, Expr_Error_Unknown) {
Ben Claytone6995de2021-04-13 23:27:27 +0000182 auto* e = create<FakeExpr>(Source{Source::Location{2, 30}});
183 WrapInFunction(e);
Ben Clayton2c41f4f2021-03-09 15:12:57 +0000184
185 EXPECT_FALSE(r()->Resolve());
186
187 EXPECT_EQ(r()->error(),
188 "2:30 error: unknown expression for type determination");
189}
190
191TEST_F(ResolverValidationTest, Expr_DontCall_Function) {
192 Func("func", {}, ty.void_(), {}, {});
193 auto* ident = create<ast::IdentifierExpression>(
194 Source{{Source::Location{3, 3}, Source::Location{3, 8}}},
195 Symbols().Register("func"));
196 WrapInFunction(ident);
197
198 EXPECT_FALSE(r()->Resolve());
199 EXPECT_EQ(r()->error(), "3:8 error: missing '(' for function call");
200}
201
202TEST_F(ResolverValidationTest, Expr_DontCall_Intrinsic) {
203 auto* ident = create<ast::IdentifierExpression>(
204 Source{{Source::Location{3, 3}, Source::Location{3, 8}}},
205 Symbols().Register("round"));
206 WrapInFunction(ident);
207
208 EXPECT_FALSE(r()->Resolve());
209 EXPECT_EQ(r()->error(), "3:8 error: missing '(' for intrinsic call");
210}
211
212TEST_F(ResolverValidationTest, UsingUndefinedVariable_Fail) {
213 // b = 2;
214
Antonio Maiorano4682e3f2021-03-22 17:38:45 +0000215 auto* lhs = Expr(Source{{12, 34}}, "b");
Ben Clayton2c41f4f2021-03-09 15:12:57 +0000216 auto* rhs = Expr(2);
Ben Clayton43073d82021-04-22 13:50:53 +0000217 auto* assign = Assign(lhs, rhs);
Ben Clayton2c41f4f2021-03-09 15:12:57 +0000218 WrapInFunction(assign);
219
220 EXPECT_FALSE(r()->Resolve());
221 EXPECT_EQ(r()->error(),
222 "12:34 error: v-0006: identifier must be declared before use: b");
223}
224
225TEST_F(ResolverValidationTest, UsingUndefinedVariableInBlockStatement_Fail) {
226 // {
227 // b = 2;
228 // }
229
Antonio Maiorano4682e3f2021-03-22 17:38:45 +0000230 auto* lhs = Expr(Source{{12, 34}}, "b");
Ben Clayton2c41f4f2021-03-09 15:12:57 +0000231 auto* rhs = Expr(2);
232
Ben Clayton43073d82021-04-22 13:50:53 +0000233 auto* body = Block(Assign(lhs, rhs));
Ben Clayton2c41f4f2021-03-09 15:12:57 +0000234 WrapInFunction(body);
235
236 EXPECT_FALSE(r()->Resolve());
237 EXPECT_EQ(r()->error(),
238 "12:34 error: v-0006: identifier must be declared before use: b");
239}
240
Antonio Maiorano4682e3f2021-03-22 17:38:45 +0000241TEST_F(ResolverValidationTest, UsingUndefinedVariableGlobalVariableAfter_Fail) {
Ben Clayton9328d942021-04-08 14:39:47 +0000242 // fn my_func() {
Antonio Maiorano4682e3f2021-03-22 17:38:45 +0000243 // global_var = 3.14f;
244 // }
245 // var global_var: f32 = 2.1;
246
247 auto* lhs = Expr(Source{{12, 34}}, "global_var");
248 auto* rhs = Expr(3.14f);
249
250 Func("my_func", ast::VariableList{}, ty.void_(),
251 ast::StatementList{
Ben Clayton43073d82021-04-22 13:50:53 +0000252 Assign(lhs, rhs),
Antonio Maiorano4682e3f2021-03-22 17:38:45 +0000253 },
Ben Clayton43073d82021-04-22 13:50:53 +0000254 ast::DecorationList{Stage(ast::PipelineStage::kVertex)});
Antonio Maiorano4682e3f2021-03-22 17:38:45 +0000255
256 Global("global_var", ty.f32(), ast::StorageClass::kPrivate, Expr(2.1f));
257
258 EXPECT_FALSE(r()->Resolve());
259 EXPECT_EQ(r()->error(),
260 "12:34 error: v-0006: identifier must be declared before use: "
261 "global_var");
262}
263
264TEST_F(ResolverValidationTest, UsingUndefinedVariableGlobalVariable_Pass) {
265 // var global_var: f32 = 2.1;
Ben Clayton9328d942021-04-08 14:39:47 +0000266 // fn my_func() {
Antonio Maiorano4682e3f2021-03-22 17:38:45 +0000267 // global_var = 3.14;
268 // return;
269 // }
270
271 Global("global_var", ty.f32(), ast::StorageClass::kPrivate, Expr(2.1f));
272
273 Func("my_func", ast::VariableList{}, ty.void_(),
274 ast::StatementList{
Ben Clayton43073d82021-04-22 13:50:53 +0000275 Assign(Expr(Source{Source::Location{12, 34}}, "global_var"), 3.14f),
276 Return(),
Antonio Maiorano4682e3f2021-03-22 17:38:45 +0000277 });
278
279 EXPECT_TRUE(r()->Resolve()) << r()->error();
280}
281
282TEST_F(ResolverValidationTest, UsingUndefinedVariableInnerScope_Fail) {
283 // {
284 // if (true) { var a : f32 = 2.0; }
285 // a = 3.14;
286 // }
287 auto* var = Var("a", ty.f32(), ast::StorageClass::kNone, Expr(2.0f));
288
289 auto* cond = Expr(true);
Ben Clayton43073d82021-04-22 13:50:53 +0000290 auto* body = Block(Decl(var));
Antonio Maiorano4682e3f2021-03-22 17:38:45 +0000291
292 SetSource(Source{Source::Location{12, 34}});
293 auto* lhs = Expr(Source{{12, 34}}, "a");
294 auto* rhs = Expr(3.14f);
295
Ben Clayton43073d82021-04-22 13:50:53 +0000296 auto* outer_body =
297 Block(create<ast::IfStatement>(cond, body, ast::ElseStatementList{}),
298 Assign(lhs, rhs));
Antonio Maiorano4682e3f2021-03-22 17:38:45 +0000299
300 WrapInFunction(outer_body);
301
302 EXPECT_FALSE(r()->Resolve());
303 EXPECT_EQ(r()->error(),
304 "12:34 error: v-0006: identifier must be declared before use: a");
305}
306
307TEST_F(ResolverValidationTest, UsingUndefinedVariableOuterScope_Pass) {
308 // {
309 // var a : f32 = 2.0;
310 // if (true) { a = 3.14; }
311 // }
312 auto* var = Var("a", ty.f32(), ast::StorageClass::kNone, Expr(2.0f));
313
314 auto* lhs = Expr(Source{{12, 34}}, "a");
315 auto* rhs = Expr(3.14f);
316
317 auto* cond = Expr(true);
Ben Clayton43073d82021-04-22 13:50:53 +0000318 auto* body = Block(Assign(lhs, rhs));
Antonio Maiorano4682e3f2021-03-22 17:38:45 +0000319
Ben Clayton43073d82021-04-22 13:50:53 +0000320 auto* outer_body =
321 Block(Decl(var),
322 create<ast::IfStatement>(cond, body, ast::ElseStatementList{}));
Antonio Maiorano4682e3f2021-03-22 17:38:45 +0000323
324 WrapInFunction(outer_body);
325
326 EXPECT_TRUE(r()->Resolve()) << r()->error();
327}
328
329TEST_F(ResolverValidationTest, UsingUndefinedVariableDifferentScope_Fail) {
330 // {
331 // { var a : f32 = 2.0; }
332 // { a = 3.14; }
333 // }
334 auto* var = Var("a", ty.f32(), ast::StorageClass::kNone, Expr(2.0f));
Ben Clayton43073d82021-04-22 13:50:53 +0000335 auto* first_body = Block(Decl(var));
Antonio Maiorano4682e3f2021-03-22 17:38:45 +0000336
337 auto* lhs = Expr(Source{{12, 34}}, "a");
338 auto* rhs = Expr(3.14f);
Ben Clayton43073d82021-04-22 13:50:53 +0000339 auto* second_body = Block(Assign(lhs, rhs));
Antonio Maiorano4682e3f2021-03-22 17:38:45 +0000340
Ben Clayton43073d82021-04-22 13:50:53 +0000341 auto* outer_body = Block(first_body, second_body);
Antonio Maiorano4682e3f2021-03-22 17:38:45 +0000342
343 WrapInFunction(outer_body);
344
345 EXPECT_FALSE(r()->Resolve());
346 EXPECT_EQ(r()->error(),
347 "12:34 error: v-0006: identifier must be declared before use: a");
348}
349
Ben Clayton2c41f4f2021-03-09 15:12:57 +0000350TEST_F(ResolverValidationTest, StorageClass_NonFunctionClassError) {
351 auto* var = Var("var", ty.i32(), ast::StorageClass::kWorkgroup);
352
Ben Clayton43073d82021-04-22 13:50:53 +0000353 auto* stmt = Decl(var);
Antonio Maiorano03c01b52021-03-19 14:04:51 +0000354 Func("func", ast::VariableList{}, ty.void_(), ast::StatementList{stmt},
James Price95d40772021-03-11 17:39:32 +0000355 ast::DecorationList{});
Ben Clayton2c41f4f2021-03-09 15:12:57 +0000356
357 EXPECT_FALSE(r()->Resolve());
358
359 EXPECT_EQ(r()->error(),
360 "error: function variable has a non-function storage class");
361}
362
363TEST_F(ResolverValidationTest, Expr_MemberAccessor_VectorSwizzle_BadChar) {
Antonio Maioranobbbb0ed2021-04-06 20:18:57 +0000364 Global("my_vec", ty.vec3<f32>(), ast::StorageClass::kInput);
Ben Clayton2c41f4f2021-03-09 15:12:57 +0000365
366 auto* ident = create<ast::IdentifierExpression>(
367 Source{{Source::Location{3, 3}, Source::Location{3, 7}}},
368 Symbols().Register("xyqz"));
369
370 auto* mem = MemberAccessor("my_vec", ident);
371 WrapInFunction(mem);
372
373 EXPECT_FALSE(r()->Resolve());
374 EXPECT_EQ(r()->error(), "3:5 error: invalid vector swizzle character");
375}
376
377TEST_F(ResolverValidationTest, Expr_MemberAccessor_VectorSwizzle_MixedChars) {
Antonio Maioranobbbb0ed2021-04-06 20:18:57 +0000378 Global("my_vec", ty.vec3<f32>(), ast::StorageClass::kInput);
Ben Clayton2c41f4f2021-03-09 15:12:57 +0000379
380 auto* ident = create<ast::IdentifierExpression>(
381 Source{{Source::Location{3, 3}, Source::Location{3, 7}}},
382 Symbols().Register("rgyw"));
383
384 auto* mem = MemberAccessor("my_vec", ident);
385 WrapInFunction(mem);
386
387 EXPECT_FALSE(r()->Resolve());
388 EXPECT_EQ(
389 r()->error(),
390 "3:3 error: invalid mixing of vector swizzle characters rgba with xyzw");
391}
392
393TEST_F(ResolverValidationTest, Expr_MemberAccessor_VectorSwizzle_BadLength) {
Antonio Maioranobbbb0ed2021-04-06 20:18:57 +0000394 Global("my_vec", ty.vec3<f32>(), ast::StorageClass::kInput);
Ben Clayton2c41f4f2021-03-09 15:12:57 +0000395
396 auto* ident = create<ast::IdentifierExpression>(
397 Source{{Source::Location{3, 3}, Source::Location{3, 8}}},
398 Symbols().Register("zzzzz"));
399 auto* mem = MemberAccessor("my_vec", ident);
400 WrapInFunction(mem);
401
402 EXPECT_FALSE(r()->Resolve());
403 EXPECT_EQ(r()->error(), "3:3 error: invalid vector swizzle size");
404}
405
406TEST_F(ResolverValidationTest,
407 Stmt_Loop_ContinueInLoopBodyBeforeDecl_UsageInContinuing) {
408 // loop {
409 // continue; // Bypasses z decl
410 // var z : i32;
411 //
412 // continuing {
413 // z = 2;
414 // }
415 // }
416
417 auto error_loc = Source{Source::Location{12, 34}};
418 auto* body = Block(create<ast::ContinueStatement>(),
419 Decl(Var("z", ty.i32(), ast::StorageClass::kNone)));
Ben Clayton43073d82021-04-22 13:50:53 +0000420 auto* continuing = Block(Assign(Expr(error_loc, "z"), 2));
Ben Clayton2c41f4f2021-03-09 15:12:57 +0000421 auto* loop_stmt = Loop(body, continuing);
422 WrapInFunction(loop_stmt);
423
424 EXPECT_FALSE(r()->Resolve()) << r()->error();
425 EXPECT_EQ(r()->error(),
426 "12:34 error: continue statement bypasses declaration of 'z' in "
427 "continuing block");
428}
429
430TEST_F(ResolverValidationTest,
431 Stmt_Loop_ContinueInLoopBodyBeforeDeclAndAfterDecl_UsageInContinuing) {
432 // loop {
433 // continue; // Bypasses z decl
434 // var z : i32;
435 // continue; // Ok
436 //
437 // continuing {
438 // z = 2;
439 // }
440 // }
441
442 auto error_loc = Source{Source::Location{12, 34}};
443 auto* body = Block(create<ast::ContinueStatement>(),
444 Decl(Var("z", ty.i32(), ast::StorageClass::kNone)),
445 create<ast::ContinueStatement>());
Ben Clayton43073d82021-04-22 13:50:53 +0000446 auto* continuing = Block(Assign(Expr(error_loc, "z"), 2));
Ben Clayton2c41f4f2021-03-09 15:12:57 +0000447 auto* loop_stmt = Loop(body, continuing);
448 WrapInFunction(loop_stmt);
449
450 EXPECT_FALSE(r()->Resolve()) << r()->error();
451 EXPECT_EQ(r()->error(),
452 "12:34 error: continue statement bypasses declaration of 'z' in "
453 "continuing block");
454}
455
456TEST_F(ResolverValidationTest,
457 Stmt_Loop_ContinueInLoopBodySubscopeBeforeDecl_UsageInContinuing) {
458 // loop {
459 // if (true) {
460 // continue; // Still bypasses z decl (if we reach here)
461 // }
462 // var z : i32;
463 // continuing {
464 // z = 2;
465 // }
466 // }
467
468 auto error_loc = Source{Source::Location{12, 34}};
469 auto* body = Block(If(Expr(true), Block(create<ast::ContinueStatement>())),
470 Decl(Var("z", ty.i32(), ast::StorageClass::kNone)));
Ben Clayton43073d82021-04-22 13:50:53 +0000471 auto* continuing = Block(Assign(Expr(error_loc, "z"), 2));
Ben Clayton2c41f4f2021-03-09 15:12:57 +0000472 auto* loop_stmt = Loop(body, continuing);
473 WrapInFunction(loop_stmt);
474
475 EXPECT_FALSE(r()->Resolve()) << r()->error();
476 EXPECT_EQ(r()->error(),
477 "12:34 error: continue statement bypasses declaration of 'z' in "
478 "continuing block");
479}
480
481TEST_F(
Arman Uguray3549e2e2021-03-15 21:21:33 +0000482 ResolverValidationTest,
Ben Clayton2c41f4f2021-03-09 15:12:57 +0000483 Stmt_Loop_ContinueInLoopBodySubscopeBeforeDecl_UsageInContinuingSubscope) {
484 // loop {
485 // if (true) {
486 // continue; // Still bypasses z decl (if we reach here)
487 // }
488 // var z : i32;
489 // continuing {
490 // if (true) {
491 // z = 2; // Must fail even if z is in a sub-scope
492 // }
493 // }
494 // }
495
496 auto error_loc = Source{Source::Location{12, 34}};
497 auto* body = Block(If(Expr(true), Block(create<ast::ContinueStatement>())),
498 Decl(Var("z", ty.i32(), ast::StorageClass::kNone)));
499
500 auto* continuing =
Ben Clayton43073d82021-04-22 13:50:53 +0000501 Block(If(Expr(true), Block(Assign(Expr(error_loc, "z"), 2))));
Ben Clayton2c41f4f2021-03-09 15:12:57 +0000502 auto* loop_stmt = Loop(body, continuing);
503 WrapInFunction(loop_stmt);
504
505 EXPECT_FALSE(r()->Resolve()) << r()->error();
506 EXPECT_EQ(r()->error(),
507 "12:34 error: continue statement bypasses declaration of 'z' in "
508 "continuing block");
509}
510
511TEST_F(ResolverValidationTest,
512 Stmt_Loop_ContinueInLoopBodySubscopeBeforeDecl_UsageInContinuingLoop) {
513 // loop {
514 // if (true) {
515 // continue; // Still bypasses z decl (if we reach here)
516 // }
517 // var z : i32;
518 // continuing {
519 // loop {
520 // z = 2; // Must fail even if z is in a sub-scope
521 // }
522 // }
523 // }
524
525 auto error_loc = Source{Source::Location{12, 34}};
526 auto* body = Block(If(Expr(true), Block(create<ast::ContinueStatement>())),
527 Decl(Var("z", ty.i32(), ast::StorageClass::kNone)));
528
Ben Clayton43073d82021-04-22 13:50:53 +0000529 auto* continuing = Block(Loop(Block(Assign(Expr(error_loc, "z"), 2))));
Ben Clayton2c41f4f2021-03-09 15:12:57 +0000530 auto* loop_stmt = Loop(body, continuing);
531 WrapInFunction(loop_stmt);
532
533 EXPECT_FALSE(r()->Resolve()) << r()->error();
534 EXPECT_EQ(r()->error(),
535 "12:34 error: continue statement bypasses declaration of 'z' in "
536 "continuing block");
537}
538
539TEST_F(ResolverValidationTest,
540 Stmt_Loop_ContinueInNestedLoopBodyBeforeDecl_UsageInContinuing) {
541 // loop {
542 // loop {
543 // continue; // OK: not part of the outer loop
544 // }
545 // var z : i32;
546 //
547 // continuing {
548 // z = 2;
549 // }
550 // }
551
552 auto* inner_loop = Loop(Block(create<ast::ContinueStatement>()));
553 auto* body =
554 Block(inner_loop, Decl(Var("z", ty.i32(), ast::StorageClass::kNone)));
Ben Clayton43073d82021-04-22 13:50:53 +0000555 auto* continuing = Block(Assign("z", 2));
Ben Clayton2c41f4f2021-03-09 15:12:57 +0000556 auto* loop_stmt = Loop(body, continuing);
557 WrapInFunction(loop_stmt);
558
559 EXPECT_TRUE(r()->Resolve()) << r()->error();
560}
561
562TEST_F(ResolverValidationTest,
563 Stmt_Loop_ContinueInNestedLoopBodyBeforeDecl_UsageInContinuingSubscope) {
564 // loop {
565 // loop {
566 // continue; // OK: not part of the outer loop
567 // }
568 // var z : i32;
569 //
570 // continuing {
571 // if (true) {
572 // z = 2;
573 // }
574 // }
575 // }
576
577 auto* inner_loop = Loop(Block(create<ast::ContinueStatement>()));
578 auto* body =
579 Block(inner_loop, Decl(Var("z", ty.i32(), ast::StorageClass::kNone)));
Ben Clayton43073d82021-04-22 13:50:53 +0000580 auto* continuing = Block(If(Expr(true), Block(Assign("z", 2))));
Ben Clayton2c41f4f2021-03-09 15:12:57 +0000581 auto* loop_stmt = Loop(body, continuing);
582 WrapInFunction(loop_stmt);
583
584 EXPECT_TRUE(r()->Resolve()) << r()->error();
585}
586
587TEST_F(ResolverValidationTest,
588 Stmt_Loop_ContinueInNestedLoopBodyBeforeDecl_UsageInContinuingLoop) {
589 // loop {
590 // loop {
591 // continue; // OK: not part of the outer loop
592 // }
593 // var z : i32;
594 //
595 // continuing {
596 // loop {
597 // z = 2;
598 // }
599 // }
600 // }
601
602 auto* inner_loop = Loop(Block(create<ast::ContinueStatement>()));
603 auto* body =
604 Block(inner_loop, Decl(Var("z", ty.i32(), ast::StorageClass::kNone)));
Ben Clayton43073d82021-04-22 13:50:53 +0000605 auto* continuing = Block(Loop(Block(Assign("z", 2))));
Ben Clayton2c41f4f2021-03-09 15:12:57 +0000606 auto* loop_stmt = Loop(body, continuing);
607 WrapInFunction(loop_stmt);
608
609 EXPECT_TRUE(r()->Resolve()) << r()->error();
610}
611
Ben Claytonf4c0d542021-03-10 23:15:09 +0000612TEST_F(ResolverTest, Stmt_Loop_ContinueInLoopBodyAfterDecl_UsageInContinuing) {
613 // loop {
614 // var z : i32;
615 // continue;
616 //
617 // continuing {
618 // z = 2;
619 // }
620 // }
621
622 auto error_loc = Source{Source::Location{12, 34}};
623 auto* body = Block(Decl(Var("z", ty.i32(), ast::StorageClass::kNone)),
624 create<ast::ContinueStatement>());
Ben Clayton43073d82021-04-22 13:50:53 +0000625 auto* continuing = Block(Assign(Expr(error_loc, "z"), 2));
Ben Claytonf4c0d542021-03-10 23:15:09 +0000626 auto* loop_stmt = Loop(body, continuing);
627 WrapInFunction(loop_stmt);
628
629 EXPECT_TRUE(r()->Resolve());
630}
631
Ben Clayton2c41f4f2021-03-09 15:12:57 +0000632TEST_F(ResolverValidationTest, Stmt_ContinueInLoop) {
633 WrapInFunction(Loop(Block(create<ast::ContinueStatement>(Source{{12, 34}}))));
634 EXPECT_TRUE(r()->Resolve()) << r()->error();
635}
636
637TEST_F(ResolverValidationTest, Stmt_ContinueNotInLoop) {
638 WrapInFunction(create<ast::ContinueStatement>(Source{{12, 34}}));
639 EXPECT_FALSE(r()->Resolve());
640 EXPECT_EQ(r()->error(), "12:34 error: continue statement must be in a loop");
641}
642
643TEST_F(ResolverValidationTest, Stmt_BreakInLoop) {
644 WrapInFunction(Loop(Block(create<ast::BreakStatement>(Source{{12, 34}}))));
645 EXPECT_TRUE(r()->Resolve()) << r()->error();
646}
647
648TEST_F(ResolverValidationTest, Stmt_BreakInSwitch) {
Antonio Maioranocea744d2021-03-25 12:55:27 +0000649 WrapInFunction(Loop(Block(Switch(
650 Expr(1),
651 Case(Literal(1), Block(create<ast::BreakStatement>(Source{{12, 34}}))),
652 DefaultCase()))));
Ben Clayton2c41f4f2021-03-09 15:12:57 +0000653 EXPECT_TRUE(r()->Resolve()) << r()->error();
654}
655
656TEST_F(ResolverValidationTest, Stmt_BreakNotInLoopOrSwitch) {
657 WrapInFunction(create<ast::BreakStatement>(Source{{12, 34}}));
658 EXPECT_FALSE(r()->Resolve());
659 EXPECT_EQ(r()->error(),
660 "12:34 error: break statement must be in a loop or switch case");
661}
662
Ben Claytond614dd52021-03-15 10:43:11 +0000663TEST_F(ResolverValidationTest, NonPOTStructMemberAlignDecoration) {
664 Structure("S", {
665 Member("a", ty.f32(), {MemberAlign(Source{{12, 34}}, 3)}),
666 });
667
668 EXPECT_FALSE(r()->Resolve());
669 EXPECT_EQ(
670 r()->error(),
671 "12:34 error: align value must be a positive, power-of-two integer");
672}
673
674TEST_F(ResolverValidationTest, ZeroStructMemberAlignDecoration) {
675 Structure("S", {
676 Member("a", ty.f32(), {MemberAlign(Source{{12, 34}}, 0)}),
677 });
678
679 EXPECT_FALSE(r()->Resolve());
680 EXPECT_EQ(
681 r()->error(),
682 "12:34 error: align value must be a positive, power-of-two integer");
683}
684
685TEST_F(ResolverValidationTest, ZeroStructMemberSizeDecoration) {
686 Structure("S", {
687 Member("a", ty.f32(), {MemberSize(Source{{12, 34}}, 0)}),
688 });
689
690 EXPECT_FALSE(r()->Resolve());
691 EXPECT_EQ(r()->error(),
692 "12:34 error: size must be at least as big as the type's size (4)");
693}
694
Ben Clayton2f9ced02021-03-15 20:34:22 +0000695TEST_F(ResolverValidationTest, OffsetAndSizeDecoration) {
696 Structure("S", {
697 Member(Source{{12, 34}}, "a", ty.f32(),
698 {MemberOffset(0), MemberSize(4)}),
699 });
700
701 EXPECT_FALSE(r()->Resolve());
702 EXPECT_EQ(r()->error(),
703 "12:34 error: offset decorations cannot be used with align or size "
704 "decorations");
705}
706
707TEST_F(ResolverValidationTest, OffsetAndAlignDecoration) {
708 Structure("S", {
709 Member(Source{{12, 34}}, "a", ty.f32(),
710 {MemberOffset(0), MemberAlign(4)}),
711 });
712
713 EXPECT_FALSE(r()->Resolve());
714 EXPECT_EQ(r()->error(),
715 "12:34 error: offset decorations cannot be used with align or size "
716 "decorations");
717}
718
719TEST_F(ResolverValidationTest, OffsetAndAlignAndSizeDecoration) {
720 Structure("S", {
721 Member(Source{{12, 34}}, "a", ty.f32(),
722 {MemberOffset(0), MemberAlign(4), MemberSize(4)}),
723 });
724
725 EXPECT_FALSE(r()->Resolve());
726 EXPECT_EQ(r()->error(),
727 "12:34 error: offset decorations cannot be used with align or size "
728 "decorations");
729}
730
Arman Uguray3549e2e2021-03-15 21:21:33 +0000731TEST_F(ResolverValidationTest,
732 Expr_Constructor_Vec2F32_Error_ScalarArgumentTypeMismatch) {
733 auto* tc = vec2<f32>(
734 create<ast::ScalarConstructorExpression>(Source{{12, 34}}, Literal(1)),
735 1.0f);
736 WrapInFunction(tc);
737
738 EXPECT_FALSE(r()->Resolve());
739 EXPECT_EQ(r()->error(),
740 "12:34 error: type in vector constructor does not match vector "
741 "type: expected 'f32', found 'i32'");
742}
743
744TEST_F(ResolverValidationTest,
745 Expr_Constructor_Vec2U32_Error_ScalarArgumentTypeMismatch) {
746 auto* tc = vec2<u32>(1u, create<ast::ScalarConstructorExpression>(
747 Source{{12, 34}}, Literal(1)));
748 WrapInFunction(tc);
749
750 EXPECT_FALSE(r()->Resolve());
751 EXPECT_EQ(r()->error(),
752 "12:34 error: type in vector constructor does not match vector "
753 "type: expected 'u32', found 'i32'");
754}
755
756TEST_F(ResolverValidationTest,
757 Expr_Constructor_Vec2I32_Error_ScalarArgumentTypeMismatch) {
758 auto* tc = vec2<i32>(
759 create<ast::ScalarConstructorExpression>(Source{{12, 34}}, Literal(1u)),
760 1);
761 WrapInFunction(tc);
762
763 EXPECT_FALSE(r()->Resolve());
764 EXPECT_EQ(r()->error(),
765 "12:34 error: type in vector constructor does not match vector "
766 "type: expected 'i32', found 'u32'");
767}
768
769TEST_F(ResolverValidationTest,
770 Expr_Constructor_Vec2Bool_Error_ScalarArgumentTypeMismatch) {
771 auto* tc = vec2<bool>(true, create<ast::ScalarConstructorExpression>(
772 Source{{12, 34}}, Literal(1)));
773 WrapInFunction(tc);
774
775 EXPECT_FALSE(r()->Resolve());
776 EXPECT_EQ(r()->error(),
777 "12:34 error: type in vector constructor does not match vector "
778 "type: expected 'bool', found 'i32'");
779}
780
781TEST_F(ResolverValidationTest,
782 Expr_Constructor_Vec2_Error_Vec3ArgumentCardinalityTooLarge) {
783 auto* tc = vec2<f32>(create<ast::TypeConstructorExpression>(
784 Source{{12, 34}}, ty.vec3<f32>(), ExprList()));
785 WrapInFunction(tc);
786
787 EXPECT_FALSE(r()->Resolve());
788 EXPECT_EQ(
789 r()->error(),
790 "12:34 error: attempted to construct 'vec2<f32>' with 3 component(s)");
791}
792
793TEST_F(ResolverValidationTest,
794 Expr_Constructor_Vec2_Error_Vec4ArgumentCardinalityTooLarge) {
795 auto* tc = vec2<f32>(create<ast::TypeConstructorExpression>(
796 Source{{12, 34}}, ty.vec4<f32>(), ExprList()));
797 WrapInFunction(tc);
798
799 EXPECT_FALSE(r()->Resolve());
800 EXPECT_EQ(
801 r()->error(),
802 "12:34 error: attempted to construct 'vec2<f32>' with 4 component(s)");
803}
804
805TEST_F(ResolverValidationTest,
806 Expr_Constructor_Vec2_Error_TooFewArgumentsScalar) {
807 auto* tc = vec2<f32>(create<ast::ScalarConstructorExpression>(
808 Source{{12, 34}}, Literal(1.0f)));
809 WrapInFunction(tc);
810
811 EXPECT_FALSE(r()->Resolve());
812 EXPECT_EQ(
813 r()->error(),
814 "12:34 error: attempted to construct 'vec2<f32>' with 1 component(s)");
815}
816
817TEST_F(ResolverValidationTest,
818 Expr_Constructor_Vec2_Error_TooManyArgumentsScalar) {
819 auto* tc = vec2<f32>(
820 create<ast::ScalarConstructorExpression>(Source{{12, 34}}, Literal(1.0f)),
821 create<ast::ScalarConstructorExpression>(Source{{12, 40}}, Literal(1.0f)),
822 create<ast::ScalarConstructorExpression>(Source{{12, 46}},
823 Literal(1.0f)));
824 WrapInFunction(tc);
825
826 EXPECT_FALSE(r()->Resolve());
827 EXPECT_EQ(
828 r()->error(),
829 "12:34 error: attempted to construct 'vec2<f32>' with 3 component(s)");
830}
831
832TEST_F(ResolverValidationTest,
833 Expr_Constructor_Vec2_Error_TooManyArgumentsVector) {
834 auto* tc = vec2<f32>(create<ast::TypeConstructorExpression>(
835 Source{{12, 34}}, ty.vec2<f32>(), ExprList()),
836 create<ast::TypeConstructorExpression>(
837 Source{{12, 40}}, ty.vec2<f32>(), ExprList()));
838 WrapInFunction(tc);
839
840 EXPECT_FALSE(r()->Resolve());
841 EXPECT_EQ(
842 r()->error(),
843 "12:34 error: attempted to construct 'vec2<f32>' with 4 component(s)");
844}
845
846TEST_F(ResolverValidationTest,
847 Expr_Constructor_Vec2_Error_TooManyArgumentsVectorAndScalar) {
848 auto* tc = vec2<f32>(create<ast::TypeConstructorExpression>(
849 Source{{12, 34}}, ty.vec2<f32>(), ExprList()),
850 create<ast::ScalarConstructorExpression>(
851 Source{{12, 40}}, Literal(1.0f)));
852 WrapInFunction(tc);
853
854 EXPECT_FALSE(r()->Resolve());
855 EXPECT_EQ(
856 r()->error(),
857 "12:34 error: attempted to construct 'vec2<f32>' with 3 component(s)");
858}
859
860TEST_F(ResolverValidationTest,
861 Expr_Constructor_Vec2_Error_InvalidConversionFromVec2Bool) {
862 SetSource(Source::Location({12, 34}));
863
864 auto* tc = vec2<f32>(create<ast::TypeConstructorExpression>(
865 Source{{12, 34}}, ty.vec2<bool>(), ExprList()));
866 WrapInFunction(tc);
867
868 EXPECT_FALSE(r()->Resolve());
869 EXPECT_EQ(r()->error(),
870 "12:34 error: type in vector constructor does not match vector "
871 "type: expected 'f32', found 'bool'");
872}
873
874TEST_F(ResolverValidationTest,
875 Expr_Constructor_Vec2_Error_InvalidArgumentType) {
876 auto* tc = vec2<f32>(create<ast::TypeConstructorExpression>(
877 Source{{12, 34}}, ty.mat2x2<f32>(), ExprList()));
878 WrapInFunction(tc);
879
880 EXPECT_FALSE(r()->Resolve());
881 EXPECT_EQ(r()->error(),
882 "12:34 error: expected vector or scalar type in vector "
883 "constructor; found: mat2x2<f32>");
884}
885
886TEST_F(ResolverValidationTest, Expr_Constructor_Vec2_Success_ZeroValue) {
887 auto* tc = vec2<f32>();
888 WrapInFunction(tc);
889
890 EXPECT_TRUE(r()->Resolve()) << r()->error();
891
892 ASSERT_NE(TypeOf(tc), nullptr);
Antonio Maiorano3751fd22021-04-19 22:51:23 +0000893 ASSERT_TRUE(TypeOf(tc)->Is<sem::Vector>());
894 EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::F32>());
895 EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->size(), 2u);
Arman Uguray3549e2e2021-03-15 21:21:33 +0000896}
897
898TEST_F(ResolverValidationTest, Expr_Constructor_Vec2F32_Success_Scalar) {
899 auto* tc = vec2<f32>(1.0f, 1.0f);
900 WrapInFunction(tc);
901
902 EXPECT_TRUE(r()->Resolve()) << r()->error();
903
904 ASSERT_NE(TypeOf(tc), nullptr);
Antonio Maiorano3751fd22021-04-19 22:51:23 +0000905 ASSERT_TRUE(TypeOf(tc)->Is<sem::Vector>());
906 EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::F32>());
907 EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->size(), 2u);
Arman Uguray3549e2e2021-03-15 21:21:33 +0000908}
909
910TEST_F(ResolverValidationTest, Expr_Constructor_Vec2U32_Success_Scalar) {
911 auto* tc = vec2<u32>(1u, 1u);
912 WrapInFunction(tc);
913
914 EXPECT_TRUE(r()->Resolve()) << r()->error();
915
916 ASSERT_NE(TypeOf(tc), nullptr);
Antonio Maiorano3751fd22021-04-19 22:51:23 +0000917 ASSERT_TRUE(TypeOf(tc)->Is<sem::Vector>());
918 EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::U32>());
919 EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->size(), 2u);
Arman Uguray3549e2e2021-03-15 21:21:33 +0000920}
921
922TEST_F(ResolverValidationTest, Expr_Constructor_Vec2I32_Success_Scalar) {
923 auto* tc = vec2<i32>(1, 1);
924 WrapInFunction(tc);
925
926 EXPECT_TRUE(r()->Resolve()) << r()->error();
927
928 ASSERT_NE(TypeOf(tc), nullptr);
Antonio Maiorano3751fd22021-04-19 22:51:23 +0000929 ASSERT_TRUE(TypeOf(tc)->Is<sem::Vector>());
930 EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::I32>());
931 EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->size(), 2u);
Arman Uguray3549e2e2021-03-15 21:21:33 +0000932}
933
934TEST_F(ResolverValidationTest, Expr_Constructor_Vec2Bool_Success_Scalar) {
935 auto* tc = vec2<bool>(true, false);
936 WrapInFunction(tc);
937
938 EXPECT_TRUE(r()->Resolve()) << r()->error();
939
940 ASSERT_NE(TypeOf(tc), nullptr);
Antonio Maiorano3751fd22021-04-19 22:51:23 +0000941 ASSERT_TRUE(TypeOf(tc)->Is<sem::Vector>());
942 EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::Bool>());
943 EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->size(), 2u);
Arman Uguray3549e2e2021-03-15 21:21:33 +0000944}
945
946TEST_F(ResolverValidationTest, Expr_Constructor_Vec2_Success_Identity) {
947 auto* tc = vec2<f32>(vec2<f32>());
948 WrapInFunction(tc);
949
950 EXPECT_TRUE(r()->Resolve()) << r()->error();
951
952 ASSERT_NE(TypeOf(tc), nullptr);
Antonio Maiorano3751fd22021-04-19 22:51:23 +0000953 ASSERT_TRUE(TypeOf(tc)->Is<sem::Vector>());
954 EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::F32>());
955 EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->size(), 2u);
Arman Uguray3549e2e2021-03-15 21:21:33 +0000956}
957
958TEST_F(ResolverValidationTest,
959 Expr_Constructor_Vec2_Success_Vec2TypeConversion) {
960 auto* tc = vec2<f32>(vec2<i32>());
961 WrapInFunction(tc);
962
963 EXPECT_TRUE(r()->Resolve()) << r()->error();
964
965 ASSERT_NE(TypeOf(tc), nullptr);
Antonio Maiorano3751fd22021-04-19 22:51:23 +0000966 ASSERT_TRUE(TypeOf(tc)->Is<sem::Vector>());
967 EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::F32>());
968 EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->size(), 2u);
Arman Uguray3549e2e2021-03-15 21:21:33 +0000969}
970
971TEST_F(ResolverValidationTest,
972 Expr_Constructor_Vec3F32_Error_ScalarArgumentTypeMismatch) {
973 auto* tc = vec3<f32>(
974 1.0f, 1.0f,
975 create<ast::ScalarConstructorExpression>(Source{{12, 34}}, Literal(1)));
976 WrapInFunction(tc);
977
978 EXPECT_FALSE(r()->Resolve());
979 EXPECT_EQ(r()->error(),
980 "12:34 error: type in vector constructor does not match vector "
981 "type: expected 'f32', found 'i32'");
982}
983
984TEST_F(ResolverValidationTest,
985 Expr_Constructor_Vec3U32_Error_ScalarArgumentTypeMismatch) {
986 auto* tc = vec3<u32>(
987 1u,
988 create<ast::ScalarConstructorExpression>(Source{{12, 34}}, Literal(1)),
989 1u);
990 WrapInFunction(tc);
991
992 EXPECT_FALSE(r()->Resolve());
993 EXPECT_EQ(r()->error(),
994 "12:34 error: type in vector constructor does not match vector "
995 "type: expected 'u32', found 'i32'");
996}
997
998TEST_F(ResolverValidationTest,
999 Expr_Constructor_Vec3I32_Error_ScalarArgumentTypeMismatch) {
1000 auto* tc = vec3<i32>(
1001 1,
1002 create<ast::ScalarConstructorExpression>(Source{{12, 34}}, Literal(1u)),
1003 1);
1004 WrapInFunction(tc);
1005
1006 EXPECT_FALSE(r()->Resolve());
1007 EXPECT_EQ(r()->error(),
1008 "12:34 error: type in vector constructor does not match vector "
1009 "type: expected 'i32', found 'u32'");
1010}
1011
1012TEST_F(ResolverValidationTest,
1013 Expr_Constructor_Vec3Bool_Error_ScalarArgumentTypeMismatch) {
1014 auto* tc = vec3<bool>(
1015 true,
1016 create<ast::ScalarConstructorExpression>(Source{{12, 34}}, Literal(1)),
1017 false);
1018 WrapInFunction(tc);
1019
1020 EXPECT_FALSE(r()->Resolve());
1021 EXPECT_EQ(r()->error(),
1022 "12:34 error: type in vector constructor does not match vector "
1023 "type: expected 'bool', found 'i32'");
1024}
1025
1026TEST_F(ResolverValidationTest,
1027 Expr_Constructor_Vec3_Error_Vec4ArgumentCardinalityTooLarge) {
1028 auto* tc = vec3<f32>(create<ast::TypeConstructorExpression>(
1029 Source{{12, 34}}, ty.vec4<f32>(), ExprList()));
1030 WrapInFunction(tc);
1031
1032 EXPECT_FALSE(r()->Resolve());
1033 EXPECT_EQ(
1034 r()->error(),
1035 "12:34 error: attempted to construct 'vec3<f32>' with 4 component(s)");
1036}
1037
1038TEST_F(ResolverValidationTest,
1039 Expr_Constructor_Vec3_Error_TooFewArgumentsScalar) {
1040 auto* tc = vec3<f32>(
1041 create<ast::ScalarConstructorExpression>(Source{{12, 34}}, Literal(1.0f)),
1042 create<ast::ScalarConstructorExpression>(Source{{12, 40}},
1043 Literal(1.0f)));
1044 WrapInFunction(tc);
1045
1046 EXPECT_FALSE(r()->Resolve());
1047 EXPECT_EQ(
1048 r()->error(),
1049 "12:34 error: attempted to construct 'vec3<f32>' with 2 component(s)");
1050}
1051
1052TEST_F(ResolverValidationTest,
1053 Expr_Constructor_Vec3_Error_TooManyArgumentsScalar) {
1054 auto* tc = vec3<f32>(
1055 create<ast::ScalarConstructorExpression>(Source{{12, 34}}, Literal(1.0f)),
1056 create<ast::ScalarConstructorExpression>(Source{{12, 40}}, Literal(1.0f)),
1057 create<ast::ScalarConstructorExpression>(Source{{12, 46}}, Literal(1.0f)),
1058 create<ast::ScalarConstructorExpression>(Source{{12, 52}},
1059 Literal(1.0f)));
1060 WrapInFunction(tc);
1061
1062 EXPECT_FALSE(r()->Resolve());
1063 EXPECT_EQ(
1064 r()->error(),
1065 "12:34 error: attempted to construct 'vec3<f32>' with 4 component(s)");
1066}
1067
1068TEST_F(ResolverValidationTest,
1069 Expr_Constructor_Vec3_Error_TooFewArgumentsVec2) {
1070 auto* tc = vec3<f32>(create<ast::TypeConstructorExpression>(
1071 Source{{12, 34}}, ty.vec2<f32>(), ExprList()));
1072 WrapInFunction(tc);
1073
1074 EXPECT_FALSE(r()->Resolve());
1075 EXPECT_EQ(
1076 r()->error(),
1077 "12:34 error: attempted to construct 'vec3<f32>' with 2 component(s)");
1078}
1079
1080TEST_F(ResolverValidationTest,
1081 Expr_Constructor_Vec3_Error_TooManyArgumentsVec2) {
1082 auto* tc = vec3<f32>(create<ast::TypeConstructorExpression>(
1083 Source{{12, 34}}, ty.vec2<f32>(), ExprList()),
1084 create<ast::TypeConstructorExpression>(
1085 Source{{12, 40}}, ty.vec2<f32>(), ExprList()));
1086 WrapInFunction(tc);
1087
1088 EXPECT_FALSE(r()->Resolve());
1089 EXPECT_EQ(
1090 r()->error(),
1091 "12:34 error: attempted to construct 'vec3<f32>' with 4 component(s)");
1092}
1093
1094TEST_F(ResolverValidationTest,
1095 Expr_Constructor_Vec3_Error_TooManyArgumentsVec2AndScalar) {
1096 auto* tc = vec3<f32>(
1097 create<ast::TypeConstructorExpression>(Source{{12, 34}}, ty.vec2<f32>(),
1098 ExprList()),
1099 create<ast::ScalarConstructorExpression>(Source{{12, 40}}, Literal(1.0f)),
1100 create<ast::ScalarConstructorExpression>(Source{{12, 46}},
1101 Literal(1.0f)));
1102 WrapInFunction(tc);
1103
1104 EXPECT_FALSE(r()->Resolve());
1105 EXPECT_EQ(
1106 r()->error(),
1107 "12:34 error: attempted to construct 'vec3<f32>' with 4 component(s)");
1108}
1109
1110TEST_F(ResolverValidationTest,
1111 Expr_Constructor_Vec3_Error_TooManyArgumentsVec3) {
1112 auto* tc = vec3<f32>(create<ast::TypeConstructorExpression>(
1113 Source{{12, 34}}, ty.vec3<f32>(), ExprList()),
1114 create<ast::ScalarConstructorExpression>(
1115 Source{{12, 40}}, Literal(1.0f)));
1116 WrapInFunction(tc);
1117
1118 EXPECT_FALSE(r()->Resolve());
1119 EXPECT_EQ(
1120 r()->error(),
1121 "12:34 error: attempted to construct 'vec3<f32>' with 4 component(s)");
1122}
1123
1124TEST_F(ResolverValidationTest,
1125 Expr_Constructor_Vec3_Error_InvalidConversionFromVec3Bool) {
1126 auto* tc = vec3<f32>(create<ast::TypeConstructorExpression>(
1127 Source{{12, 34}}, ty.vec3<bool>(), ExprList()));
1128 WrapInFunction(tc);
1129
1130 EXPECT_FALSE(r()->Resolve());
1131 EXPECT_EQ(r()->error(),
1132 "12:34 error: type in vector constructor does not match vector "
1133 "type: expected 'f32', found 'bool'");
1134}
1135
1136TEST_F(ResolverValidationTest,
1137 Expr_Constructor_Vec3_Error_InvalidArgumentType) {
1138 auto* tc = vec3<f32>(create<ast::TypeConstructorExpression>(
1139 Source{{12, 34}}, ty.mat2x2<f32>(), ExprList()));
1140 WrapInFunction(tc);
1141
1142 EXPECT_FALSE(r()->Resolve());
1143 EXPECT_EQ(r()->error(),
1144 "12:34 error: expected vector or scalar type in vector "
1145 "constructor; found: mat2x2<f32>");
1146}
1147
1148TEST_F(ResolverValidationTest, Expr_Constructor_Vec3_Success_ZeroValue) {
1149 auto* tc = vec3<f32>();
1150 WrapInFunction(tc);
1151
1152 EXPECT_TRUE(r()->Resolve()) << r()->error();
1153
1154 ASSERT_NE(TypeOf(tc), nullptr);
Antonio Maiorano3751fd22021-04-19 22:51:23 +00001155 ASSERT_TRUE(TypeOf(tc)->Is<sem::Vector>());
1156 EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::F32>());
1157 EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->size(), 3u);
Arman Uguray3549e2e2021-03-15 21:21:33 +00001158}
1159
1160TEST_F(ResolverValidationTest, Expr_Constructor_Vec3F32_Success_Scalar) {
1161 auto* tc = vec3<f32>(1.0f, 1.0f, 1.0f);
1162 WrapInFunction(tc);
1163
1164 EXPECT_TRUE(r()->Resolve()) << r()->error();
1165
1166 ASSERT_NE(TypeOf(tc), nullptr);
Antonio Maiorano3751fd22021-04-19 22:51:23 +00001167 ASSERT_TRUE(TypeOf(tc)->Is<sem::Vector>());
1168 EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::F32>());
1169 EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->size(), 3u);
Arman Uguray3549e2e2021-03-15 21:21:33 +00001170}
1171
1172TEST_F(ResolverValidationTest, Expr_Constructor_Vec3U32_Success_Scalar) {
1173 auto* tc = vec3<u32>(1u, 1u, 1u);
1174 WrapInFunction(tc);
1175
1176 EXPECT_TRUE(r()->Resolve()) << r()->error();
1177
1178 ASSERT_NE(TypeOf(tc), nullptr);
Antonio Maiorano3751fd22021-04-19 22:51:23 +00001179 ASSERT_TRUE(TypeOf(tc)->Is<sem::Vector>());
1180 EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::U32>());
1181 EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->size(), 3u);
Arman Uguray3549e2e2021-03-15 21:21:33 +00001182}
1183
1184TEST_F(ResolverValidationTest, Expr_Constructor_Vec3I32_Success_Scalar) {
1185 auto* tc = vec3<i32>(1, 1, 1);
1186 WrapInFunction(tc);
1187
1188 EXPECT_TRUE(r()->Resolve()) << r()->error();
1189
1190 ASSERT_NE(TypeOf(tc), nullptr);
Antonio Maiorano3751fd22021-04-19 22:51:23 +00001191 ASSERT_TRUE(TypeOf(tc)->Is<sem::Vector>());
1192 EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::I32>());
1193 EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->size(), 3u);
Arman Uguray3549e2e2021-03-15 21:21:33 +00001194}
1195
1196TEST_F(ResolverValidationTest, Expr_Constructor_Vec3Bool_Success_Scalar) {
1197 auto* tc = vec3<bool>(true, false, true);
1198 WrapInFunction(tc);
1199
1200 EXPECT_TRUE(r()->Resolve()) << r()->error();
1201
1202 ASSERT_NE(TypeOf(tc), nullptr);
Antonio Maiorano3751fd22021-04-19 22:51:23 +00001203 ASSERT_TRUE(TypeOf(tc)->Is<sem::Vector>());
1204 EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::Bool>());
1205 EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->size(), 3u);
Arman Uguray3549e2e2021-03-15 21:21:33 +00001206}
1207
1208TEST_F(ResolverValidationTest, Expr_Constructor_Vec3_Success_Vec2AndScalar) {
1209 auto* tc = vec3<f32>(vec2<f32>(), 1.0f);
1210 WrapInFunction(tc);
1211
1212 EXPECT_TRUE(r()->Resolve()) << r()->error();
1213
1214 ASSERT_NE(TypeOf(tc), nullptr);
Antonio Maiorano3751fd22021-04-19 22:51:23 +00001215 ASSERT_TRUE(TypeOf(tc)->Is<sem::Vector>());
1216 EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::F32>());
1217 EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->size(), 3u);
Arman Uguray3549e2e2021-03-15 21:21:33 +00001218}
1219
1220TEST_F(ResolverValidationTest, Expr_Constructor_Vec3_Success_ScalarAndVec2) {
1221 auto* tc = vec3<f32>(1.0f, vec2<f32>());
1222 WrapInFunction(tc);
1223
1224 EXPECT_TRUE(r()->Resolve()) << r()->error();
1225
1226 ASSERT_NE(TypeOf(tc), nullptr);
Antonio Maiorano3751fd22021-04-19 22:51:23 +00001227 ASSERT_TRUE(TypeOf(tc)->Is<sem::Vector>());
1228 EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::F32>());
1229 EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->size(), 3u);
Arman Uguray3549e2e2021-03-15 21:21:33 +00001230}
1231
1232TEST_F(ResolverValidationTest, Expr_Constructor_Vec3_Success_Identity) {
1233 auto* tc = vec3<f32>(vec3<f32>());
1234 WrapInFunction(tc);
1235
1236 EXPECT_TRUE(r()->Resolve()) << r()->error();
1237
1238 ASSERT_NE(TypeOf(tc), nullptr);
Antonio Maiorano3751fd22021-04-19 22:51:23 +00001239 ASSERT_TRUE(TypeOf(tc)->Is<sem::Vector>());
1240 EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::F32>());
1241 EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->size(), 3u);
Arman Uguray3549e2e2021-03-15 21:21:33 +00001242}
1243
1244TEST_F(ResolverValidationTest,
1245 Expr_Constructor_Vec3_Success_Vec3TypeConversion) {
1246 auto* tc = vec3<f32>(vec3<i32>());
1247 WrapInFunction(tc);
1248
1249 EXPECT_TRUE(r()->Resolve()) << r()->error();
1250
1251 ASSERT_NE(TypeOf(tc), nullptr);
Antonio Maiorano3751fd22021-04-19 22:51:23 +00001252 ASSERT_TRUE(TypeOf(tc)->Is<sem::Vector>());
1253 EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::F32>());
1254 EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->size(), 3u);
Arman Uguray3549e2e2021-03-15 21:21:33 +00001255}
1256
1257TEST_F(ResolverValidationTest,
1258 Expr_Constructor_Vec4F32_Error_ScalarArgumentTypeMismatch) {
1259 auto* tc = vec4<f32>(
1260 1.0f, 1.0f,
1261 create<ast::ScalarConstructorExpression>(Source{{12, 34}}, Literal(1)),
1262 1.0f);
1263 WrapInFunction(tc);
1264
1265 EXPECT_FALSE(r()->Resolve());
1266 EXPECT_EQ(r()->error(),
1267 "12:34 error: type in vector constructor does not match vector "
1268 "type: expected 'f32', found 'i32'");
1269}
1270
1271TEST_F(ResolverValidationTest,
1272 Expr_Constructor_Vec4U32_Error_ScalarArgumentTypeMismatch) {
1273 auto* tc = vec4<u32>(
1274 1u, 1u,
1275 create<ast::ScalarConstructorExpression>(Source{{12, 34}}, Literal(1)),
1276 1u);
1277 WrapInFunction(tc);
1278
1279 EXPECT_FALSE(r()->Resolve());
1280 EXPECT_EQ(r()->error(),
1281 "12:34 error: type in vector constructor does not match vector "
1282 "type: expected 'u32', found 'i32'");
1283}
1284
1285TEST_F(ResolverValidationTest,
1286 Expr_Constructor_Vec4I32_Error_ScalarArgumentTypeMismatch) {
1287 auto* tc = vec4<i32>(
1288 1, 1,
1289 create<ast::ScalarConstructorExpression>(Source{{12, 34}}, Literal(1u)),
1290 1);
1291 WrapInFunction(tc);
1292
1293 EXPECT_FALSE(r()->Resolve());
1294 EXPECT_EQ(r()->error(),
1295 "12:34 error: type in vector constructor does not match vector "
1296 "type: expected 'i32', found 'u32'");
1297}
1298
1299TEST_F(ResolverValidationTest,
1300 Expr_Constructor_Vec4Bool_Error_ScalarArgumentTypeMismatch) {
1301 auto* tc = vec4<bool>(
1302 true, false,
1303 create<ast::ScalarConstructorExpression>(Source{{12, 34}}, Literal(1)),
1304 true);
1305 WrapInFunction(tc);
1306
1307 EXPECT_FALSE(r()->Resolve());
1308 EXPECT_EQ(r()->error(),
1309 "12:34 error: type in vector constructor does not match vector "
1310 "type: expected 'bool', found 'i32'");
1311}
1312
1313TEST_F(ResolverValidationTest,
1314 Expr_Constructor_Vec4_Error_TooFewArgumentsScalar) {
1315 auto* tc = vec4<f32>(
1316 create<ast::ScalarConstructorExpression>(Source{{12, 34}}, Literal(1.0f)),
1317 create<ast::ScalarConstructorExpression>(Source{{12, 40}}, Literal(1.0f)),
1318 create<ast::ScalarConstructorExpression>(Source{{12, 46}},
1319 Literal(1.0f)));
1320 WrapInFunction(tc);
1321
1322 EXPECT_FALSE(r()->Resolve());
1323 EXPECT_EQ(
1324 r()->error(),
1325 "12:34 error: attempted to construct 'vec4<f32>' with 3 component(s)");
1326}
1327
1328TEST_F(ResolverValidationTest,
1329 Expr_Constructor_Vec4_Error_TooManyArgumentsScalar) {
1330 auto* tc = vec4<f32>(
1331 create<ast::ScalarConstructorExpression>(Source{{12, 34}}, Literal(1.0f)),
1332 create<ast::ScalarConstructorExpression>(Source{{12, 40}}, Literal(1.0f)),
1333 create<ast::ScalarConstructorExpression>(Source{{12, 46}}, Literal(1.0f)),
1334 create<ast::ScalarConstructorExpression>(Source{{12, 52}}, Literal(1.0f)),
1335 create<ast::ScalarConstructorExpression>(Source{{12, 58}},
1336 Literal(1.0f)));
1337 WrapInFunction(tc);
1338
1339 EXPECT_FALSE(r()->Resolve());
1340 EXPECT_EQ(
1341 r()->error(),
1342 "12:34 error: attempted to construct 'vec4<f32>' with 5 component(s)");
1343}
1344
1345TEST_F(ResolverValidationTest,
1346 Expr_Constructor_Vec4_Error_TooFewArgumentsVec2AndScalar) {
1347 auto* tc = vec4<f32>(create<ast::TypeConstructorExpression>(
1348 Source{{12, 34}}, ty.vec2<f32>(), ExprList()),
1349 create<ast::ScalarConstructorExpression>(
1350 Source{{12, 40}}, Literal(1.0f)));
1351 WrapInFunction(tc);
1352
1353 EXPECT_FALSE(r()->Resolve());
1354 EXPECT_EQ(
1355 r()->error(),
1356 "12:34 error: attempted to construct 'vec4<f32>' with 3 component(s)");
1357}
1358
1359TEST_F(ResolverValidationTest,
1360 Expr_Constructor_Vec4_Error_TooManyArgumentsVec2AndScalars) {
1361 auto* tc = vec4<f32>(
1362 create<ast::TypeConstructorExpression>(Source{{12, 34}}, ty.vec2<f32>(),
1363 ExprList()),
1364 create<ast::ScalarConstructorExpression>(Source{{12, 40}}, Literal(1.0f)),
1365 create<ast::ScalarConstructorExpression>(Source{{12, 46}}, Literal(1.0f)),
1366 create<ast::ScalarConstructorExpression>(Source{{12, 52}},
1367 Literal(1.0f)));
1368 WrapInFunction(tc);
1369
1370 EXPECT_FALSE(r()->Resolve());
1371 EXPECT_EQ(
1372 r()->error(),
1373 "12:34 error: attempted to construct 'vec4<f32>' with 5 component(s)");
1374}
1375
1376TEST_F(ResolverValidationTest,
1377 Expr_Constructor_Vec4_Error_TooManyArgumentsVec2Vec2Scalar) {
1378 auto* tc = vec4<f32>(create<ast::TypeConstructorExpression>(
1379 Source{{12, 34}}, ty.vec2<f32>(), ExprList()),
1380 create<ast::TypeConstructorExpression>(
1381 Source{{12, 40}}, ty.vec2<f32>(), ExprList()),
1382 create<ast::ScalarConstructorExpression>(
1383 Source{{12, 46}}, Literal(1.0f)));
1384 WrapInFunction(tc);
1385
1386 EXPECT_FALSE(r()->Resolve());
1387 EXPECT_EQ(
1388 r()->error(),
1389 "12:34 error: attempted to construct 'vec4<f32>' with 5 component(s)");
1390}
1391
1392TEST_F(ResolverValidationTest,
1393 Expr_Constructor_Vec4_Error_TooManyArgumentsVec2Vec2Vec2) {
1394 auto* tc = vec4<f32>(create<ast::TypeConstructorExpression>(
1395 Source{{12, 34}}, ty.vec2<f32>(), ExprList()),
1396 create<ast::TypeConstructorExpression>(
1397 Source{{12, 40}}, ty.vec2<f32>(), ExprList()),
1398 create<ast::TypeConstructorExpression>(
1399 Source{{12, 40}}, ty.vec2<f32>(), ExprList()));
1400 WrapInFunction(tc);
1401
1402 EXPECT_FALSE(r()->Resolve());
1403 EXPECT_EQ(
1404 r()->error(),
1405 "12:34 error: attempted to construct 'vec4<f32>' with 6 component(s)");
1406}
1407
1408TEST_F(ResolverValidationTest,
1409 Expr_Constructor_Vec4_Error_TooFewArgumentsVec3) {
1410 auto* tc = vec4<f32>(create<ast::TypeConstructorExpression>(
1411 Source{{12, 34}}, ty.vec3<f32>(), ExprList()));
1412 WrapInFunction(tc);
1413
1414 EXPECT_FALSE(r()->Resolve());
1415 EXPECT_EQ(
1416 r()->error(),
1417 "12:34 error: attempted to construct 'vec4<f32>' with 3 component(s)");
1418}
1419
1420TEST_F(ResolverValidationTest,
1421 Expr_Constructor_Vec4_Error_TooManyArgumentsVec3AndScalars) {
1422 auto* tc = vec4<f32>(
1423 create<ast::TypeConstructorExpression>(Source{{12, 34}}, ty.vec3<f32>(),
1424 ExprList()),
1425 create<ast::ScalarConstructorExpression>(Source{{12, 40}}, Literal(1.0f)),
1426 create<ast::ScalarConstructorExpression>(Source{{12, 46}},
1427 Literal(1.0f)));
1428 WrapInFunction(tc);
1429
1430 EXPECT_FALSE(r()->Resolve());
1431 EXPECT_EQ(
1432 r()->error(),
1433 "12:34 error: attempted to construct 'vec4<f32>' with 5 component(s)");
1434}
1435
1436TEST_F(ResolverValidationTest,
1437 Expr_Constructor_Vec4_Error_TooManyArgumentsVec3AndVec2) {
1438 auto* tc = vec4<f32>(create<ast::TypeConstructorExpression>(
1439 Source{{12, 34}}, ty.vec3<f32>(), ExprList()),
1440 create<ast::TypeConstructorExpression>(
1441 Source{{12, 40}}, ty.vec2<f32>(), ExprList()));
1442 WrapInFunction(tc);
1443
1444 EXPECT_FALSE(r()->Resolve());
1445 EXPECT_EQ(
1446 r()->error(),
1447 "12:34 error: attempted to construct 'vec4<f32>' with 5 component(s)");
1448}
1449
1450TEST_F(ResolverValidationTest,
1451 Expr_Constructor_Vec4_Error_TooManyArgumentsVec2AndVec3) {
1452 auto* tc = vec4<f32>(create<ast::TypeConstructorExpression>(
1453 Source{{12, 34}}, ty.vec2<f32>(), ExprList()),
1454 create<ast::TypeConstructorExpression>(
1455 Source{{12, 40}}, ty.vec3<f32>(), ExprList()));
1456 WrapInFunction(tc);
1457
1458 EXPECT_FALSE(r()->Resolve());
1459 EXPECT_EQ(
1460 r()->error(),
1461 "12:34 error: attempted to construct 'vec4<f32>' with 5 component(s)");
1462}
1463
1464TEST_F(ResolverValidationTest,
1465 Expr_Constructor_Vec4_Error_TooManyArgumentsVec3AndVec3) {
1466 auto* tc = vec4<f32>(create<ast::TypeConstructorExpression>(
1467 Source{{12, 34}}, ty.vec3<f32>(), ExprList()),
1468 create<ast::TypeConstructorExpression>(
1469 Source{{12, 40}}, ty.vec3<f32>(), ExprList()));
1470 WrapInFunction(tc);
1471
1472 EXPECT_FALSE(r()->Resolve());
1473 EXPECT_EQ(
1474 r()->error(),
1475 "12:34 error: attempted to construct 'vec4<f32>' with 6 component(s)");
1476}
1477
1478TEST_F(ResolverValidationTest,
1479 Expr_Constructor_Vec4_Error_InvalidConversionFromVec4Bool) {
1480 auto* tc = vec4<f32>(create<ast::TypeConstructorExpression>(
1481 Source{{12, 34}}, ty.vec4<bool>(), ExprList()));
1482 WrapInFunction(tc);
1483
1484 EXPECT_FALSE(r()->Resolve());
1485 EXPECT_EQ(r()->error(),
1486 "12:34 error: type in vector constructor does not match vector "
1487 "type: expected 'f32', found 'bool'");
1488}
1489
1490TEST_F(ResolverValidationTest,
1491 Expr_Constructor_Vec4_Error_InvalidArgumentType) {
1492 auto* tc = vec4<f32>(create<ast::TypeConstructorExpression>(
1493 Source{{12, 34}}, ty.mat2x2<f32>(), ExprList()));
1494 WrapInFunction(tc);
1495
1496 EXPECT_FALSE(r()->Resolve());
1497 EXPECT_EQ(r()->error(),
1498 "12:34 error: expected vector or scalar type in vector "
1499 "constructor; found: mat2x2<f32>");
1500}
1501
1502TEST_F(ResolverValidationTest, Expr_Constructor_Vec4_Success_ZeroValue) {
1503 auto* tc = vec4<f32>();
1504 WrapInFunction(tc);
1505
1506 EXPECT_TRUE(r()->Resolve()) << r()->error();
1507
1508 ASSERT_NE(TypeOf(tc), nullptr);
Antonio Maiorano3751fd22021-04-19 22:51:23 +00001509 ASSERT_TRUE(TypeOf(tc)->Is<sem::Vector>());
1510 EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::F32>());
1511 EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->size(), 4u);
Arman Uguray3549e2e2021-03-15 21:21:33 +00001512}
1513
1514TEST_F(ResolverValidationTest, Expr_Constructor_Vec4F32_Success_Scalar) {
1515 auto* tc = vec4<f32>(1.0f, 1.0f, 1.0f, 1.0f);
1516 WrapInFunction(tc);
1517
1518 EXPECT_TRUE(r()->Resolve()) << r()->error();
1519
1520 ASSERT_NE(TypeOf(tc), nullptr);
Antonio Maiorano3751fd22021-04-19 22:51:23 +00001521 ASSERT_TRUE(TypeOf(tc)->Is<sem::Vector>());
1522 EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::F32>());
1523 EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->size(), 4u);
Arman Uguray3549e2e2021-03-15 21:21:33 +00001524}
1525
1526TEST_F(ResolverValidationTest, Expr_Constructor_Vec4U32_Success_Scalar) {
1527 auto* tc = vec4<u32>(1u, 1u, 1u, 1u);
1528 WrapInFunction(tc);
1529
1530 EXPECT_TRUE(r()->Resolve()) << r()->error();
1531
1532 ASSERT_NE(TypeOf(tc), nullptr);
Antonio Maiorano3751fd22021-04-19 22:51:23 +00001533 ASSERT_TRUE(TypeOf(tc)->Is<sem::Vector>());
1534 EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::U32>());
1535 EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->size(), 4u);
Arman Uguray3549e2e2021-03-15 21:21:33 +00001536}
1537
1538TEST_F(ResolverValidationTest, Expr_Constructor_Vec4I32_Success_Scalar) {
1539 auto* tc = vec4<i32>(1, 1, 1, 1);
1540 WrapInFunction(tc);
1541
1542 EXPECT_TRUE(r()->Resolve()) << r()->error();
1543
1544 ASSERT_NE(TypeOf(tc), nullptr);
Antonio Maiorano3751fd22021-04-19 22:51:23 +00001545 ASSERT_TRUE(TypeOf(tc)->Is<sem::Vector>());
1546 EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::I32>());
1547 EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->size(), 4u);
Arman Uguray3549e2e2021-03-15 21:21:33 +00001548}
1549
1550TEST_F(ResolverValidationTest, Expr_Constructor_Vec4Bool_Success_Scalar) {
1551 auto* tc = vec4<bool>(true, false, true, false);
1552 WrapInFunction(tc);
1553
1554 EXPECT_TRUE(r()->Resolve()) << r()->error();
1555
1556 ASSERT_NE(TypeOf(tc), nullptr);
Antonio Maiorano3751fd22021-04-19 22:51:23 +00001557 ASSERT_TRUE(TypeOf(tc)->Is<sem::Vector>());
1558 EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::Bool>());
1559 EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->size(), 4u);
Arman Uguray3549e2e2021-03-15 21:21:33 +00001560}
1561
1562TEST_F(ResolverValidationTest, Expr_Constructor_Vec4_Success_Vec2ScalarScalar) {
1563 auto* tc = vec4<f32>(vec2<f32>(), 1.0f, 1.0f);
1564 WrapInFunction(tc);
1565
1566 EXPECT_TRUE(r()->Resolve()) << r()->error();
1567
1568 ASSERT_NE(TypeOf(tc), nullptr);
Antonio Maiorano3751fd22021-04-19 22:51:23 +00001569 ASSERT_TRUE(TypeOf(tc)->Is<sem::Vector>());
1570 EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::F32>());
1571 EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->size(), 4u);
Arman Uguray3549e2e2021-03-15 21:21:33 +00001572}
1573
1574TEST_F(ResolverValidationTest, Expr_Constructor_Vec4_Success_ScalarVec2Scalar) {
1575 auto* tc = vec4<f32>(1.0f, vec2<f32>(), 1.0f);
1576 WrapInFunction(tc);
1577
1578 EXPECT_TRUE(r()->Resolve()) << r()->error();
1579
1580 ASSERT_NE(TypeOf(tc), nullptr);
Antonio Maiorano3751fd22021-04-19 22:51:23 +00001581 ASSERT_TRUE(TypeOf(tc)->Is<sem::Vector>());
1582 EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::F32>());
1583 EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->size(), 4u);
Arman Uguray3549e2e2021-03-15 21:21:33 +00001584}
1585
1586TEST_F(ResolverValidationTest, Expr_Constructor_Vec4_Success_ScalarScalarVec2) {
1587 auto* tc = vec4<f32>(1.0f, 1.0f, vec2<f32>());
1588 WrapInFunction(tc);
1589
1590 EXPECT_TRUE(r()->Resolve()) << r()->error();
1591
1592 ASSERT_NE(TypeOf(tc), nullptr);
Antonio Maiorano3751fd22021-04-19 22:51:23 +00001593 ASSERT_TRUE(TypeOf(tc)->Is<sem::Vector>());
1594 EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::F32>());
1595 EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->size(), 4u);
Arman Uguray3549e2e2021-03-15 21:21:33 +00001596}
1597
1598TEST_F(ResolverValidationTest, Expr_Constructor_Vec4_Success_Vec2AndVec2) {
1599 auto* tc = vec4<f32>(vec2<f32>(), vec2<f32>());
1600 WrapInFunction(tc);
1601
1602 EXPECT_TRUE(r()->Resolve()) << r()->error();
1603
1604 ASSERT_NE(TypeOf(tc), nullptr);
Antonio Maiorano3751fd22021-04-19 22:51:23 +00001605 ASSERT_TRUE(TypeOf(tc)->Is<sem::Vector>());
1606 EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::F32>());
1607 EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->size(), 4u);
Arman Uguray3549e2e2021-03-15 21:21:33 +00001608}
1609
1610TEST_F(ResolverValidationTest, Expr_Constructor_Vec4_Success_Vec3AndScalar) {
1611 auto* tc = vec4<f32>(vec3<f32>(), 1.0f);
1612 WrapInFunction(tc);
1613
1614 EXPECT_TRUE(r()->Resolve()) << r()->error();
1615
1616 ASSERT_NE(TypeOf(tc), nullptr);
Antonio Maiorano3751fd22021-04-19 22:51:23 +00001617 ASSERT_TRUE(TypeOf(tc)->Is<sem::Vector>());
1618 EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::F32>());
1619 EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->size(), 4u);
Arman Uguray3549e2e2021-03-15 21:21:33 +00001620}
1621
1622TEST_F(ResolverValidationTest, Expr_Constructor_Vec4_Success_ScalarAndVec3) {
1623 auto* tc = vec4<f32>(1.0f, vec3<f32>());
1624 WrapInFunction(tc);
1625
1626 EXPECT_TRUE(r()->Resolve()) << r()->error();
1627
1628 ASSERT_NE(TypeOf(tc), nullptr);
Antonio Maiorano3751fd22021-04-19 22:51:23 +00001629 ASSERT_TRUE(TypeOf(tc)->Is<sem::Vector>());
1630 EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::F32>());
1631 EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->size(), 4u);
Arman Uguray3549e2e2021-03-15 21:21:33 +00001632}
1633
1634TEST_F(ResolverValidationTest, Expr_Constructor_Vec4_Success_Identity) {
1635 auto* tc = vec4<f32>(vec4<f32>());
1636 WrapInFunction(tc);
1637
1638 EXPECT_TRUE(r()->Resolve()) << r()->error();
1639
1640 ASSERT_NE(TypeOf(tc), nullptr);
Antonio Maiorano3751fd22021-04-19 22:51:23 +00001641 ASSERT_TRUE(TypeOf(tc)->Is<sem::Vector>());
1642 EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::F32>());
1643 EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->size(), 4u);
Arman Uguray3549e2e2021-03-15 21:21:33 +00001644}
1645
1646TEST_F(ResolverValidationTest,
1647 Expr_Constructor_Vec4_Success_Vec4TypeConversion) {
1648 auto* tc = vec4<f32>(vec4<i32>());
1649 WrapInFunction(tc);
1650
1651 EXPECT_TRUE(r()->Resolve()) << r()->error();
1652
1653 ASSERT_NE(TypeOf(tc), nullptr);
Antonio Maiorano3751fd22021-04-19 22:51:23 +00001654 ASSERT_TRUE(TypeOf(tc)->Is<sem::Vector>());
1655 EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::F32>());
1656 EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->size(), 4u);
Arman Uguray3549e2e2021-03-15 21:21:33 +00001657}
1658
1659TEST_F(ResolverValidationTest,
1660 Expr_Constructor_NestedVectorConstructors_InnerError) {
1661 auto* tc = vec4<f32>(
1662 vec3<f32>(1.0f, vec2<f32>(create<ast::ScalarConstructorExpression>(
1663 Source{{12, 34}}, Literal(1.0f)))),
1664 1.0f);
1665 WrapInFunction(tc);
1666
1667 EXPECT_FALSE(r()->Resolve());
1668 EXPECT_EQ(
1669 r()->error(),
1670 "12:34 error: attempted to construct 'vec2<f32>' with 1 component(s)");
1671}
1672
1673TEST_F(ResolverValidationTest,
1674 Expr_Constructor_NestedVectorConstructors_Success) {
1675 auto* tc = vec4<f32>(vec3<f32>(vec2<f32>(1.0f, 1.0f), 1.0f), 1.0f);
1676 WrapInFunction(tc);
1677
1678 EXPECT_TRUE(r()->Resolve()) << r()->error();
1679
1680 ASSERT_NE(TypeOf(tc), nullptr);
Antonio Maiorano3751fd22021-04-19 22:51:23 +00001681 ASSERT_TRUE(TypeOf(tc)->Is<sem::Vector>());
1682 EXPECT_TRUE(TypeOf(tc)->As<sem::Vector>()->type()->Is<sem::F32>());
1683 EXPECT_EQ(TypeOf(tc)->As<sem::Vector>()->size(), 4u);
Arman Uguray3549e2e2021-03-15 21:21:33 +00001684}
1685
1686TEST_F(ResolverValidationTest, Expr_Constructor_Vector_Alias_Argument_Error) {
Ben Claytone204f272021-04-22 14:40:23 +00001687 auto alias = ty.alias("UnsignedInt", ty.u32());
Antonio Maioranobbbb0ed2021-04-06 20:18:57 +00001688 Global("uint_var", alias, ast::StorageClass::kInput);
Arman Uguray3549e2e2021-03-15 21:21:33 +00001689
1690 auto* tc = vec2<f32>(Expr(Source{{12, 34}}, "uint_var"));
1691 WrapInFunction(tc);
1692
1693 EXPECT_FALSE(r()->Resolve());
1694 EXPECT_EQ(r()->error(),
1695 "12:34 error: type in vector constructor does not match vector "
1696 "type: expected 'f32', found 'u32'");
1697}
1698
1699TEST_F(ResolverValidationTest, Expr_Constructor_Vector_Alias_Argument_Success) {
Ben Claytone204f272021-04-22 14:40:23 +00001700 auto f32_alias = ty.alias("Float32", ty.f32());
1701 auto vec2_alias = ty.alias("VectorFloat2", ty.vec2<f32>());
Antonio Maioranobbbb0ed2021-04-06 20:18:57 +00001702 Global("my_f32", f32_alias, ast::StorageClass::kInput);
1703 Global("my_vec2", vec2_alias, ast::StorageClass::kInput);
Arman Uguray3549e2e2021-03-15 21:21:33 +00001704
1705 auto* tc = vec3<f32>("my_vec2", "my_f32");
1706 WrapInFunction(tc);
1707 EXPECT_TRUE(r()->Resolve()) << r()->error();
1708}
1709
1710TEST_F(ResolverValidationTest, Expr_Constructor_Vector_ElementTypeAlias_Error) {
Ben Claytone204f272021-04-22 14:40:23 +00001711 auto f32_alias = ty.alias("Float32", ty.f32());
Antonio Maiorano3751fd22021-04-19 22:51:23 +00001712 auto* vec_type = create<sem::Vector>(f32_alias, 2);
Arman Uguray3549e2e2021-03-15 21:21:33 +00001713
1714 // vec2<Float32>(1.0f, 1u)
1715 auto* tc = create<ast::TypeConstructorExpression>(
1716 Source{{12, 34}}, vec_type,
1717 ExprList(1.0f, create<ast::ScalarConstructorExpression>(Source{{12, 40}},
1718 Literal(1u))));
1719 WrapInFunction(tc);
1720
1721 EXPECT_FALSE(r()->Resolve());
1722 EXPECT_EQ(r()->error(),
1723 "12:40 error: type in vector constructor does not match vector "
1724 "type: expected 'f32', found 'u32'");
1725}
1726
1727TEST_F(ResolverValidationTest,
1728 Expr_Constructor_Vector_ElementTypeAlias_Success) {
Ben Claytone204f272021-04-22 14:40:23 +00001729 auto f32_alias = ty.alias("Float32", ty.f32());
Antonio Maiorano3751fd22021-04-19 22:51:23 +00001730 auto* vec_type = create<sem::Vector>(f32_alias, 2);
Arman Uguray3549e2e2021-03-15 21:21:33 +00001731
1732 // vec2<Float32>(1.0f, 1.0f)
1733 auto* tc = create<ast::TypeConstructorExpression>(Source{{12, 34}}, vec_type,
1734 ExprList(1.0f, 1.0f));
1735 WrapInFunction(tc);
1736
1737 EXPECT_TRUE(r()->Resolve()) << r()->error();
1738}
1739
1740TEST_F(ResolverValidationTest,
1741 Expr_Constructor_Vector_ArgumentElementTypeAlias_Error) {
Ben Claytone204f272021-04-22 14:40:23 +00001742 auto f32_alias = ty.alias("Float32", ty.f32());
Antonio Maiorano3751fd22021-04-19 22:51:23 +00001743 auto* vec_type = create<sem::Vector>(f32_alias, 2);
Arman Uguray3549e2e2021-03-15 21:21:33 +00001744
1745 // vec3<u32>(vec<Float32>(), 1.0f)
1746 auto* tc = vec3<u32>(create<ast::TypeConstructorExpression>(
1747 Source{{12, 34}}, vec_type, ExprList()),
1748 1.0f);
1749 WrapInFunction(tc);
1750
1751 EXPECT_FALSE(r()->Resolve());
1752 EXPECT_EQ(r()->error(),
1753 "12:34 error: type in vector constructor does not match vector "
1754 "type: expected 'u32', found 'f32'");
1755}
1756
1757TEST_F(ResolverValidationTest,
1758 Expr_Constructor_Vector_ArgumentElementTypeAlias_Success) {
Ben Claytone204f272021-04-22 14:40:23 +00001759 auto f32_alias = ty.alias("Float32", ty.f32());
Antonio Maiorano3751fd22021-04-19 22:51:23 +00001760 auto* vec_type = create<sem::Vector>(f32_alias, 2);
Arman Uguray3549e2e2021-03-15 21:21:33 +00001761
1762 // vec3<f32>(vec<Float32>(), 1.0f)
1763 auto* tc = vec3<f32>(create<ast::TypeConstructorExpression>(
1764 Source{{12, 34}}, vec_type, ExprList()),
1765 1.0f);
1766 WrapInFunction(tc);
1767
1768 EXPECT_TRUE(r()->Resolve()) << r()->error();
1769}
1770
Arman Uguray097c75a2021-03-18 15:43:14 +00001771struct MatrixDimensions {
1772 uint32_t rows;
1773 uint32_t columns;
1774};
1775
1776std::string MatrixStr(const MatrixDimensions& dimensions,
1777 std::string subtype = "f32") {
1778 return "mat" + std::to_string(dimensions.columns) + "x" +
1779 std::to_string(dimensions.rows) + "<" + subtype + ">";
1780}
1781
1782std::string VecStr(uint32_t dimensions, std::string subtype = "f32") {
1783 return "vec" + std::to_string(dimensions) + "<" + subtype + ">";
1784}
1785
1786using MatrixConstructorTest = ResolverTestWithParam<MatrixDimensions>;
1787
1788TEST_P(MatrixConstructorTest, Expr_Constructor_Error_TooFewArguments) {
1789 // matNxM<f32>(vecM<f32>(), ...); with N - 1 arguments
1790
1791 const auto param = GetParam();
Ben Claytone204f272021-04-22 14:40:23 +00001792 auto matrix_type = ty.mat<f32>(param.columns, param.rows);
1793 auto vec_type = ty.vec<f32>(param.rows);
Arman Uguray097c75a2021-03-18 15:43:14 +00001794
1795 ast::ExpressionList args;
1796 for (uint32_t i = 1; i <= param.columns - 1; i++) {
1797 args.push_back(create<ast::TypeConstructorExpression>(
1798 Source{{12, i}}, vec_type, ExprList()));
1799 }
1800
1801 auto* tc = create<ast::TypeConstructorExpression>(Source{}, matrix_type,
1802 std::move(args));
1803 WrapInFunction(tc);
1804
1805 EXPECT_FALSE(r()->Resolve());
1806 EXPECT_EQ(r()->error(),
1807 "12:1 error: expected " + std::to_string(param.columns) + " '" +
1808 VecStr(param.rows) + "' arguments in '" + MatrixStr(param) +
1809 "' constructor, found " + std::to_string(param.columns - 1));
1810}
1811
1812TEST_P(MatrixConstructorTest, Expr_Constructor_Error_TooManyArguments) {
1813 // matNxM<f32>(vecM<f32>(), ...); with N + 1 arguments
1814
1815 const auto param = GetParam();
Ben Claytone204f272021-04-22 14:40:23 +00001816 auto matrix_type = ty.mat<f32>(param.columns, param.rows);
1817 auto vec_type = ty.vec<f32>(param.rows);
Arman Uguray097c75a2021-03-18 15:43:14 +00001818
1819 ast::ExpressionList args;
1820 for (uint32_t i = 1; i <= param.columns + 1; i++) {
1821 args.push_back(create<ast::TypeConstructorExpression>(
1822 Source{{12, i}}, vec_type, ExprList()));
1823 }
1824
1825 auto* tc = create<ast::TypeConstructorExpression>(Source{}, matrix_type,
1826 std::move(args));
1827 WrapInFunction(tc);
1828
1829 EXPECT_FALSE(r()->Resolve());
1830 EXPECT_EQ(r()->error(),
1831 "12:1 error: expected " + std::to_string(param.columns) + " '" +
1832 VecStr(param.rows) + "' arguments in '" + MatrixStr(param) +
1833 "' constructor, found " + std::to_string(param.columns + 1));
1834}
1835
1836TEST_P(MatrixConstructorTest, Expr_Constructor_Error_InvalidArgumentType) {
1837 // matNxM<f32>(1.0, 1.0, ...); N arguments
1838
1839 const auto param = GetParam();
Ben Claytone204f272021-04-22 14:40:23 +00001840 auto matrix_type = ty.mat<f32>(param.columns, param.rows);
Arman Uguray097c75a2021-03-18 15:43:14 +00001841
1842 ast::ExpressionList args;
1843 for (uint32_t i = 1; i <= param.columns; i++) {
1844 args.push_back(create<ast::ScalarConstructorExpression>(Source{{12, i}},
1845 Literal(1.0f)));
1846 }
1847
1848 auto* tc = create<ast::TypeConstructorExpression>(Source{}, matrix_type,
1849 std::move(args));
1850 WrapInFunction(tc);
1851
1852 EXPECT_FALSE(r()->Resolve());
1853 EXPECT_EQ(r()->error(), "12:1 error: expected argument type '" +
1854 VecStr(param.rows) + "' in '" + MatrixStr(param) +
1855 "' constructor, found 'f32'");
1856}
1857
1858TEST_P(MatrixConstructorTest,
1859 Expr_Constructor_Error_TooFewRowsInVectorArgument) {
1860 // matNxM<f32>(vecM<f32>(),...,vecM-1<f32>());
1861
1862 const auto param = GetParam();
1863
1864 // Skip the test if parameters would have resuled in an invalid vec1 type.
1865 if (param.rows == 2) {
1866 return;
1867 }
1868
Ben Claytone204f272021-04-22 14:40:23 +00001869 auto matrix_type = ty.mat<f32>(param.columns, param.rows);
1870 auto valid_vec_type = ty.vec<f32>(param.rows);
1871 auto invalid_vec_type = ty.vec<f32>(param.rows - 1);
Arman Uguray097c75a2021-03-18 15:43:14 +00001872
1873 ast::ExpressionList args;
1874 for (uint32_t i = 1; i <= param.columns - 1; i++) {
1875 args.push_back(create<ast::TypeConstructorExpression>(
1876 Source{{12, i}}, valid_vec_type, ExprList()));
1877 }
1878 const size_t kInvalidLoc = 2 * (param.columns - 1);
1879 args.push_back(create<ast::TypeConstructorExpression>(
1880 Source{{12, kInvalidLoc}}, invalid_vec_type, ExprList()));
1881
1882 auto* tc = create<ast::TypeConstructorExpression>(Source{}, matrix_type,
1883 std::move(args));
1884 WrapInFunction(tc);
1885
1886 EXPECT_FALSE(r()->Resolve());
1887 EXPECT_EQ(r()->error(), "12:" + std::to_string(kInvalidLoc) +
1888 " error: expected argument type '" +
1889 VecStr(param.rows) + "' in '" + MatrixStr(param) +
1890 "' constructor, found '" +
1891 VecStr(param.rows - 1) + "'");
1892}
1893
1894TEST_P(MatrixConstructorTest,
1895 Expr_Constructor_Error_TooManyRowsInVectorArgument) {
1896 // matNxM<f32>(vecM<f32>(),...,vecM+1<f32>());
1897
1898 const auto param = GetParam();
1899
1900 // Skip the test if parameters would have resuled in an invalid vec5 type.
1901 if (param.rows == 4) {
1902 return;
1903 }
1904
Ben Claytone204f272021-04-22 14:40:23 +00001905 auto matrix_type = ty.mat<f32>(param.columns, param.rows);
1906 auto valid_vec_type = ty.vec<f32>(param.rows);
1907 auto invalid_vec_type = ty.vec<f32>(param.rows + 1);
Arman Uguray097c75a2021-03-18 15:43:14 +00001908
1909 ast::ExpressionList args;
1910 for (uint32_t i = 1; i <= param.columns - 1; i++) {
1911 args.push_back(create<ast::TypeConstructorExpression>(
1912 Source{{12, i}}, valid_vec_type, ExprList()));
1913 }
1914 const size_t kInvalidLoc = 2 * (param.columns - 1);
1915 args.push_back(create<ast::TypeConstructorExpression>(
1916 Source{{12, kInvalidLoc}}, invalid_vec_type, ExprList()));
1917
1918 auto* tc = create<ast::TypeConstructorExpression>(Source{}, matrix_type,
1919 std::move(args));
1920 WrapInFunction(tc);
1921
1922 EXPECT_FALSE(r()->Resolve());
1923 EXPECT_EQ(r()->error(), "12:" + std::to_string(kInvalidLoc) +
1924 " error: expected argument type '" +
1925 VecStr(param.rows) + "' in '" + MatrixStr(param) +
1926 "' constructor, found '" +
1927 VecStr(param.rows + 1) + "'");
1928}
1929
1930TEST_P(MatrixConstructorTest,
1931 Expr_Constructor_Error_ArgumentVectorElementTypeMismatch) {
1932 // matNxM<f32>(vecM<u32>(), ...); with N arguments
1933
1934 const auto param = GetParam();
Ben Claytone204f272021-04-22 14:40:23 +00001935 auto matrix_type = ty.mat<f32>(param.columns, param.rows);
Antonio Maiorano3751fd22021-04-19 22:51:23 +00001936 auto* vec_type = create<sem::Vector>(ty.u32(), param.rows);
Arman Uguray097c75a2021-03-18 15:43:14 +00001937
1938 ast::ExpressionList args;
1939 for (uint32_t i = 1; i <= param.columns; i++) {
1940 args.push_back(create<ast::TypeConstructorExpression>(
1941 Source{{12, i}}, vec_type, ExprList()));
1942 }
1943
1944 auto* tc = create<ast::TypeConstructorExpression>(Source{}, matrix_type,
1945 std::move(args));
1946 WrapInFunction(tc);
1947
1948 EXPECT_FALSE(r()->Resolve());
1949 EXPECT_EQ(r()->error(), "12:1 error: expected argument type '" +
1950 VecStr(param.rows) + "' in '" + MatrixStr(param) +
1951 "' constructor, found '" +
1952 VecStr(param.rows, "u32") + "'");
1953}
1954
1955TEST_P(MatrixConstructorTest, Expr_Constructor_ZeroValue_Success) {
1956 // matNxM<f32>();
1957
1958 const auto param = GetParam();
Ben Claytone204f272021-04-22 14:40:23 +00001959 auto matrix_type = ty.mat<f32>(param.columns, param.rows);
Arman Uguray097c75a2021-03-18 15:43:14 +00001960 auto* tc = create<ast::TypeConstructorExpression>(Source{{12, 40}},
1961 matrix_type, ExprList());
1962 WrapInFunction(tc);
1963
1964 EXPECT_TRUE(r()->Resolve()) << r()->error();
1965}
1966
1967TEST_P(MatrixConstructorTest, Expr_Constructor_WithArguments_Success) {
1968 // matNxM<f32>(vecM<f32>(), ...); with N arguments
1969
1970 const auto param = GetParam();
Ben Claytone204f272021-04-22 14:40:23 +00001971 auto matrix_type = ty.mat<f32>(param.columns, param.rows);
1972 auto vec_type = ty.vec<f32>(param.rows);
Arman Uguray097c75a2021-03-18 15:43:14 +00001973
1974 ast::ExpressionList args;
1975 for (uint32_t i = 1; i <= param.columns; i++) {
1976 args.push_back(create<ast::TypeConstructorExpression>(
1977 Source{{12, i}}, vec_type, ExprList()));
1978 }
1979
1980 auto* tc = create<ast::TypeConstructorExpression>(Source{}, matrix_type,
1981 std::move(args));
1982 WrapInFunction(tc);
1983
1984 EXPECT_TRUE(r()->Resolve()) << r()->error();
1985}
1986
1987TEST_P(MatrixConstructorTest, Expr_Constructor_ElementTypeAlias_Error) {
1988 // matNxM<Float32>(vecM<u32>(), ...); with N arguments
1989
1990 const auto param = GetParam();
Ben Claytone204f272021-04-22 14:40:23 +00001991 auto f32_alias = ty.alias("Float32", ty.f32());
1992 auto matrix_type = ty.mat(f32_alias, param.columns, param.rows);
Antonio Maiorano3751fd22021-04-19 22:51:23 +00001993 auto* vec_type = create<sem::Vector>(ty.u32(), param.rows);
Arman Uguray097c75a2021-03-18 15:43:14 +00001994
1995 ast::ExpressionList args;
1996 for (uint32_t i = 1; i <= param.columns; i++) {
1997 args.push_back(create<ast::TypeConstructorExpression>(
1998 Source{{12, i}}, vec_type, ExprList()));
1999 }
2000
2001 auto* tc = create<ast::TypeConstructorExpression>(Source{}, matrix_type,
2002 std::move(args));
2003 WrapInFunction(tc);
2004
2005 EXPECT_FALSE(r()->Resolve());
2006 EXPECT_EQ(r()->error(),
2007 "12:1 error: expected argument type '" + VecStr(param.rows) +
2008 "' in '" + MatrixStr(param, "Float32") +
2009 "' constructor, found '" + VecStr(param.rows, "u32") + "'");
2010}
2011
2012TEST_P(MatrixConstructorTest, Expr_Constructor_ElementTypeAlias_Success) {
2013 // matNxM<Float32>(vecM<f32>(), ...); with N arguments
2014
2015 const auto param = GetParam();
Ben Claytone204f272021-04-22 14:40:23 +00002016 auto f32_alias = ty.alias("Float32", ty.f32());
2017 auto matrix_type = ty.mat(f32_alias, param.columns, param.rows);
2018 auto vec_type = ty.vec<f32>(param.rows);
Arman Uguray097c75a2021-03-18 15:43:14 +00002019
2020 ast::ExpressionList args;
2021 for (uint32_t i = 1; i <= param.columns; i++) {
2022 args.push_back(create<ast::TypeConstructorExpression>(
2023 Source{{12, i}}, vec_type, ExprList()));
2024 }
2025
2026 auto* tc = create<ast::TypeConstructorExpression>(Source{}, matrix_type,
2027 std::move(args));
2028 WrapInFunction(tc);
2029
2030 EXPECT_TRUE(r()->Resolve()) << r()->error();
2031}
2032
2033TEST_F(ResolverValidationTest, Expr_MatrixConstructor_ArgumentTypeAlias_Error) {
Ben Claytone204f272021-04-22 14:40:23 +00002034 auto vec2_alias = ty.alias("VectorUnsigned2", ty.vec2<u32>());
Arman Uguray097c75a2021-03-18 15:43:14 +00002035 auto* tc = mat2x2<f32>(create<ast::TypeConstructorExpression>(
2036 Source{{12, 34}}, vec2_alias, ExprList()),
2037 vec2<f32>());
2038 WrapInFunction(tc);
2039
2040 EXPECT_FALSE(r()->Resolve());
2041 EXPECT_EQ(r()->error(),
2042 "12:34 error: expected argument type 'vec2<f32>' in 'mat2x2<f32>' "
2043 "constructor, found 'vec2<u32>'");
2044}
2045
2046TEST_P(MatrixConstructorTest, Expr_Constructor_ArgumentTypeAlias_Success) {
2047 const auto param = GetParam();
Ben Claytone204f272021-04-22 14:40:23 +00002048 auto matrix_type = ty.mat<f32>(param.columns, param.rows);
2049 auto vec_type = ty.vec<f32>(param.rows);
2050 auto vec_alias = ty.alias("VectorFloat2", vec_type);
Arman Uguray097c75a2021-03-18 15:43:14 +00002051
2052 ast::ExpressionList args;
2053 for (uint32_t i = 1; i <= param.columns; i++) {
2054 args.push_back(create<ast::TypeConstructorExpression>(
2055 Source{{12, i}}, vec_alias, ExprList()));
2056 }
2057
2058 auto* tc = create<ast::TypeConstructorExpression>(Source{}, matrix_type,
2059 std::move(args));
2060 WrapInFunction(tc);
2061
2062 EXPECT_TRUE(r()->Resolve()) << r()->error();
2063}
2064
2065TEST_P(MatrixConstructorTest, Expr_Constructor_ArgumentElementTypeAlias_Error) {
2066 const auto param = GetParam();
Ben Claytone204f272021-04-22 14:40:23 +00002067 auto matrix_type = ty.mat<f32>(param.columns, param.rows);
2068 auto f32_alias = ty.alias("UnsignedInt", ty.u32());
Antonio Maiorano3751fd22021-04-19 22:51:23 +00002069 auto* vec_type = create<sem::Vector>(f32_alias, param.rows);
Arman Uguray097c75a2021-03-18 15:43:14 +00002070
2071 ast::ExpressionList args;
2072 for (uint32_t i = 1; i <= param.columns; i++) {
2073 args.push_back(create<ast::TypeConstructorExpression>(
2074 Source{{12, i}}, vec_type, ExprList()));
2075 }
2076
2077 auto* tc = create<ast::TypeConstructorExpression>(Source{}, matrix_type,
2078 std::move(args));
2079 WrapInFunction(tc);
2080
2081 EXPECT_FALSE(r()->Resolve());
2082 EXPECT_EQ(r()->error(), "12:1 error: expected argument type '" +
2083 VecStr(param.rows) + "' in '" + MatrixStr(param) +
2084 "' constructor, found '" +
2085 VecStr(param.rows, "UnsignedInt") + "'");
2086}
2087
2088TEST_P(MatrixConstructorTest,
2089 Expr_Constructor_ArgumentElementTypeAlias_Success) {
2090 const auto param = GetParam();
Ben Claytone204f272021-04-22 14:40:23 +00002091 auto matrix_type = ty.mat<f32>(param.columns, param.rows);
2092 auto f32_alias = ty.alias("Float32", ty.f32());
Antonio Maiorano3751fd22021-04-19 22:51:23 +00002093 auto* vec_type = create<sem::Vector>(f32_alias, param.rows);
Arman Uguray097c75a2021-03-18 15:43:14 +00002094
2095 ast::ExpressionList args;
2096 for (uint32_t i = 1; i <= param.columns; i++) {
2097 args.push_back(create<ast::TypeConstructorExpression>(
2098 Source{{12, i}}, vec_type, ExprList()));
2099 }
2100
2101 auto* tc = create<ast::TypeConstructorExpression>(Source{}, matrix_type,
2102 std::move(args));
2103 WrapInFunction(tc);
2104
2105 EXPECT_TRUE(r()->Resolve()) << r()->error();
2106}
2107
2108INSTANTIATE_TEST_SUITE_P(ResolverValidationTest,
2109 MatrixConstructorTest,
2110 testing::Values(MatrixDimensions{2, 2},
2111 MatrixDimensions{3, 2},
2112 MatrixDimensions{4, 2},
2113 MatrixDimensions{2, 3},
2114 MatrixDimensions{3, 3},
2115 MatrixDimensions{4, 3},
2116 MatrixDimensions{2, 4},
2117 MatrixDimensions{3, 4},
2118 MatrixDimensions{4, 4}));
2119
Ben Clayton2c41f4f2021-03-09 15:12:57 +00002120} // namespace
2121} // namespace resolver
2122} // namespace tint