Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 1 | // 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 sinclair | 3cbf3fc | 2023-01-21 19:16:15 +0000 | [diff] [blame] | 15 | #include "gmock/gmock.h" |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 16 | #include "src/tint/resolver/resolver.h" |
| 17 | #include "src/tint/resolver/resolver_test_helper.h" |
dan sinclair | 3cbf3fc | 2023-01-21 19:16:15 +0000 | [diff] [blame] | 18 | #include "src/tint/type/texture_dimension.h" |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 19 | |
dan sinclair | d209379 | 2022-04-07 17:45:45 +0000 | [diff] [blame] | 20 | namespace tint::resolver { |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 21 | namespace { |
| 22 | |
Ben Clayton | 138d5b7 | 2023-06-15 08:42:46 +0000 | [diff] [blame] | 23 | using namespace tint::builtin::fluent_types; // NOLINT |
| 24 | using namespace tint::number_suffixes; // NOLINT |
| 25 | |
Ben Clayton | 68ae36e | 2022-06-24 21:26:39 +0000 | [diff] [blame] | 26 | struct ResolverVariableValidationTest : public resolver::TestHelper, public testing::Test {}; |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 27 | |
Ben Clayton | 68ae36e | 2022-06-24 21:26:39 +0000 | [diff] [blame] | 28 | TEST_F(ResolverVariableValidationTest, VarNoInitializerNoType) { |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 29 | // var a; |
Ben Clayton | 58794ae | 2022-08-19 17:28:53 +0000 | [diff] [blame] | 30 | WrapInFunction(Var(Source{{12, 34}}, "a")); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 31 | |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 32 | EXPECT_FALSE(r()->Resolve()); |
Ben Clayton | f903133 | 2022-06-26 11:36:10 +0000 | [diff] [blame] | 33 | EXPECT_EQ(r()->error(), "12:34 error: var declaration requires a type or initializer"); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 34 | } |
| 35 | |
Ben Clayton | 68ae36e | 2022-06-24 21:26:39 +0000 | [diff] [blame] | 36 | TEST_F(ResolverVariableValidationTest, GlobalVarNoInitializerNoType) { |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 37 | // var a; |
Ben Clayton | 58794ae | 2022-08-19 17:28:53 +0000 | [diff] [blame] | 38 | GlobalVar(Source{{12, 34}}, "a"); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 39 | |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 40 | EXPECT_FALSE(r()->Resolve()); |
Ben Clayton | f903133 | 2022-06-26 11:36:10 +0000 | [diff] [blame] | 41 | EXPECT_EQ(r()->error(), "12:34 error: var declaration requires a type or initializer"); |
| 42 | } |
| 43 | |
Zhaoming Jiang | 659d58c | 2022-07-25 12:18:38 +0000 | [diff] [blame] | 44 | TEST_F(ResolverVariableValidationTest, VarInitializerNoReturnValueBuiltin) { |
| 45 | // fn f() { var a = storageBarrier(); } |
| 46 | auto* NoReturnValueBuiltin = Call(Source{{12, 34}}, "storageBarrier"); |
Ben Clayton | 58794ae | 2022-08-19 17:28:53 +0000 | [diff] [blame] | 47 | WrapInFunction(Var("a", NoReturnValueBuiltin)); |
Zhaoming Jiang | 659d58c | 2022-07-25 12:18:38 +0000 | [diff] [blame] | 48 | |
| 49 | EXPECT_FALSE(r()->Resolve()); |
| 50 | EXPECT_EQ(r()->error(), "12:34 error: builtin 'storageBarrier' does not return a value"); |
| 51 | } |
| 52 | |
| 53 | TEST_F(ResolverVariableValidationTest, GlobalVarInitializerNoReturnValueBuiltin) { |
| 54 | // var a = storageBarrier(); |
| 55 | auto* NoReturnValueBuiltin = Call(Source{{12, 34}}, "storageBarrier"); |
Ben Clayton | 58794ae | 2022-08-19 17:28:53 +0000 | [diff] [blame] | 56 | GlobalVar("a", NoReturnValueBuiltin); |
Zhaoming Jiang | 659d58c | 2022-07-25 12:18:38 +0000 | [diff] [blame] | 57 | |
| 58 | EXPECT_FALSE(r()->Resolve()); |
| 59 | EXPECT_EQ(r()->error(), "12:34 error: builtin 'storageBarrier' does not return a value"); |
| 60 | } |
| 61 | |
Ben Clayton | cd097f4 | 2023-03-10 13:10:52 +0000 | [diff] [blame] | 62 | TEST_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 | |
| 72 | TEST_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 Clayton | f903133 | 2022-06-26 11:36:10 +0000 | [diff] [blame] | 82 | TEST_F(ResolverVariableValidationTest, GlobalVarUsedAtModuleScope) { |
| 83 | // var<private> a : i32; |
| 84 | // var<private> b : i32 = a; |
dan sinclair | 2a65163 | 2023-02-19 04:03:55 +0000 | [diff] [blame] | 85 | GlobalVar(Source{{12, 34}}, "a", ty.i32(), builtin::AddressSpace::kPrivate); |
| 86 | GlobalVar("b", ty.i32(), builtin::AddressSpace::kPrivate, Expr(Source{{56, 78}}, "a")); |
Ben Clayton | f903133 | 2022-06-26 11:36:10 +0000 | [diff] [blame] | 87 | |
| 88 | EXPECT_FALSE(r()->Resolve()); |
dan sinclair | 1662f55 | 2022-09-21 14:44:33 +0000 | [diff] [blame] | 89 | EXPECT_EQ(r()->error(), R"(56:78 error: var 'a' cannot be referenced at module-scope |
Ben Clayton | f903133 | 2022-06-26 11:36:10 +0000 | [diff] [blame] | 90 | 12:34 note: var 'a' declared here)"); |
Ben Clayton | ee49b1e | 2022-06-20 15:30:41 +0000 | [diff] [blame] | 91 | } |
| 92 | |
Ben Clayton | 68ae36e | 2022-06-24 21:26:39 +0000 | [diff] [blame] | 93 | TEST_F(ResolverVariableValidationTest, OverrideNoInitializerNoType) { |
Ben Clayton | ee49b1e | 2022-06-20 15:30:41 +0000 | [diff] [blame] | 94 | // override a; |
Ben Clayton | 58794ae | 2022-08-19 17:28:53 +0000 | [diff] [blame] | 95 | Override(Source{{12, 34}}, "a"); |
Ben Clayton | ee49b1e | 2022-06-20 15:30:41 +0000 | [diff] [blame] | 96 | |
| 97 | EXPECT_FALSE(r()->Resolve()); |
Ben Clayton | f903133 | 2022-06-26 11:36:10 +0000 | [diff] [blame] | 98 | EXPECT_EQ(r()->error(), "12:34 error: override declaration requires a type or initializer"); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 99 | } |
| 100 | |
Ben Clayton | 9a6acc4 | 2022-07-27 20:50:40 +0000 | [diff] [blame] | 101 | TEST_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 Clayton | 58794ae | 2022-08-19 17:28:53 +0000 | [diff] [blame] | 108 | Override("o" + std::to_string(i), ty.i32()); |
Ben Clayton | 9a6acc4 | 2022-07-27 20:50:40 +0000 | [diff] [blame] | 109 | } |
Ben Clayton | 58794ae | 2022-08-19 17:28:53 +0000 | [diff] [blame] | 110 | Override(Source{{12, 34}}, "bang", ty.i32()); |
Ben Clayton | 9a6acc4 | 2022-07-27 20:50:40 +0000 | [diff] [blame] | 111 | |
| 112 | EXPECT_FALSE(r()->Resolve()); |
| 113 | EXPECT_EQ(r()->error(), "12:34 error: number of 'override' variables exceeded limit of 65535"); |
| 114 | } |
| 115 | |
| 116 | TEST_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 sinclair | 5361d9e | 2022-08-31 13:39:48 +0000 | [diff] [blame] | 122 | Override("reserved", ty.i32(), Id(AInt(kLimit))); |
Ben Clayton | 9a6acc4 | 2022-07-27 20:50:40 +0000 | [diff] [blame] | 123 | for (size_t i = 0; i < kLimit; i++) { |
Ben Clayton | 58794ae | 2022-08-19 17:28:53 +0000 | [diff] [blame] | 124 | Override("o" + std::to_string(i), ty.i32()); |
Ben Clayton | 9a6acc4 | 2022-07-27 20:50:40 +0000 | [diff] [blame] | 125 | } |
Ben Clayton | 58794ae | 2022-08-19 17:28:53 +0000 | [diff] [blame] | 126 | Override(Source{{12, 34}}, "bang", ty.i32()); |
Ben Clayton | 9a6acc4 | 2022-07-27 20:50:40 +0000 | [diff] [blame] | 127 | |
| 128 | EXPECT_FALSE(r()->Resolve()); |
| 129 | EXPECT_EQ(r()->error(), "12:34 error: number of 'override' variables exceeded limit of 65535"); |
| 130 | } |
| 131 | |
Ben Clayton | cfe07a1 | 2022-07-15 13:01:49 +0000 | [diff] [blame] | 132 | TEST_F(ResolverVariableValidationTest, VarTypeNotConstructible) { |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 133 | // var i : i32; |
| 134 | // var p : pointer<function, i32> = &v; |
Ben Clayton | 58794ae | 2022-08-19 17:28:53 +0000 | [diff] [blame] | 135 | auto* i = Var("i", ty.i32()); |
Ben Clayton | 66805b0 | 2023-06-14 22:00:01 +0000 | [diff] [blame] | 136 | auto* p = Var("a", ty.ptr<function, i32>(Source{{56, 78}}), builtin::AddressSpace::kUndefined, |
| 137 | AddressOf(Source{{12, 34}}, "i")); |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 138 | WrapInFunction(i, p); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 139 | |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 140 | EXPECT_FALSE(r()->Resolve()); |
Ben Clayton | cfe07a1 | 2022-07-15 13:01:49 +0000 | [diff] [blame] | 141 | EXPECT_EQ(r()->error(), "56:78 error: function-scope 'var' must have a constructible type"); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 142 | } |
| 143 | |
Ben Clayton | 68ae36e | 2022-06-24 21:26:39 +0000 | [diff] [blame] | 144 | TEST_F(ResolverVariableValidationTest, LetTypeNotConstructible) { |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 145 | // @group(0) @binding(0) var t1 : texture_2d<f32>; |
| 146 | // let t2 : t1; |
dan sinclair | 3cbf3fc | 2023-01-21 19:16:15 +0000 | [diff] [blame] | 147 | auto* t1 = GlobalVar("t1", ty.sampled_texture(type::TextureDimension::k2d, ty.f32()), |
| 148 | Group(0_a), Binding(0_a)); |
Ben Clayton | 58794ae | 2022-08-19 17:28:53 +0000 | [diff] [blame] | 149 | auto* t2 = Let(Source{{56, 78}}, "t2", Expr(t1)); |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 150 | WrapInFunction(t2); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 151 | |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 152 | EXPECT_FALSE(r()->Resolve()); |
Ben Clayton | ee49b1e | 2022-06-20 15:30:41 +0000 | [diff] [blame] | 153 | EXPECT_EQ(r()->error(), "56:78 error: texture_2d<f32> cannot be used as the type of a 'let'"); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 154 | } |
| 155 | |
Ben Clayton | 68ae36e | 2022-06-24 21:26:39 +0000 | [diff] [blame] | 156 | TEST_F(ResolverVariableValidationTest, OverrideExplicitTypeNotScalar) { |
Ben Clayton | e4e4854 | 2022-06-20 19:17:52 +0000 | [diff] [blame] | 157 | // override o : vec3<f32>; |
Ben Clayton | 58794ae | 2022-08-19 17:28:53 +0000 | [diff] [blame] | 158 | Override(Source{{56, 78}}, "o", ty.vec3<f32>()); |
Ben Clayton | e4e4854 | 2022-06-20 19:17:52 +0000 | [diff] [blame] | 159 | |
| 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 Clayton | 68ae36e | 2022-06-24 21:26:39 +0000 | [diff] [blame] | 164 | TEST_F(ResolverVariableValidationTest, OverrideInferedTypeNotScalar) { |
Ben Clayton | e4e4854 | 2022-06-20 19:17:52 +0000 | [diff] [blame] | 165 | // override o = vec3(1.0f); |
Ben Clayton | 66805b0 | 2023-06-14 22:00:01 +0000 | [diff] [blame] | 166 | Override(Source{{56, 78}}, "o", Call<vec3<f32>>(1.0_f)); |
Ben Clayton | e4e4854 | 2022-06-20 19:17:52 +0000 | [diff] [blame] | 167 | |
| 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 sinclair | 6e77b47 | 2022-10-20 13:38:28 +0000 | [diff] [blame] | 172 | TEST_F(ResolverVariableValidationTest, ConstInitializerWrongType) { |
Ben Clayton | e3834c4 | 2022-06-25 23:21:39 +0000 | [diff] [blame] | 173 | // 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 sinclair | 6e77b47 | 2022-10-20 13:38:28 +0000 | [diff] [blame] | 181 | TEST_F(ResolverVariableValidationTest, LetInitializerWrongType) { |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 182 | // var v : i32 = 2u |
Ben Clayton | 0ce9ab0 | 2022-05-05 20:23:40 +0000 | [diff] [blame] | 183 | WrapInFunction(Let(Source{{3, 3}}, "v", ty.i32(), Expr(2_u))); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 184 | |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 185 | 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 Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 188 | } |
| 189 | |
dan sinclair | 6e77b47 | 2022-10-20 13:38:28 +0000 | [diff] [blame] | 190 | TEST_F(ResolverVariableValidationTest, VarInitializerWrongType) { |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 191 | // var v : i32 = 2u |
Ben Clayton | 58794ae | 2022-08-19 17:28:53 +0000 | [diff] [blame] | 192 | WrapInFunction(Var(Source{{3, 3}}, "v", ty.i32(), Expr(2_u))); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 193 | |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 194 | 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 Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 197 | } |
| 198 | |
dan sinclair | 6e77b47 | 2022-10-20 13:38:28 +0000 | [diff] [blame] | 199 | TEST_F(ResolverVariableValidationTest, ConstInitializerWrongTypeViaAlias) { |
Ben Clayton | e3834c4 | 2022-06-25 23:21:39 +0000 | [diff] [blame] | 200 | 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 sinclair | 6e77b47 | 2022-10-20 13:38:28 +0000 | [diff] [blame] | 208 | TEST_F(ResolverVariableValidationTest, LetInitializerWrongTypeViaAlias) { |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 209 | auto* a = Alias("I32", ty.i32()); |
Ben Clayton | 0ce9ab0 | 2022-05-05 20:23:40 +0000 | [diff] [blame] | 210 | WrapInFunction(Let(Source{{3, 3}}, "v", ty.Of(a), Expr(2_u))); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 211 | |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 212 | 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 Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 215 | } |
| 216 | |
dan sinclair | 6e77b47 | 2022-10-20 13:38:28 +0000 | [diff] [blame] | 217 | TEST_F(ResolverVariableValidationTest, VarInitializerWrongTypeViaAlias) { |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 218 | auto* a = Alias("I32", ty.i32()); |
Ben Clayton | 58794ae | 2022-08-19 17:28:53 +0000 | [diff] [blame] | 219 | WrapInFunction(Var(Source{{3, 3}}, "v", ty.Of(a), Expr(2_u))); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 220 | |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 221 | 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 Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 224 | } |
| 225 | |
Ben Clayton | 68ae36e | 2022-06-24 21:26:39 +0000 | [diff] [blame] | 226 | TEST_F(ResolverVariableValidationTest, LetOfPtrConstructedWithRef) { |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 227 | // var a : f32; |
| 228 | // let b : ptr<function,f32> = a; |
dan sinclair | 2a65163 | 2023-02-19 04:03:55 +0000 | [diff] [blame] | 229 | const auto priv = builtin::AddressSpace::kFunction; |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 230 | auto* var_a = Var("a", ty.f32(), priv); |
Ben Clayton | 1a8a19d | 2023-06-13 17:01:16 +0000 | [diff] [blame] | 231 | auto* var_b = Let(Source{{12, 34}}, "b", ty.ptr<f32>(priv), Expr("a")); |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 232 | WrapInFunction(var_a, var_b); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 233 | |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 234 | ASSERT_FALSE(r()->Resolve()); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 235 | |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 236 | 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 Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 239 | } |
| 240 | |
Ben Clayton | 68ae36e | 2022-06-24 21:26:39 +0000 | [diff] [blame] | 241 | TEST_F(ResolverVariableValidationTest, LocalLetRedeclared) { |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 242 | // let l : f32 = 1.; |
| 243 | // let l : i32 = 0; |
Ben Clayton | 0a3cda9 | 2022-05-10 17:30:15 +0000 | [diff] [blame] | 244 | auto* l1 = Let("l", ty.f32(), Expr(1_f)); |
Ben Clayton | 0ce9ab0 | 2022-05-05 20:23:40 +0000 | [diff] [blame] | 245 | auto* l2 = Let(Source{{12, 34}}, "l", ty.i32(), Expr(0_i)); |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 246 | WrapInFunction(l1, l2); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 247 | |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 248 | EXPECT_FALSE(r()->Resolve()); |
| 249 | EXPECT_EQ(r()->error(), |
| 250 | "12:34 error: redeclaration of 'l'\nnote: 'l' previously declared here"); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 251 | } |
| 252 | |
Ben Clayton | 68ae36e | 2022-06-24 21:26:39 +0000 | [diff] [blame] | 253 | TEST_F(ResolverVariableValidationTest, GlobalVarRedeclaredAsLocal) { |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 254 | // var v : f32 = 2.1; |
| 255 | // fn my_func() { |
| 256 | // var v : f32 = 2.0; |
| 257 | // return 0; |
| 258 | // } |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 259 | |
dan sinclair | 2a65163 | 2023-02-19 04:03:55 +0000 | [diff] [blame] | 260 | GlobalVar("v", ty.f32(), builtin::AddressSpace::kPrivate, Expr(2.1_f)); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 261 | |
Ben Clayton | 58794ae | 2022-08-19 17:28:53 +0000 | [diff] [blame] | 262 | WrapInFunction(Var(Source{{12, 34}}, "v", ty.f32(), Expr(2_f))); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 263 | |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 264 | EXPECT_TRUE(r()->Resolve()) << r()->error(); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 265 | } |
| 266 | |
Ben Clayton | 68ae36e | 2022-06-24 21:26:39 +0000 | [diff] [blame] | 267 | TEST_F(ResolverVariableValidationTest, VarRedeclaredInInnerBlock) { |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 268 | // { |
| 269 | // var v : f32; |
| 270 | // { var v : f32; } |
| 271 | // } |
Ben Clayton | 58794ae | 2022-08-19 17:28:53 +0000 | [diff] [blame] | 272 | auto* var_outer = Var("v", ty.f32()); |
| 273 | auto* var_inner = Var(Source{{12, 34}}, "v", ty.f32()); |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 274 | auto* inner = Block(Decl(var_inner)); |
| 275 | auto* outer_body = Block(Decl(var_outer), inner); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 276 | |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 277 | WrapInFunction(outer_body); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 278 | |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 279 | EXPECT_TRUE(r()->Resolve()) << r()->error(); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 280 | } |
| 281 | |
Ben Clayton | 68ae36e | 2022-06-24 21:26:39 +0000 | [diff] [blame] | 282 | TEST_F(ResolverVariableValidationTest, VarRedeclaredInIfBlock) { |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 283 | // { |
| 284 | // var v : f32 = 3.14; |
| 285 | // if (true) { var v : f32 = 2.0; } |
| 286 | // } |
Ben Clayton | 58794ae | 2022-08-19 17:28:53 +0000 | [diff] [blame] | 287 | auto* var_a_float = Var("v", ty.f32(), Expr(3.1_f)); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 288 | |
Ben Clayton | 58794ae | 2022-08-19 17:28:53 +0000 | [diff] [blame] | 289 | auto* var = Var(Source{{12, 34}}, "v", ty.f32(), Expr(2_f)); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 290 | |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 291 | auto* cond = Expr(true); |
| 292 | auto* body = Block(Decl(var)); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 293 | |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 294 | auto* outer_body = Block(Decl(var_a_float), If(cond, body)); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 295 | |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 296 | WrapInFunction(outer_body); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 297 | |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 298 | EXPECT_TRUE(r()->Resolve()) << r()->error(); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 299 | } |
| 300 | |
Ben Clayton | 68ae36e | 2022-06-24 21:26:39 +0000 | [diff] [blame] | 301 | TEST_F(ResolverVariableValidationTest, InferredPtrStorageAccessMismatch) { |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 302 | // 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 Clayton | 0ce9ab0 | 2022-05-05 20:23:40 +0000 | [diff] [blame] | 310 | // let p : pointer<storage, i32, read_write> = &s.inner.arr[2i]; |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 311 | // } |
Ben Clayton | 783b169 | 2022-08-02 17:03:35 +0000 | [diff] [blame] | 312 | 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 Clayton | 66805b0 | 2023-06-14 22:00:01 +0000 | [diff] [blame] | 318 | auto* var = |
dan sinclair | 2a65163 | 2023-02-19 04:03:55 +0000 | [diff] [blame] | 319 | GlobalVar("s", ty.Of(buf), builtin::AddressSpace::kStorage, Binding(0_a), Group(0_a)); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 320 | |
Ben Clayton | 66805b0 | 2023-06-14 22:00:01 +0000 | [diff] [blame] | 321 | 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 Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 323 | |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 324 | WrapInFunction(ptr); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 325 | |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 326 | 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 Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 331 | } |
| 332 | |
Ben Clayton | 68ae36e | 2022-06-24 21:26:39 +0000 | [diff] [blame] | 333 | TEST_F(ResolverVariableValidationTest, NonConstructibleType_Atomic) { |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 334 | auto* v = Var("v", ty.atomic(Source{{12, 34}}, ty.i32())); |
| 335 | WrapInFunction(v); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 336 | |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 337 | EXPECT_FALSE(r()->Resolve()); |
Ben Clayton | ee49b1e | 2022-06-20 15:30:41 +0000 | [diff] [blame] | 338 | EXPECT_EQ(r()->error(), "12:34 error: function-scope 'var' must have a constructible type"); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 339 | } |
| 340 | |
Ben Clayton | 68ae36e | 2022-06-24 21:26:39 +0000 | [diff] [blame] | 341 | TEST_F(ResolverVariableValidationTest, NonConstructibleType_RuntimeArray) { |
Ben Clayton | 783b169 | 2022-08-02 17:03:35 +0000 | [diff] [blame] | 342 | auto* s = Structure("S", utils::Vector{ |
Ben Clayton | d205b71 | 2022-11-30 01:13:35 +0000 | [diff] [blame] | 343 | Member(Source{{12, 34}}, "m", ty.array<i32>()), |
Ben Clayton | 783b169 | 2022-08-02 17:03:35 +0000 | [diff] [blame] | 344 | }); |
Ben Clayton | d205b71 | 2022-11-30 01:13:35 +0000 | [diff] [blame] | 345 | auto* v = Var(Source{{56, 78}}, "v", ty.Of(s)); |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 346 | WrapInFunction(v); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 347 | |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 348 | EXPECT_FALSE(r()->Resolve()); |
| 349 | EXPECT_EQ(r()->error(), |
Ben Clayton | d205b71 | 2022-11-30 01:13:35 +0000 | [diff] [blame] | 350 | R"(error: runtime-sized arrays can only be used in the <storage> address space |
| 351 | 12:34 note: while analyzing structure member S.m |
| 352 | 56:78 note: while instantiating 'var' v)"); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 353 | } |
| 354 | |
Ben Clayton | 68ae36e | 2022-06-24 21:26:39 +0000 | [diff] [blame] | 355 | TEST_F(ResolverVariableValidationTest, NonConstructibleType_Struct_WithAtomic) { |
Ben Clayton | 783b169 | 2022-08-02 17:03:35 +0000 | [diff] [blame] | 356 | auto* s = Structure("S", utils::Vector{ |
| 357 | Member("m", ty.atomic(ty.i32())), |
| 358 | }); |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 359 | auto* v = Var("v", ty.Of(s)); |
| 360 | WrapInFunction(v); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 361 | |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 362 | EXPECT_FALSE(r()->Resolve()); |
Ben Clayton | ee49b1e | 2022-06-20 15:30:41 +0000 | [diff] [blame] | 363 | EXPECT_EQ(r()->error(), "error: function-scope 'var' must have a constructible type"); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 364 | } |
| 365 | |
Ben Clayton | 68ae36e | 2022-06-24 21:26:39 +0000 | [diff] [blame] | 366 | TEST_F(ResolverVariableValidationTest, NonConstructibleType_InferredType) { |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 367 | // @group(0) @binding(0) var s : sampler; |
| 368 | // fn foo() { |
| 369 | // var v = s; |
| 370 | // } |
dan sinclair | 3085e23 | 2023-01-23 16:24:12 +0000 | [diff] [blame] | 371 | GlobalVar("s", ty.sampler(type::SamplerKind::kSampler), Group(0_a), Binding(0_a)); |
Ben Clayton | 58794ae | 2022-08-19 17:28:53 +0000 | [diff] [blame] | 372 | auto* v = Var(Source{{12, 34}}, "v", Expr("s")); |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 373 | WrapInFunction(v); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 374 | |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 375 | EXPECT_FALSE(r()->Resolve()); |
Ben Clayton | ee49b1e | 2022-06-20 15:30:41 +0000 | [diff] [blame] | 376 | EXPECT_EQ(r()->error(), "12:34 error: function-scope 'var' must have a constructible type"); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 377 | } |
| 378 | |
dan sinclair | ff7cf21 | 2022-10-03 14:05:23 +0000 | [diff] [blame] | 379 | TEST_F(ResolverVariableValidationTest, InvalidAddressSpaceForInitializer) { |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 380 | // var<workgroup> v : f32 = 1.23; |
dan sinclair | 2a65163 | 2023-02-19 04:03:55 +0000 | [diff] [blame] | 381 | GlobalVar(Source{{12, 34}}, "v", ty.f32(), builtin::AddressSpace::kWorkgroup, Expr(1.23_f)); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 382 | |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 383 | EXPECT_FALSE(r()->Resolve()); |
| 384 | EXPECT_EQ(r()->error(), |
dan sinclair | ff7cf21 | 2022-10-03 14:05:23 +0000 | [diff] [blame] | 385 | "12:34 error: var of address space 'workgroup' cannot have " |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 386 | "an initializer. var initializers are only supported for the " |
Ben Clayton | d205b71 | 2022-11-30 01:13:35 +0000 | [diff] [blame] | 387 | "address spaces 'private' and 'function'"); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 388 | } |
| 389 | |
Ben Clayton | e3834c4 | 2022-06-25 23:21:39 +0000 | [diff] [blame] | 390 | TEST_F(ResolverVariableValidationTest, VectorConstNoType) { |
Ben Clayton | 971318f | 2023-02-14 13:52:43 +0000 | [diff] [blame] | 391 | // const a vec3 = vec3<f32>(); |
Ben Clayton | 66805b0 | 2023-06-14 22:00:01 +0000 | [diff] [blame] | 392 | WrapInFunction(Const("a", ty.vec3<Infer>(Source{{12, 34}}), Call<vec3<f32>>())); |
Ben Clayton | e3834c4 | 2022-06-25 23:21:39 +0000 | [diff] [blame] | 393 | |
| 394 | EXPECT_FALSE(r()->Resolve()); |
Ben Clayton | 971318f | 2023-02-14 13:52:43 +0000 | [diff] [blame] | 395 | EXPECT_EQ(r()->error(), "12:34 error: expected '<' for 'vec3'"); |
Ben Clayton | e3834c4 | 2022-06-25 23:21:39 +0000 | [diff] [blame] | 396 | } |
| 397 | |
Ben Clayton | 68ae36e | 2022-06-24 21:26:39 +0000 | [diff] [blame] | 398 | TEST_F(ResolverVariableValidationTest, VectorLetNoType) { |
Ben Clayton | 971318f | 2023-02-14 13:52:43 +0000 | [diff] [blame] | 399 | // let a : vec3 = vec3<f32>(); |
Ben Clayton | 66805b0 | 2023-06-14 22:00:01 +0000 | [diff] [blame] | 400 | WrapInFunction(Let("a", ty.vec3<Infer>(Source{{12, 34}}), Call<vec3<f32>>())); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 401 | |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 402 | EXPECT_FALSE(r()->Resolve()); |
Ben Clayton | 971318f | 2023-02-14 13:52:43 +0000 | [diff] [blame] | 403 | EXPECT_EQ(r()->error(), "12:34 error: expected '<' for 'vec3'"); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 404 | } |
| 405 | |
Ben Clayton | 68ae36e | 2022-06-24 21:26:39 +0000 | [diff] [blame] | 406 | TEST_F(ResolverVariableValidationTest, VectorVarNoType) { |
Ben Clayton | 971318f | 2023-02-14 13:52:43 +0000 | [diff] [blame] | 407 | // var a : vec3; |
| 408 | WrapInFunction(Var("a", ty.vec3<Infer>(Source{{12, 34}}))); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 409 | |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 410 | EXPECT_FALSE(r()->Resolve()); |
Ben Clayton | 971318f | 2023-02-14 13:52:43 +0000 | [diff] [blame] | 411 | EXPECT_EQ(r()->error(), "12:34 error: expected '<' for 'vec3'"); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 412 | } |
| 413 | |
Ben Clayton | e3834c4 | 2022-06-25 23:21:39 +0000 | [diff] [blame] | 414 | TEST_F(ResolverVariableValidationTest, MatrixConstNoType) { |
| 415 | // const a : mat3x3 = mat3x3<f32>(); |
Ben Clayton | 66805b0 | 2023-06-14 22:00:01 +0000 | [diff] [blame] | 416 | WrapInFunction(Const("a", ty.mat3x3<Infer>(Source{{12, 34}}), Call<mat3x3<f32>>())); |
Ben Clayton | e3834c4 | 2022-06-25 23:21:39 +0000 | [diff] [blame] | 417 | |
| 418 | EXPECT_FALSE(r()->Resolve()); |
Ben Clayton | 971318f | 2023-02-14 13:52:43 +0000 | [diff] [blame] | 419 | EXPECT_EQ(r()->error(), "12:34 error: expected '<' for 'mat3x3'"); |
Ben Clayton | e3834c4 | 2022-06-25 23:21:39 +0000 | [diff] [blame] | 420 | } |
| 421 | |
Ben Clayton | 68ae36e | 2022-06-24 21:26:39 +0000 | [diff] [blame] | 422 | TEST_F(ResolverVariableValidationTest, MatrixLetNoType) { |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 423 | // let a : mat3x3 = mat3x3<f32>(); |
Ben Clayton | 66805b0 | 2023-06-14 22:00:01 +0000 | [diff] [blame] | 424 | WrapInFunction(Let("a", ty.mat3x3<Infer>(Source{{12, 34}}), Call<mat3x3<f32>>())); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 425 | |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 426 | EXPECT_FALSE(r()->Resolve()); |
Ben Clayton | 971318f | 2023-02-14 13:52:43 +0000 | [diff] [blame] | 427 | EXPECT_EQ(r()->error(), "12:34 error: expected '<' for 'mat3x3'"); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 428 | } |
| 429 | |
Ben Clayton | 68ae36e | 2022-06-24 21:26:39 +0000 | [diff] [blame] | 430 | TEST_F(ResolverVariableValidationTest, MatrixVarNoType) { |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 431 | // var a : mat3x3; |
Ben Clayton | 971318f | 2023-02-14 13:52:43 +0000 | [diff] [blame] | 432 | WrapInFunction(Var("a", ty.mat3x3<Infer>(Source{{12, 34}}))); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 433 | |
dan sinclair | 41e4d9a | 2022-05-01 14:40:55 +0000 | [diff] [blame] | 434 | EXPECT_FALSE(r()->Resolve()); |
Ben Clayton | 971318f | 2023-02-14 13:52:43 +0000 | [diff] [blame] | 435 | EXPECT_EQ(r()->error(), "12:34 error: expected '<' for 'mat3x3'"); |
Ryan Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 436 | } |
| 437 | |
Ben Clayton | 9535f72 | 2022-11-02 18:14:59 +0000 | [diff] [blame] | 438 | TEST_F(ResolverVariableValidationTest, GlobalConstWithRuntimeExpression) { |
| 439 | GlobalConst("c", Call(Source{{12, 34}}, "dpdx", 1._a)); |
Ben Clayton | e3834c4 | 2022-06-25 23:21:39 +0000 | [diff] [blame] | 440 | |
| 441 | EXPECT_FALSE(r()->Resolve()); |
Ben Clayton | c84d06e | 2022-10-13 17:23:06 +0000 | [diff] [blame] | 442 | EXPECT_EQ( |
| 443 | r()->error(), |
| 444 | R"(12:34 error: const initializer requires a const-expression, but expression is a runtime-expression)"); |
Ben Clayton | e3834c4 | 2022-06-25 23:21:39 +0000 | [diff] [blame] | 445 | } |
| 446 | |
Ben Clayton | 9535f72 | 2022-11-02 18:14:59 +0000 | [diff] [blame] | 447 | TEST_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 |
| 456 | 56:78 note: consider changing 'const' to 'let')"); |
| 457 | } |
| 458 | |
Ben Clayton | e3834c4 | 2022-06-25 23:21:39 +0000 | [diff] [blame] | 459 | TEST_F(ResolverVariableValidationTest, ConstInitWithOverride) { |
Ben Clayton | 58794ae | 2022-08-19 17:28:53 +0000 | [diff] [blame] | 460 | auto* o = Override("v", Expr(1_i)); |
| 461 | auto* c = Const("c", Expr(Source{{12, 34}}, o)); |
Ben Clayton | 9535f72 | 2022-11-02 18:14:59 +0000 | [diff] [blame] | 462 | WrapInFunction(Decl(Source{{56, 78}}, c)); |
Ben Clayton | e3834c4 | 2022-06-25 23:21:39 +0000 | [diff] [blame] | 463 | |
| 464 | EXPECT_FALSE(r()->Resolve()); |
Ben Clayton | c84d06e | 2022-10-13 17:23:06 +0000 | [diff] [blame] | 465 | EXPECT_EQ( |
| 466 | r()->error(), |
Ben Clayton | 9535f72 | 2022-11-02 18:14:59 +0000 | [diff] [blame] | 467 | R"(12:34 error: const initializer requires a const-expression, but expression is an override-expression |
| 468 | 56:78 note: consider changing 'const' to 'let')"); |
Ben Clayton | e3834c4 | 2022-06-25 23:21:39 +0000 | [diff] [blame] | 469 | } |
| 470 | |
| 471 | TEST_F(ResolverVariableValidationTest, ConstInitWithLet) { |
Ben Clayton | 58794ae | 2022-08-19 17:28:53 +0000 | [diff] [blame] | 472 | auto* l = Let("v", Expr(1_i)); |
| 473 | auto* c = Const("c", Expr(Source{{12, 34}}, l)); |
Ben Clayton | 9535f72 | 2022-11-02 18:14:59 +0000 | [diff] [blame] | 474 | WrapInFunction(l, Decl(Source{{56, 78}}, c)); |
Ben Clayton | e3834c4 | 2022-06-25 23:21:39 +0000 | [diff] [blame] | 475 | |
| 476 | EXPECT_FALSE(r()->Resolve()); |
Ben Clayton | c84d06e | 2022-10-13 17:23:06 +0000 | [diff] [blame] | 477 | EXPECT_EQ( |
| 478 | r()->error(), |
Ben Clayton | 9535f72 | 2022-11-02 18:14:59 +0000 | [diff] [blame] | 479 | R"(12:34 error: const initializer requires a const-expression, but expression is a runtime-expression |
| 480 | 56:78 note: consider changing 'const' to 'let')"); |
Ben Clayton | c84d06e | 2022-10-13 17:23:06 +0000 | [diff] [blame] | 481 | } |
| 482 | |
| 483 | TEST_F(ResolverVariableValidationTest, ConstInitWithRuntimeExpr) { |
| 484 | // const c = clamp(2, dpdx(0.5), 3); |
Ben Clayton | 9535f72 | 2022-11-02 18:14:59 +0000 | [diff] [blame] | 485 | 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 Clayton | c84d06e | 2022-10-13 17:23:06 +0000 | [diff] [blame] | 487 | |
| 488 | EXPECT_FALSE(r()->Resolve()); |
| 489 | EXPECT_EQ( |
| 490 | r()->error(), |
Ben Clayton | 9535f72 | 2022-11-02 18:14:59 +0000 | [diff] [blame] | 491 | R"(12:34 error: const initializer requires a const-expression, but expression is a runtime-expression |
| 492 | 56:78 note: consider changing 'const' to 'let')"); |
Ben Clayton | c84d06e | 2022-10-13 17:23:06 +0000 | [diff] [blame] | 493 | } |
| 494 | |
| 495 | TEST_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 Clayton | 9535f72 | 2022-11-02 18:14:59 +0000 | [diff] [blame] | 498 | WrapInFunction(Decl(Source{{56, 78}}, c)); |
Ben Clayton | c84d06e | 2022-10-13 17:23:06 +0000 | [diff] [blame] | 499 | |
| 500 | EXPECT_FALSE(r()->Resolve()); |
| 501 | EXPECT_EQ( |
| 502 | r()->error(), |
Ben Clayton | 9535f72 | 2022-11-02 18:14:59 +0000 | [diff] [blame] | 503 | R"(12:34 error: const initializer requires a const-expression, but expression is an override-expression |
| 504 | 56:78 note: consider changing 'const' to 'let')"); |
Ben Clayton | e3834c4 | 2022-06-25 23:21:39 +0000 | [diff] [blame] | 505 | } |
| 506 | |
Ben Clayton | d205b71 | 2022-11-30 01:13:35 +0000 | [diff] [blame] | 507 | TEST_F(ResolverVariableValidationTest, GlobalVariable_PushConstantWithInitializer) { |
| 508 | // enable chromium_experimental_push_constant; |
| 509 | // var<push_constant> a : u32 = 0u; |
dan sinclair | e4039c7 | 2023-02-17 21:58:59 +0000 | [diff] [blame] | 510 | Enable(builtin::Extension::kChromiumExperimentalPushConstant); |
dan sinclair | 2a65163 | 2023-02-19 04:03:55 +0000 | [diff] [blame] | 511 | GlobalVar(Source{{1u, 2u}}, "a", ty.u32(), builtin::AddressSpace::kPushConstant, |
Ben Clayton | d205b71 | 2022-11-30 01:13:35 +0000 | [diff] [blame] | 512 | 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 Harrison | dbc13af | 2022-02-21 15:19:07 +0000 | [diff] [blame] | 520 | } // namespace |
dan sinclair | d209379 | 2022-04-07 17:45:45 +0000 | [diff] [blame] | 521 | } // namespace tint::resolver |