tint: Rename 'static_assert' to 'const_assert'

Bug: tint:1807
Change-Id: I2c2a205ada01ad14d0bf6620a3dc3ec84dd7ee67
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/117212
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Dan Sinclair <dsinclair@chromium.org>
Commit-Queue: Ben Clayton <bclayton@google.com>
This commit is contained in:
Ben Clayton 2023-01-24 14:59:43 +00:00 committed by Dawn LUCI CQ
parent 9dc48bcef3
commit c98d57d662
38 changed files with 565 additions and 302 deletions

View File

@ -20,7 +20,7 @@ This round-trip ability provides a few features:
The IR helps with the complexity of the AST transforms by limiting the The IR helps with the complexity of the AST transforms by limiting the
representations seen in the IR form. For example, instead of `for`, representations seen in the IR form. For example, instead of `for`,
`while` and `loop` constructs there is a single `loop` construct. `while` and `loop` constructs there is a single `loop` construct.
`alias` and `static_assert` nodes are not emitted into IR. Dead code is `alias` and `const_assert` nodes are not emitted into IR. Dead code is
eliminated during the IR construction. eliminated during the IR construction.
As the IR can convert into AST, we could potentially simplify the As the IR can convert into AST, we could potentially simplify the
@ -48,7 +48,7 @@ greatly simplifies the number of things to consider in the IR. For
instance: instance:
* No `alias` nodes * No `alias` nodes
* No `static_assert` nodes * No `const_assert` nodes
* All loops become `while` loops * All loops become `while` loops
* `if` statements may all become `if/else` * `if` statements may all become `if/else`

View File

@ -5,6 +5,7 @@
## Deprecated Features ## Deprecated Features
* The keyword to alias a type has been renamed from `type` to `alias`. [tint:1812](crbug.com/tint/1812) * The keyword to alias a type has been renamed from `type` to `alias`. [tint:1812](crbug.com/tint/1812)
* `static_assert` has been renamed to `const_assert`. [tint:1807](crbug.com/tint/1807)
## Changes for M110 ## Changes for M110

View File

@ -224,6 +224,8 @@ libtint_source_set("libtint_core_all_src") {
"ast/compound_assignment_statement.h", "ast/compound_assignment_statement.h",
"ast/const.cc", "ast/const.cc",
"ast/const.h", "ast/const.h",
"ast/const_assert.cc",
"ast/const_assert.h",
"ast/continue_statement.cc", "ast/continue_statement.cc",
"ast/continue_statement.h", "ast/continue_statement.h",
"ast/depth_multisampled_texture.cc", "ast/depth_multisampled_texture.cc",
@ -315,8 +317,6 @@ libtint_source_set("libtint_core_all_src") {
"ast/stage_attribute.h", "ast/stage_attribute.h",
"ast/statement.cc", "ast/statement.cc",
"ast/statement.h", "ast/statement.h",
"ast/static_assert.cc",
"ast/static_assert.h",
"ast/storage_texture.cc", "ast/storage_texture.cc",
"ast/storage_texture.h", "ast/storage_texture.h",
"ast/stride_attribute.cc", "ast/stride_attribute.cc",
@ -1179,6 +1179,7 @@ if (tint_build_unittests) {
"ast/case_selector_test.cc", "ast/case_selector_test.cc",
"ast/case_statement_test.cc", "ast/case_statement_test.cc",
"ast/compound_assignment_statement_test.cc", "ast/compound_assignment_statement_test.cc",
"ast/const_assert_test.cc",
"ast/continue_statement_test.cc", "ast/continue_statement_test.cc",
"ast/diagnostic_control_test.cc", "ast/diagnostic_control_test.cc",
"ast/discard_statement_test.cc", "ast/discard_statement_test.cc",
@ -1213,7 +1214,6 @@ if (tint_build_unittests) {
"ast/sampled_texture_test.cc", "ast/sampled_texture_test.cc",
"ast/sampler_test.cc", "ast/sampler_test.cc",
"ast/stage_attribute_test.cc", "ast/stage_attribute_test.cc",
"ast/static_assert_test.cc",
"ast/storage_texture_test.cc", "ast/storage_texture_test.cc",
"ast/stride_attribute_test.cc", "ast/stride_attribute_test.cc",
"ast/struct_member_align_attribute_test.cc", "ast/struct_member_align_attribute_test.cc",
@ -1272,6 +1272,7 @@ if (tint_build_unittests) {
"resolver/call_validation_test.cc", "resolver/call_validation_test.cc",
"resolver/compound_assignment_validation_test.cc", "resolver/compound_assignment_validation_test.cc",
"resolver/compound_statement_test.cc", "resolver/compound_statement_test.cc",
"resolver/const_assert_test.cc",
"resolver/const_eval_binary_op_test.cc", "resolver/const_eval_binary_op_test.cc",
"resolver/const_eval_bitcast_test.cc", "resolver/const_eval_bitcast_test.cc",
"resolver/const_eval_builtin_test.cc", "resolver/const_eval_builtin_test.cc",
@ -1304,7 +1305,6 @@ if (tint_build_unittests) {
"resolver/resolver_test_helper.h", "resolver/resolver_test_helper.h",
"resolver/root_identifier_test.cc", "resolver/root_identifier_test.cc",
"resolver/side_effects_test.cc", "resolver/side_effects_test.cc",
"resolver/static_assert_test.cc",
"resolver/struct_address_space_use_test.cc", "resolver/struct_address_space_use_test.cc",
"resolver/struct_layout_test.cc", "resolver/struct_layout_test.cc",
"resolver/struct_pipeline_stage_use_test.cc", "resolver/struct_pipeline_stage_use_test.cc",
@ -1526,6 +1526,7 @@ if (tint_build_unittests) {
"writer/spirv/builder_builtin_test.cc", "writer/spirv/builder_builtin_test.cc",
"writer/spirv/builder_builtin_texture_test.cc", "writer/spirv/builder_builtin_texture_test.cc",
"writer/spirv/builder_call_test.cc", "writer/spirv/builder_call_test.cc",
"writer/spirv/builder_const_assert_test.cc",
"writer/spirv/builder_discard_test.cc", "writer/spirv/builder_discard_test.cc",
"writer/spirv/builder_entry_point_test.cc", "writer/spirv/builder_entry_point_test.cc",
"writer/spirv/builder_format_conversion_test.cc", "writer/spirv/builder_format_conversion_test.cc",
@ -1539,7 +1540,6 @@ if (tint_build_unittests) {
"writer/spirv/builder_literal_test.cc", "writer/spirv/builder_literal_test.cc",
"writer/spirv/builder_loop_test.cc", "writer/spirv/builder_loop_test.cc",
"writer/spirv/builder_return_test.cc", "writer/spirv/builder_return_test.cc",
"writer/spirv/builder_static_assert_test.cc",
"writer/spirv/builder_switch_test.cc", "writer/spirv/builder_switch_test.cc",
"writer/spirv/builder_test.cc", "writer/spirv/builder_test.cc",
"writer/spirv/builder_type_test.cc", "writer/spirv/builder_type_test.cc",
@ -1654,6 +1654,7 @@ if (tint_build_unittests) {
"writer/wgsl/generator_impl_call_test.cc", "writer/wgsl/generator_impl_call_test.cc",
"writer/wgsl/generator_impl_case_test.cc", "writer/wgsl/generator_impl_case_test.cc",
"writer/wgsl/generator_impl_cast_test.cc", "writer/wgsl/generator_impl_cast_test.cc",
"writer/wgsl/generator_impl_const_assert_test.cc",
"writer/wgsl/generator_impl_continue_test.cc", "writer/wgsl/generator_impl_continue_test.cc",
"writer/wgsl/generator_impl_discard_test.cc", "writer/wgsl/generator_impl_discard_test.cc",
"writer/wgsl/generator_impl_enable_test.cc", "writer/wgsl/generator_impl_enable_test.cc",
@ -1666,7 +1667,6 @@ if (tint_build_unittests) {
"writer/wgsl/generator_impl_loop_test.cc", "writer/wgsl/generator_impl_loop_test.cc",
"writer/wgsl/generator_impl_member_accessor_test.cc", "writer/wgsl/generator_impl_member_accessor_test.cc",
"writer/wgsl/generator_impl_return_test.cc", "writer/wgsl/generator_impl_return_test.cc",
"writer/wgsl/generator_impl_static_assert_test.cc",
"writer/wgsl/generator_impl_switch_test.cc", "writer/wgsl/generator_impl_switch_test.cc",
"writer/wgsl/generator_impl_test.cc", "writer/wgsl/generator_impl_test.cc",
"writer/wgsl/generator_impl_type_test.cc", "writer/wgsl/generator_impl_type_test.cc",
@ -1695,6 +1695,7 @@ if (tint_build_unittests) {
"writer/msl/generator_impl_call_test.cc", "writer/msl/generator_impl_call_test.cc",
"writer/msl/generator_impl_case_test.cc", "writer/msl/generator_impl_case_test.cc",
"writer/msl/generator_impl_cast_test.cc", "writer/msl/generator_impl_cast_test.cc",
"writer/msl/generator_impl_const_assert_test.cc",
"writer/msl/generator_impl_continue_test.cc", "writer/msl/generator_impl_continue_test.cc",
"writer/msl/generator_impl_discard_test.cc", "writer/msl/generator_impl_discard_test.cc",
"writer/msl/generator_impl_function_test.cc", "writer/msl/generator_impl_function_test.cc",
@ -1707,7 +1708,6 @@ if (tint_build_unittests) {
"writer/msl/generator_impl_module_constant_test.cc", "writer/msl/generator_impl_module_constant_test.cc",
"writer/msl/generator_impl_return_test.cc", "writer/msl/generator_impl_return_test.cc",
"writer/msl/generator_impl_sanitizer_test.cc", "writer/msl/generator_impl_sanitizer_test.cc",
"writer/msl/generator_impl_static_assert_test.cc",
"writer/msl/generator_impl_switch_test.cc", "writer/msl/generator_impl_switch_test.cc",
"writer/msl/generator_impl_test.cc", "writer/msl/generator_impl_test.cc",
"writer/msl/generator_impl_type_test.cc", "writer/msl/generator_impl_type_test.cc",
@ -1735,6 +1735,7 @@ if (tint_build_unittests) {
"writer/hlsl/generator_impl_call_test.cc", "writer/hlsl/generator_impl_call_test.cc",
"writer/hlsl/generator_impl_case_test.cc", "writer/hlsl/generator_impl_case_test.cc",
"writer/hlsl/generator_impl_cast_test.cc", "writer/hlsl/generator_impl_cast_test.cc",
"writer/hlsl/generator_impl_const_assert_test.cc",
"writer/hlsl/generator_impl_continue_test.cc", "writer/hlsl/generator_impl_continue_test.cc",
"writer/hlsl/generator_impl_discard_test.cc", "writer/hlsl/generator_impl_discard_test.cc",
"writer/hlsl/generator_impl_function_test.cc", "writer/hlsl/generator_impl_function_test.cc",
@ -1747,7 +1748,6 @@ if (tint_build_unittests) {
"writer/hlsl/generator_impl_module_constant_test.cc", "writer/hlsl/generator_impl_module_constant_test.cc",
"writer/hlsl/generator_impl_return_test.cc", "writer/hlsl/generator_impl_return_test.cc",
"writer/hlsl/generator_impl_sanitizer_test.cc", "writer/hlsl/generator_impl_sanitizer_test.cc",
"writer/hlsl/generator_impl_static_assert_test.cc",
"writer/hlsl/generator_impl_switch_test.cc", "writer/hlsl/generator_impl_switch_test.cc",
"writer/hlsl/generator_impl_test.cc", "writer/hlsl/generator_impl_test.cc",
"writer/hlsl/generator_impl_type_test.cc", "writer/hlsl/generator_impl_type_test.cc",

View File

@ -119,6 +119,8 @@ list(APPEND TINT_LIB_SRCS
ast/compound_assignment_statement.h ast/compound_assignment_statement.h
ast/const.cc ast/const.cc
ast/const.h ast/const.h
ast/const_assert.cc
ast/const_assert.h
ast/continue_statement.cc ast/continue_statement.cc
ast/continue_statement.h ast/continue_statement.h
ast/depth_multisampled_texture.cc ast/depth_multisampled_texture.cc
@ -206,8 +208,6 @@ list(APPEND TINT_LIB_SRCS
ast/stage_attribute.h ast/stage_attribute.h
ast/statement.cc ast/statement.cc
ast/statement.h ast/statement.h
ast/static_assert.cc
ast/static_assert.h
ast/storage_texture.cc ast/storage_texture.cc
ast/storage_texture.h ast/storage_texture.h
ast/stride_attribute.cc ast/stride_attribute.cc
@ -829,6 +829,7 @@ if(TINT_BUILD_TESTS)
ast/case_selector_test.cc ast/case_selector_test.cc
ast/case_statement_test.cc ast/case_statement_test.cc
ast/compound_assignment_statement_test.cc ast/compound_assignment_statement_test.cc
ast/const_assert_test.cc
ast/continue_statement_test.cc ast/continue_statement_test.cc
ast/depth_multisampled_texture_test.cc ast/depth_multisampled_texture_test.cc
ast/depth_texture_test.cc ast/depth_texture_test.cc
@ -863,7 +864,6 @@ if(TINT_BUILD_TESTS)
ast/sampled_texture_test.cc ast/sampled_texture_test.cc
ast/sampler_test.cc ast/sampler_test.cc
ast/stage_attribute_test.cc ast/stage_attribute_test.cc
ast/static_assert_test.cc
ast/storage_texture_test.cc ast/storage_texture_test.cc
ast/stride_attribute_test.cc ast/stride_attribute_test.cc
ast/struct_member_align_attribute_test.cc ast/struct_member_align_attribute_test.cc
@ -910,6 +910,7 @@ if(TINT_BUILD_TESTS)
resolver/call_validation_test.cc resolver/call_validation_test.cc
resolver/compound_assignment_validation_test.cc resolver/compound_assignment_validation_test.cc
resolver/compound_statement_test.cc resolver/compound_statement_test.cc
resolver/const_assert_test.cc
resolver/const_eval_binary_op_test.cc resolver/const_eval_binary_op_test.cc
resolver/const_eval_bitcast_test.cc resolver/const_eval_bitcast_test.cc
resolver/const_eval_builtin_test.cc resolver/const_eval_builtin_test.cc
@ -941,7 +942,6 @@ if(TINT_BUILD_TESTS)
resolver/resolver_test_helper.h resolver/resolver_test_helper.h
resolver/resolver_test.cc resolver/resolver_test.cc
resolver/side_effects_test.cc resolver/side_effects_test.cc
resolver/static_assert_test.cc
resolver/root_identifier_test.cc resolver/root_identifier_test.cc
resolver/address_space_layout_validation_test.cc resolver/address_space_layout_validation_test.cc
resolver/address_space_validation_test.cc resolver/address_space_validation_test.cc
@ -1164,7 +1164,7 @@ if(TINT_BUILD_TESTS)
writer/spirv/builder_builtin_test.cc writer/spirv/builder_builtin_test.cc
writer/spirv/builder_builtin_texture_test.cc writer/spirv/builder_builtin_texture_test.cc
writer/spirv/builder_call_test.cc writer/spirv/builder_call_test.cc
writer/spirv/builder_initializer_expression_test.cc writer/spirv/builder_const_assert_test.cc
writer/spirv/builder_discard_test.cc writer/spirv/builder_discard_test.cc
writer/spirv/builder_entry_point_test.cc writer/spirv/builder_entry_point_test.cc
writer/spirv/builder_format_conversion_test.cc writer/spirv/builder_format_conversion_test.cc
@ -1174,10 +1174,10 @@ if(TINT_BUILD_TESTS)
writer/spirv/builder_global_variable_test.cc writer/spirv/builder_global_variable_test.cc
writer/spirv/builder_ident_expression_test.cc writer/spirv/builder_ident_expression_test.cc
writer/spirv/builder_if_test.cc writer/spirv/builder_if_test.cc
writer/spirv/builder_initializer_expression_test.cc
writer/spirv/builder_literal_test.cc writer/spirv/builder_literal_test.cc
writer/spirv/builder_loop_test.cc writer/spirv/builder_loop_test.cc
writer/spirv/builder_return_test.cc writer/spirv/builder_return_test.cc
writer/spirv/builder_static_assert_test.cc
writer/spirv/builder_switch_test.cc writer/spirv/builder_switch_test.cc
writer/spirv/builder_test.cc writer/spirv/builder_test.cc
writer/spirv/builder_type_test.cc writer/spirv/builder_type_test.cc
@ -1204,7 +1204,7 @@ if(TINT_BUILD_TESTS)
writer/wgsl/generator_impl_call_test.cc writer/wgsl/generator_impl_call_test.cc
writer/wgsl/generator_impl_case_test.cc writer/wgsl/generator_impl_case_test.cc
writer/wgsl/generator_impl_cast_test.cc writer/wgsl/generator_impl_cast_test.cc
writer/wgsl/generator_impl_initializer_test.cc writer/wgsl/generator_impl_const_assert_test.cc
writer/wgsl/generator_impl_continue_test.cc writer/wgsl/generator_impl_continue_test.cc
writer/wgsl/generator_impl_discard_test.cc writer/wgsl/generator_impl_discard_test.cc
writer/wgsl/generator_impl_enable_test.cc writer/wgsl/generator_impl_enable_test.cc
@ -1212,11 +1212,11 @@ if(TINT_BUILD_TESTS)
writer/wgsl/generator_impl_global_decl_test.cc writer/wgsl/generator_impl_global_decl_test.cc
writer/wgsl/generator_impl_identifier_test.cc writer/wgsl/generator_impl_identifier_test.cc
writer/wgsl/generator_impl_if_test.cc writer/wgsl/generator_impl_if_test.cc
writer/wgsl/generator_impl_initializer_test.cc
writer/wgsl/generator_impl_loop_test.cc writer/wgsl/generator_impl_loop_test.cc
writer/wgsl/generator_impl_literal_test.cc writer/wgsl/generator_impl_literal_test.cc
writer/wgsl/generator_impl_member_accessor_test.cc writer/wgsl/generator_impl_member_accessor_test.cc
writer/wgsl/generator_impl_return_test.cc writer/wgsl/generator_impl_return_test.cc
writer/wgsl/generator_impl_static_assert_test.cc
writer/wgsl/generator_impl_switch_test.cc writer/wgsl/generator_impl_switch_test.cc
writer/wgsl/generator_impl_type_test.cc writer/wgsl/generator_impl_type_test.cc
writer/wgsl/generator_impl_unary_op_test.cc writer/wgsl/generator_impl_unary_op_test.cc
@ -1298,19 +1298,19 @@ if(TINT_BUILD_TESTS)
writer/msl/generator_impl_call_test.cc writer/msl/generator_impl_call_test.cc
writer/msl/generator_impl_case_test.cc writer/msl/generator_impl_case_test.cc
writer/msl/generator_impl_cast_test.cc writer/msl/generator_impl_cast_test.cc
writer/msl/generator_impl_initializer_test.cc writer/msl/generator_impl_const_assert_test.cc
writer/msl/generator_impl_continue_test.cc writer/msl/generator_impl_continue_test.cc
writer/msl/generator_impl_discard_test.cc writer/msl/generator_impl_discard_test.cc
writer/msl/generator_impl_function_test.cc writer/msl/generator_impl_function_test.cc
writer/msl/generator_impl_identifier_test.cc writer/msl/generator_impl_identifier_test.cc
writer/msl/generator_impl_if_test.cc writer/msl/generator_impl_if_test.cc
writer/msl/generator_impl_initializer_test.cc
writer/msl/generator_impl_import_test.cc writer/msl/generator_impl_import_test.cc
writer/msl/generator_impl_loop_test.cc writer/msl/generator_impl_loop_test.cc
writer/msl/generator_impl_member_accessor_test.cc writer/msl/generator_impl_member_accessor_test.cc
writer/msl/generator_impl_module_constant_test.cc writer/msl/generator_impl_module_constant_test.cc
writer/msl/generator_impl_return_test.cc writer/msl/generator_impl_return_test.cc
writer/msl/generator_impl_sanitizer_test.cc writer/msl/generator_impl_sanitizer_test.cc
writer/msl/generator_impl_static_assert_test.cc
writer/msl/generator_impl_switch_test.cc writer/msl/generator_impl_switch_test.cc
writer/msl/generator_impl_test.cc writer/msl/generator_impl_test.cc
writer/msl/generator_impl_type_test.cc writer/msl/generator_impl_type_test.cc
@ -1370,19 +1370,19 @@ if(TINT_BUILD_TESTS)
writer/hlsl/generator_impl_call_test.cc writer/hlsl/generator_impl_call_test.cc
writer/hlsl/generator_impl_case_test.cc writer/hlsl/generator_impl_case_test.cc
writer/hlsl/generator_impl_cast_test.cc writer/hlsl/generator_impl_cast_test.cc
writer/hlsl/generator_impl_initializer_test.cc writer/hlsl/generator_impl_const_assert_test.cc
writer/hlsl/generator_impl_continue_test.cc writer/hlsl/generator_impl_continue_test.cc
writer/hlsl/generator_impl_discard_test.cc writer/hlsl/generator_impl_discard_test.cc
writer/hlsl/generator_impl_function_test.cc writer/hlsl/generator_impl_function_test.cc
writer/hlsl/generator_impl_identifier_test.cc writer/hlsl/generator_impl_identifier_test.cc
writer/hlsl/generator_impl_if_test.cc writer/hlsl/generator_impl_if_test.cc
writer/hlsl/generator_impl_initializer_test.cc
writer/hlsl/generator_impl_import_test.cc writer/hlsl/generator_impl_import_test.cc
writer/hlsl/generator_impl_loop_test.cc writer/hlsl/generator_impl_loop_test.cc
writer/hlsl/generator_impl_member_accessor_test.cc writer/hlsl/generator_impl_member_accessor_test.cc
writer/hlsl/generator_impl_module_constant_test.cc writer/hlsl/generator_impl_module_constant_test.cc
writer/hlsl/generator_impl_return_test.cc writer/hlsl/generator_impl_return_test.cc
writer/hlsl/generator_impl_sanitizer_test.cc writer/hlsl/generator_impl_sanitizer_test.cc
writer/hlsl/generator_impl_static_assert_test.cc
writer/hlsl/generator_impl_switch_test.cc writer/hlsl/generator_impl_switch_test.cc
writer/hlsl/generator_impl_test.cc writer/hlsl/generator_impl_test.cc
writer/hlsl/generator_impl_type_test.cc writer/hlsl/generator_impl_type_test.cc

View File

@ -12,29 +12,29 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "src/tint/ast/static_assert.h" #include "src/tint/ast/const_assert.h"
#include "src/tint/program_builder.h" #include "src/tint/program_builder.h"
TINT_INSTANTIATE_TYPEINFO(tint::ast::StaticAssert); TINT_INSTANTIATE_TYPEINFO(tint::ast::ConstAssert);
namespace tint::ast { namespace tint::ast {
StaticAssert::StaticAssert(ProgramID pid, NodeID nid, const Source& src, const Expression* cond) ConstAssert::ConstAssert(ProgramID pid, NodeID nid, const Source& src, const Expression* cond)
: Base(pid, nid, src), condition(cond) { : Base(pid, nid, src), condition(cond) {
TINT_ASSERT(AST, cond); TINT_ASSERT(AST, cond);
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, cond, program_id); TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, cond, program_id);
} }
StaticAssert::StaticAssert(StaticAssert&&) = default; ConstAssert::ConstAssert(ConstAssert&&) = default;
StaticAssert::~StaticAssert() = default; ConstAssert::~ConstAssert() = default;
const StaticAssert* StaticAssert::Clone(CloneContext* ctx) const { const ConstAssert* ConstAssert::Clone(CloneContext* ctx) const {
// Clone arguments outside of create() call to have deterministic ordering // Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source); auto src = ctx->Clone(source);
auto* cond = ctx->Clone(condition); auto* cond = ctx->Clone(condition);
return ctx->dst->create<StaticAssert>(src, cond); return ctx->dst->create<ConstAssert>(src, cond);
} }
} // namespace tint::ast } // namespace tint::ast

View File

@ -12,34 +12,34 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#ifndef SRC_TINT_AST_STATIC_ASSERT_H_ #ifndef SRC_TINT_AST_CONST_ASSERT_H_
#define SRC_TINT_AST_STATIC_ASSERT_H_ #define SRC_TINT_AST_CONST_ASSERT_H_
#include "src/tint/ast/statement.h" #include "src/tint/ast/statement.h"
#include "src/tint/ast/variable.h" #include "src/tint/ast/variable.h"
namespace tint::ast { namespace tint::ast {
/// A `static_assert` statement /// A `const_assert` statement
class StaticAssert final : public Castable<StaticAssert, Statement> { class ConstAssert final : public Castable<ConstAssert, Statement> {
public: public:
/// Constructor /// Constructor
/// @param pid the identifier of the program that owns this node /// @param pid the identifier of the program that owns this node
/// @param nid the unique node identifier /// @param nid the unique node identifier
/// @param source the variable statement source /// @param source the variable statement source
/// @param condition the assertion condition /// @param condition the assertion condition
StaticAssert(ProgramID pid, NodeID nid, const Source& source, const Expression* condition); ConstAssert(ProgramID pid, NodeID nid, const Source& source, const Expression* condition);
/// Move constructor /// Move constructor
StaticAssert(StaticAssert&&); ConstAssert(ConstAssert&&);
/// Destructor /// Destructor
~StaticAssert() override; ~ConstAssert() override;
/// Clones this node and all transitive child nodes using the `CloneContext` `ctx`. /// Clones this node and all transitive child nodes using the `CloneContext` `ctx`.
/// @param ctx the clone context /// @param ctx the clone context
/// @return the newly cloned node /// @return the newly cloned node
const StaticAssert* Clone(CloneContext* ctx) const override; const ConstAssert* Clone(CloneContext* ctx) const override;
/// The assertion condition /// The assertion condition
const Expression* const condition; const Expression* const condition;
@ -47,4 +47,4 @@ class StaticAssert final : public Castable<StaticAssert, Statement> {
} // namespace tint::ast } // namespace tint::ast
#endif // SRC_TINT_AST_STATIC_ASSERT_H_ #endif // SRC_TINT_AST_CONST_ASSERT_H_

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "src/tint/ast/static_assert.h" #include "src/tint/ast/const_assert.h"
#include "gtest/gtest-spi.h" #include "gtest/gtest-spi.h"
#include "src/tint/ast/test_helper.h" #include "src/tint/ast/test_helper.h"
@ -20,44 +20,44 @@
namespace tint::ast { namespace tint::ast {
namespace { namespace {
using StaticAssertTest = TestHelper; using ConstAssertTest = TestHelper;
TEST_F(StaticAssertTest, Creation) { TEST_F(ConstAssertTest, Creation) {
auto* cond = Expr(true); auto* cond = Expr(true);
auto* stmt = StaticAssert(cond); auto* stmt = ConstAssert(cond);
EXPECT_EQ(stmt->condition, cond); EXPECT_EQ(stmt->condition, cond);
} }
TEST_F(StaticAssertTest, Creation_WithSource) { TEST_F(ConstAssertTest, Creation_WithSource) {
auto* cond = Expr(true); auto* cond = Expr(true);
auto* stmt = StaticAssert(Source{{20, 2}}, cond); auto* stmt = ConstAssert(Source{{20, 2}}, cond);
auto src = stmt->source; auto src = stmt->source;
EXPECT_EQ(src.range.begin.line, 20u); EXPECT_EQ(src.range.begin.line, 20u);
EXPECT_EQ(src.range.begin.column, 2u); EXPECT_EQ(src.range.begin.column, 2u);
} }
TEST_F(StaticAssertTest, IsStaticAssert) { TEST_F(ConstAssertTest, IsConstAssert) {
auto* cond = Expr(true); auto* cond = Expr(true);
auto* stmt = StaticAssert(cond); auto* stmt = ConstAssert(cond);
EXPECT_TRUE(stmt->Is<ast::StaticAssert>()); EXPECT_TRUE(stmt->Is<ast::ConstAssert>());
} }
TEST_F(StaticAssertTest, Assert_Null_Condition) { TEST_F(ConstAssertTest, Assert_Null_Condition) {
EXPECT_FATAL_FAILURE( EXPECT_FATAL_FAILURE(
{ {
ProgramBuilder b; ProgramBuilder b;
b.StaticAssert(nullptr); b.ConstAssert(nullptr);
}, },
"internal compiler error"); "internal compiler error");
} }
TEST_F(StaticAssertTest, Assert_DifferentProgramID_Condition) { TEST_F(ConstAssertTest, Assert_DifferentProgramID_Condition) {
EXPECT_FATAL_FAILURE( EXPECT_FATAL_FAILURE(
{ {
ProgramBuilder b1; ProgramBuilder b1;
ProgramBuilder b2; ProgramBuilder b2;
b1.StaticAssert(b2.Expr(i32(123))); b1.ConstAssert(b2.Expr(i32(123)));
}, },
"internal compiler error"); "internal compiler error");
} }

View File

@ -75,9 +75,9 @@ void Module::BinGlobalDeclaration(const tint::ast::Node* decl, diag::List& diags
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, enable, program_id); TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, enable, program_id);
enables_.Push(enable); enables_.Push(enable);
}, },
[&](const StaticAssert* assertion) { [&](const ConstAssert* assertion) {
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, assertion, program_id); TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, assertion, program_id);
static_asserts_.Push(assertion); const_asserts_.Push(assertion);
}, },
[&](Default) { TINT_ICE(AST, diags) << "Unknown global declaration type"; }); [&](Default) { TINT_ICE(AST, diags) << "Unknown global declaration type"; });
} }
@ -96,10 +96,10 @@ void Module::AddGlobalVariable(const ast::Variable* var) {
global_declarations_.Push(var); global_declarations_.Push(var);
} }
void Module::AddStaticAssert(const StaticAssert* assertion) { void Module::AddConstAssert(const ConstAssert* assertion) {
TINT_ASSERT(AST, assertion); TINT_ASSERT(AST, assertion);
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, assertion, program_id); TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, assertion, program_id);
static_asserts_.Push(assertion); const_asserts_.Push(assertion);
global_declarations_.Push(assertion); global_declarations_.Push(assertion);
} }

View File

@ -17,9 +17,9 @@
#include <string> #include <string>
#include "src/tint/ast/const_assert.h"
#include "src/tint/ast/enable.h" #include "src/tint/ast/enable.h"
#include "src/tint/ast/function.h" #include "src/tint/ast/function.h"
#include "src/tint/ast/static_assert.h"
#include "src/tint/ast/type.h" #include "src/tint/ast/type.h"
#include "src/tint/utils/vector.h" #include "src/tint/utils/vector.h"
@ -99,12 +99,12 @@ class Module final : public Castable<Module, Node> {
/// @returns the extension set for the module /// @returns the extension set for the module
const auto& Enables() const { return enables_; } const auto& Enables() const { return enables_; }
/// Add a global static assertion to the module /// Add a global const assertion to the module
/// @param assertion the static assert to add /// @param assertion the const assert to add
void AddStaticAssert(const StaticAssert* assertion); void AddConstAssert(const ConstAssert* assertion);
/// @returns the list of global static assertions /// @returns the list of global const assertions
const auto& StaticAsserts() const { return static_asserts_; } const auto& ConstAsserts() const { return const_asserts_; }
/// Adds a type declaration to the module /// Adds a type declaration to the module
/// @param decl the type declaration to add /// @param decl the type declaration to add
@ -147,7 +147,7 @@ class Module final : public Castable<Module, Node> {
FunctionList functions_; FunctionList functions_;
utils::Vector<const Variable*, 32> global_variables_; utils::Vector<const Variable*, 32> global_variables_;
utils::Vector<const Enable*, 8> enables_; utils::Vector<const Enable*, 8> enables_;
utils::Vector<const StaticAssert*, 8> static_asserts_; utils::Vector<const ConstAssert*, 8> const_asserts_;
}; };
} // namespace tint::ast } // namespace tint::ast

View File

@ -21,6 +21,7 @@
#include "src/tint/ast/bool_literal_expression.h" #include "src/tint/ast/bool_literal_expression.h"
#include "src/tint/ast/break_if_statement.h" #include "src/tint/ast/break_if_statement.h"
#include "src/tint/ast/break_statement.h" #include "src/tint/ast/break_statement.h"
#include "src/tint/ast/const_assert.h"
#include "src/tint/ast/continue_statement.h" #include "src/tint/ast/continue_statement.h"
#include "src/tint/ast/float_literal_expression.h" #include "src/tint/ast/float_literal_expression.h"
#include "src/tint/ast/for_loop_statement.h" #include "src/tint/ast/for_loop_statement.h"
@ -33,7 +34,6 @@
#include "src/tint/ast/override.h" #include "src/tint/ast/override.h"
#include "src/tint/ast/return_statement.h" #include "src/tint/ast/return_statement.h"
#include "src/tint/ast/statement.h" #include "src/tint/ast/statement.h"
#include "src/tint/ast/static_assert.h"
#include "src/tint/ast/struct.h" #include "src/tint/ast/struct.h"
#include "src/tint/ast/struct_member_align_attribute.h" #include "src/tint/ast/struct_member_align_attribute.h"
#include "src/tint/ast/struct_member_size_attribute.h" #include "src/tint/ast/struct_member_size_attribute.h"
@ -155,7 +155,7 @@ ResultType BuilderImpl::Build() {
// TODO(dsinclair): Implement? I think these need to be passed along so further stages // TODO(dsinclair): Implement? I think these need to be passed along so further stages
// know what is enabled. // know what is enabled.
// }, // },
[&](const ast::StaticAssert*) { [&](const ast::ConstAssert*) {
// Evaluated by the resolver, drop from the IR. // Evaluated by the resolver, drop from the IR.
return true; return true;
}, },
@ -253,7 +253,7 @@ bool BuilderImpl::EmitStatement(const ast::Statement* stmt) {
[&](const ast::ReturnStatement* r) { return EmitReturn(r); }, [&](const ast::ReturnStatement* r) { return EmitReturn(r); },
[&](const ast::SwitchStatement* s) { return EmitSwitch(s); }, [&](const ast::SwitchStatement* s) { return EmitSwitch(s); },
[&](const ast::VariableDeclStatement* v) { return EmitVariable(v->variable); }, [&](const ast::VariableDeclStatement* v) { return EmitVariable(v->variable); },
[&](const ast::StaticAssert*) { [&](const ast::ConstAssert*) {
return true; // Not emitted return true; // Not emitted
}, },
[&](Default) { [&](Default) {

View File

@ -37,6 +37,7 @@
#include "src/tint/ast/case_statement.h" #include "src/tint/ast/case_statement.h"
#include "src/tint/ast/compound_assignment_statement.h" #include "src/tint/ast/compound_assignment_statement.h"
#include "src/tint/ast/const.h" #include "src/tint/ast/const.h"
#include "src/tint/ast/const_assert.h"
#include "src/tint/ast/continue_statement.h" #include "src/tint/ast/continue_statement.h"
#include "src/tint/ast/depth_multisampled_texture.h" #include "src/tint/ast/depth_multisampled_texture.h"
#include "src/tint/ast/depth_texture.h" #include "src/tint/ast/depth_texture.h"
@ -72,7 +73,6 @@
#include "src/tint/ast/sampled_texture.h" #include "src/tint/ast/sampled_texture.h"
#include "src/tint/ast/sampler.h" #include "src/tint/ast/sampler.h"
#include "src/tint/ast/stage_attribute.h" #include "src/tint/ast/stage_attribute.h"
#include "src/tint/ast/static_assert.h"
#include "src/tint/ast/storage_texture.h" #include "src/tint/ast/storage_texture.h"
#include "src/tint/ast/stride_attribute.h" #include "src/tint/ast/stride_attribute.h"
#include "src/tint/ast/struct_member_align_attribute.h" #include "src/tint/ast/struct_member_align_attribute.h"
@ -1926,38 +1926,38 @@ class ProgramBuilder {
/// @param source the source information /// @param source the source information
/// @param condition the assertion condition /// @param condition the assertion condition
/// @returns a new `ast::StaticAssert`, which is automatically registered as a global statement /// @returns a new `ast::ConstAssert`, which is automatically registered as a global statement
/// with the ast::Module. /// with the ast::Module.
template <typename EXPR> template <typename EXPR>
const ast::StaticAssert* GlobalStaticAssert(const Source& source, EXPR&& condition) { const ast::ConstAssert* GlobalConstAssert(const Source& source, EXPR&& condition) {
auto* sa = StaticAssert(source, std::forward<EXPR>(condition)); auto* sa = ConstAssert(source, std::forward<EXPR>(condition));
AST().AddStaticAssert(sa); AST().AddConstAssert(sa);
return sa; return sa;
} }
/// @param condition the assertion condition /// @param condition the assertion condition
/// @returns a new `ast::StaticAssert`, which is automatically registered as a global statement /// @returns a new `ast::ConstAssert`, which is automatically registered as a global statement
/// with the ast::Module. /// with the ast::Module.
template <typename EXPR, typename = DisableIfSource<EXPR>> template <typename EXPR, typename = DisableIfSource<EXPR>>
const ast::StaticAssert* GlobalStaticAssert(EXPR&& condition) { const ast::ConstAssert* GlobalConstAssert(EXPR&& condition) {
auto* sa = StaticAssert(std::forward<EXPR>(condition)); auto* sa = ConstAssert(std::forward<EXPR>(condition));
AST().AddStaticAssert(sa); AST().AddConstAssert(sa);
return sa; return sa;
} }
/// @param source the source information /// @param source the source information
/// @param condition the assertion condition /// @param condition the assertion condition
/// @returns a new `ast::StaticAssert` with the given assertion condition /// @returns a new `ast::ConstAssert` with the given assertion condition
template <typename EXPR> template <typename EXPR>
const ast::StaticAssert* StaticAssert(const Source& source, EXPR&& condition) { const ast::ConstAssert* ConstAssert(const Source& source, EXPR&& condition) {
return create<ast::StaticAssert>(source, Expr(std::forward<EXPR>(condition))); return create<ast::ConstAssert>(source, Expr(std::forward<EXPR>(condition)));
} }
/// @param condition the assertion condition /// @param condition the assertion condition
/// @returns a new `ast::StaticAssert` with the given assertion condition /// @returns a new `ast::ConstAssert` with the given assertion condition
template <typename EXPR, typename = DisableIfSource<EXPR>> template <typename EXPR, typename = DisableIfSource<EXPR>>
const ast::StaticAssert* StaticAssert(EXPR&& condition) { const ast::ConstAssert* ConstAssert(EXPR&& condition) {
return create<ast::StaticAssert>(Expr(std::forward<EXPR>(condition))); return create<ast::ConstAssert>(Expr(std::forward<EXPR>(condition)));
} }
/// @param source the source information /// @param source the source information

View File

@ -1139,6 +1139,9 @@ Token Lexer::check_keyword(const Source& source, std::string_view str) {
if (str == "const") { if (str == "const") {
return {Token::Type::kConst, source, "const"}; return {Token::Type::kConst, source, "const"};
} }
if (str == "const_assert") {
return {Token::Type::kConstAssert, source, "const_assert"};
}
if (str == "continue") { if (str == "continue") {
return {Token::Type::kContinue, source, "continue"}; return {Token::Type::kContinue, source, "continue"};
} }

View File

@ -1064,6 +1064,7 @@ INSTANTIATE_TEST_SUITE_P(
TokenData{"break", Token::Type::kBreak}, TokenData{"break", Token::Type::kBreak},
TokenData{"case", Token::Type::kCase}, TokenData{"case", Token::Type::kCase},
TokenData{"const", Token::Type::kConst}, TokenData{"const", Token::Type::kConst},
TokenData{"const_assert", Token::Type::kConstAssert},
TokenData{"continue", Token::Type::kContinue}, TokenData{"continue", Token::Type::kContinue},
TokenData{"continuing", Token::Type::kContinuing}, TokenData{"continuing", Token::Type::kContinuing},
TokenData{"default", Token::Type::kDefault}, TokenData{"default", Token::Type::kDefault},

View File

@ -427,7 +427,7 @@ Maybe<Void> ParserImpl::enable_directive() {
// | type_alias_decl SEMICOLON // | type_alias_decl SEMICOLON
// | struct_decl // | struct_decl
// | function_decl // | function_decl
// | static_assert_statement SEMICOLON // | const_assert_statement SEMICOLON
Maybe<Void> ParserImpl::global_decl() { Maybe<Void> ParserImpl::global_decl() {
if (match(Token::Type::kSemicolon) || match(Token::Type::kEOF)) { if (match(Token::Type::kSemicolon) || match(Token::Type::kEOF)) {
return kSuccess; return kSuccess;
@ -486,13 +486,13 @@ Maybe<Void> ParserImpl::global_decl() {
return kSuccess; return kSuccess;
} }
auto assertion = static_assert_statement(); auto assertion = const_assert_statement();
if (assertion.errored) { if (assertion.errored) {
return Failure::kErrored; return Failure::kErrored;
} }
if (assertion.matched) { if (assertion.matched) {
builder_.AST().AddStaticAssert(assertion.value); builder_.AST().AddConstAssert(assertion.value);
if (!expect("static assertion declaration", Token::Type::kSemicolon)) { if (!expect("const assertion declaration", Token::Type::kSemicolon)) {
return Failure::kErrored; return Failure::kErrored;
} }
return kSuccess; return kSuccess;
@ -1455,11 +1455,15 @@ Expect<ast::StructMember*> ParserImpl::expect_struct_member() {
decl->type, std::move(attrs.value)); decl->type, std::move(attrs.value));
} }
// static_assert_statement // const_assert_statement
// : STATIC_ASSERT expression // : STATIC_ASSERT expression
Maybe<const ast::StaticAssert*> ParserImpl::static_assert_statement() { Maybe<const ast::ConstAssert*> ParserImpl::const_assert_statement() {
Source start; Source start;
if (!match(Token::Type::kStaticAssert, &start)) { if (match(Token::Type::kConstAssert, &start)) {
// matched
} else if (match(Token::Type::kStaticAssert, &start)) {
deprecated(start, "'static_assert' has been renamed to 'const_assert'");
} else {
return Failure::kNoMatch; return Failure::kNoMatch;
} }
@ -1472,7 +1476,7 @@ Maybe<const ast::StaticAssert*> ParserImpl::static_assert_statement() {
} }
Source source = make_source_range_from(start); Source source = make_source_range_from(start);
return create<ast::StaticAssert>(source, condition.value); return create<ast::ConstAssert>(source, condition.value);
} }
// function_decl // function_decl
@ -1786,7 +1790,7 @@ Maybe<const ast::Statement*> ParserImpl::statement() {
// | continue_statement SEMICOLON // | continue_statement SEMICOLON
// | DISCARD SEMICOLON // | DISCARD SEMICOLON
// | variable_updating_statement SEMICOLON // | variable_updating_statement SEMICOLON
// | static_assert_statement SEMICOLON // | const_assert_statement SEMICOLON
Maybe<const ast::Statement*> ParserImpl::non_block_statement() { Maybe<const ast::Statement*> ParserImpl::non_block_statement() {
auto stmt = [&]() -> Maybe<const ast::Statement*> { auto stmt = [&]() -> Maybe<const ast::Statement*> {
auto ret_stmt = return_statement(); auto ret_stmt = return_statement();
@ -1843,7 +1847,7 @@ Maybe<const ast::Statement*> ParserImpl::non_block_statement() {
return assign.value; return assign.value;
} }
auto stmt_static_assert = static_assert_statement(); auto stmt_static_assert = const_assert_statement();
if (stmt_static_assert.errored) { if (stmt_static_assert.errored) {
return Failure::kErrored; return Failure::kErrored;
} }

View File

@ -505,9 +505,9 @@ class ParserImpl {
/// @param use a description of what was being parsed if an error was raised /// @param use a description of what was being parsed if an error was raised
/// @returns returns the texel format or kNone if none matched. /// @returns returns the texel format or kNone if none matched.
Expect<type::TexelFormat> expect_texel_format(std::string_view use); Expect<type::TexelFormat> expect_texel_format(std::string_view use);
/// Parses a `static_assert_statement` grammar element /// Parses a `const_assert_statement` grammar element
/// @returns returns the static assert, if it matched. /// @returns returns the const assert, if it matched.
Maybe<const ast::StaticAssert*> static_assert_statement(); Maybe<const ast::ConstAssert*> const_assert_statement();
/// Parses a `function_header` grammar element /// Parses a `function_header` grammar element
/// @returns the parsed function header /// @returns the parsed function header
Maybe<FunctionHeader> function_header(); Maybe<FunctionHeader> function_header();

View File

@ -311,46 +311,130 @@ fn f() { for (var i : i32 = 0; i < 8; i=i+1) {
)"); )");
} }
TEST_F(ParserImplErrorTest, FunctionDeclStaticAssertMissingCondThenEOF) { TEST_F(ParserImplErrorTest, FunctionDeclConstAssertMissingCondThenEOF) {
EXPECT("fn f() { static_assert }", R"(test.wgsl:1:24 error: unable to parse condition expression EXPECT("fn f() { const_assert }", R"(test.wgsl:1:23 error: unable to parse condition expression
fn f() { static_assert } fn f() { const_assert }
^ ^
)"); )");
} }
TEST_F(ParserImplErrorTest, FunctionDeclStaticAssertMissingCondThenSemicolon) { TEST_F(ParserImplErrorTest, FunctionDeclConstAssertMissingCondThenSemicolon) {
EXPECT("fn f() { static_assert; }", EXPECT("fn f() { const_assert; }",
R"(test.wgsl:1:23 error: unable to parse condition expression R"(test.wgsl:1:22 error: unable to parse condition expression
fn f() { static_assert; } fn f() { const_assert; }
^ ^
)"); )");
} }
TEST_F(ParserImplErrorTest, FunctionDeclStaticAssertMissingCondThenLet) { TEST_F(ParserImplErrorTest, FunctionDeclConstAssertMissingCondThenLet) {
EXPECT("fn f() { static_assert\nlet x = 0; }", EXPECT("fn f() { const_assert\nlet x = 0; }",
R"(test.wgsl:2:1 error: unable to parse condition expression R"(test.wgsl:2:1 error: unable to parse condition expression
let x = 0; } let x = 0; }
^^^ ^^^
)"); )");
} }
TEST_F(ParserImplErrorTest, FunctionDeclStaticAssertMissingLParen) { TEST_F(ParserImplErrorTest, FunctionDeclConstAssertMissingLParen) {
EXPECT("fn f() { static_assert true);", R"(test.wgsl:1:28 error: expected ';' for statement EXPECT("fn f() { const_assert true);", R"(test.wgsl:1:27 error: expected ';' for statement
fn f() { const_assert true);
^
)");
}
TEST_F(ParserImplErrorTest, FunctionDeclConstAssertMissingRParen) {
EXPECT("fn f() { const_assert (true;", R"(test.wgsl:1:28 error: expected ')'
fn f() { const_assert (true;
^
)");
}
TEST_F(ParserImplErrorTest, FunctionDeclConstAssertMissingSemicolon) {
EXPECT("fn f() { const_assert true }",
R"(test.wgsl:1:28 error: expected ';' for statement
fn f() { const_assert true }
^
)");
}
// TODO(crbug.com/tint/1807)
TEST_F(ParserImplErrorTest, DEPRECATED_FunctionDeclStaticAssertMissingCondThenEOF) {
EXPECT(
"fn f() { static_assert }",
R"(test.wgsl:1:10 warning: use of deprecated language feature: 'static_assert' has been renamed to 'const_assert'
fn f() { static_assert }
^^^^^^^^^^^^^
test.wgsl:1:24 error: unable to parse condition expression
fn f() { static_assert }
^
)");
}
// TODO(crbug.com/tint/1807)
TEST_F(ParserImplErrorTest, DEPRECATED_FunctionDeclStaticAssertMissingCondThenSemicolon) {
EXPECT(
"fn f() { static_assert; }",
R"(test.wgsl:1:10 warning: use of deprecated language feature: 'static_assert' has been renamed to 'const_assert'
fn f() { static_assert; }
^^^^^^^^^^^^^
test.wgsl:1:23 error: unable to parse condition expression
fn f() { static_assert; }
^
)");
}
// TODO(crbug.com/tint/1807)
TEST_F(ParserImplErrorTest, DEPRECATED_FunctionDeclStaticAssertMissingCondThenLet) {
EXPECT(
"fn f() { static_assert\nlet x = 0; }",
R"(test.wgsl:1:10 warning: use of deprecated language feature: 'static_assert' has been renamed to 'const_assert'
fn f() { static_assert
^^^^^^^^^^^^^
test.wgsl:2:1 error: unable to parse condition expression
let x = 0; }
^^^
)");
}
// TODO(crbug.com/tint/1807)
TEST_F(ParserImplErrorTest, DEPRECATED_FunctionDeclStaticAssertMissingLParen) {
EXPECT(
"fn f() { static_assert true);",
R"(test.wgsl:1:10 warning: use of deprecated language feature: 'static_assert' has been renamed to 'const_assert'
fn f() { static_assert true);
^^^^^^^^^^^^^
test.wgsl:1:28 error: expected ';' for statement
fn f() { static_assert true); fn f() { static_assert true);
^ ^
)"); )");
} }
TEST_F(ParserImplErrorTest, FunctionDeclStaticAssertMissingRParen) { // TODO(crbug.com/tint/1807)
EXPECT("fn f() { static_assert (true;", R"(test.wgsl:1:29 error: expected ')' TEST_F(ParserImplErrorTest, DEPRECATED_FunctionDeclStaticAssertMissingRParen) {
EXPECT(
"fn f() { static_assert (true;",
R"(test.wgsl:1:10 warning: use of deprecated language feature: 'static_assert' has been renamed to 'const_assert'
fn f() { static_assert (true;
^^^^^^^^^^^^^
test.wgsl:1:29 error: expected ')'
fn f() { static_assert (true; fn f() { static_assert (true;
^ ^
)"); )");
} }
TEST_F(ParserImplErrorTest, FunctionDeclStaticAssertMissingSemicolon) { // TODO(crbug.com/tint/1807)
EXPECT("fn f() { static_assert true }", TEST_F(ParserImplErrorTest, DEPRECATED_FunctionDeclStaticAssertMissingSemicolon) {
R"(test.wgsl:1:29 error: expected ';' for statement EXPECT(
"fn f() { static_assert true }",
R"(test.wgsl:1:10 warning: use of deprecated language feature: 'static_assert' has been renamed to 'const_assert'
fn f() { static_assert true }
^^^^^^^^^^^^^
test.wgsl:1:29 error: expected ';' for statement
fn f() { static_assert true } fn f() { static_assert true }
^ ^
)"); )");
@ -622,46 +706,124 @@ var x : texture_multisampled_2d<1>;
)"); )");
} }
TEST_F(ParserImplErrorTest, GlobalDeclStaticAssertMissingCondThenEOF) { TEST_F(ParserImplErrorTest, GlobalDeclConstAssertMissingCondThenEOF) {
EXPECT("static_assert", R"(test.wgsl:1:14 error: unable to parse condition expression EXPECT("const_assert", R"(test.wgsl:1:13 error: unable to parse condition expression
static_assert const_assert
^ ^
)"); )");
} }
TEST_F(ParserImplErrorTest, GlobalDeclStaticAssertMissingCondThenSemicolon) { TEST_F(ParserImplErrorTest, GlobalDeclConstAssertMissingCondThenSemicolon) {
EXPECT("static_assert;", R"(test.wgsl:1:14 error: unable to parse condition expression EXPECT("const_assert;", R"(test.wgsl:1:13 error: unable to parse condition expression
static_assert; const_assert;
^ ^
)"); )");
} }
TEST_F(ParserImplErrorTest, GlobalDeclStaticAssertMissingCondThenAlias) { TEST_F(ParserImplErrorTest, GlobalDeclConstAssertMissingCondThenAlias) {
EXPECT("static_assert\ntype T = i32;", EXPECT("const_assert\ntype T = i32;",
R"(test.wgsl:2:1 error: unable to parse condition expression R"(test.wgsl:2:1 error: unable to parse condition expression
type T = i32; type T = i32;
^^^^ ^^^^
)"); )");
} }
TEST_F(ParserImplErrorTest, GlobalDeclStaticAssertMissingLParen) { TEST_F(ParserImplErrorTest, GlobalDeclConstAssertMissingLParen) {
EXPECT("static_assert true);", EXPECT("const_assert true);",
R"(test.wgsl:1:19 error: expected ';' for static assertion declaration R"(test.wgsl:1:18 error: expected ';' for const assertion declaration
const_assert true);
^
)");
}
TEST_F(ParserImplErrorTest, GlobalDeclConstAssertMissingRParen) {
EXPECT("const_assert (true;", R"(test.wgsl:1:19 error: expected ')'
const_assert (true;
^
)");
}
TEST_F(ParserImplErrorTest, GlobalDeclConstAssertMissingSemicolon) {
EXPECT("const_assert true const_assert true;",
R"(test.wgsl:1:19 error: expected ';' for const assertion declaration
const_assert true const_assert true;
^^^^^^^^^^^^
)");
}
// TODO(crbug.com/tint/1807): DEPRECATED
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclStaticAssertMissingCondThenEOF) {
EXPECT("const_assert", R"(test.wgsl:1:13 error: unable to parse condition expression
const_assert
^
)");
}
// TODO(crbug.com/tint/1807): DEPRECATED
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclStaticAssertMissingCondThenSemicolon) {
EXPECT(
"static_assert;",
R"(test.wgsl:1:1 warning: use of deprecated language feature: 'static_assert' has been renamed to 'const_assert'
static_assert;
^^^^^^^^^^^^^
test.wgsl:1:14 error: unable to parse condition expression
static_assert;
^
)");
}
// TODO(crbug.com/tint/1807): DEPRECATED
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclStaticAssertMissingCondThenAlias) {
EXPECT(
"static_assert\ntype T = i32;",
R"(test.wgsl:1:1 warning: use of deprecated language feature: 'static_assert' has been renamed to 'const_assert'
static_assert
^^^^^^^^^^^^^
test.wgsl:2:1 error: unable to parse condition expression
type T = i32;
^^^^
)");
}
// TODO(crbug.com/tint/1807): DEPRECATED
TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclStaticAssertMissingLParen) {
EXPECT(
"static_assert true);",
R"(test.wgsl:1:1 warning: use of deprecated language feature: 'static_assert' has been renamed to 'const_assert'
static_assert true);
^^^^^^^^^^^^^
test.wgsl:1:19 error: expected ';' for const assertion declaration
static_assert true); static_assert true);
^ ^
)"); )");
} }
TEST_F(ParserImplErrorTest, GlobalDeclStaticAssertMissingRParen) { // TODO(crbug.com/tint/1807): DEPRECATED
EXPECT("static_assert (true;", R"(test.wgsl:1:20 error: expected ')' TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclStaticAssertMissingRParen) {
EXPECT(
"static_assert (true;",
R"(test.wgsl:1:1 warning: use of deprecated language feature: 'static_assert' has been renamed to 'const_assert'
static_assert (true;
^^^^^^^^^^^^^
test.wgsl:1:20 error: expected ')'
static_assert (true; static_assert (true;
^ ^
)"); )");
} }
TEST_F(ParserImplErrorTest, GlobalDeclStaticAssertMissingSemicolon) { // TODO(crbug.com/tint/1807): DEPRECATED
EXPECT("static_assert true static_assert true;", TEST_F(ParserImplErrorTest, DEPRECATED_GlobalDeclStaticAssertMissingSemicolon) {
R"(test.wgsl:1:20 error: expected ';' for static assertion declaration EXPECT(
"static_assert true static_assert true;",
R"(test.wgsl:1:1 warning: use of deprecated language feature: 'static_assert' has been renamed to 'const_assert'
static_assert true static_assert true;
^^^^^^^^^^^^^
test.wgsl:1:20 error: expected ';' for const assertion declaration
static_assert true static_assert true; static_assert true static_assert true;
^^^^^^^^^^^^^ ^^^^^^^^^^^^^
)"); )");

View File

@ -257,14 +257,57 @@ TEST_F(ParserImplTest, GlobalDecl_Struct_UnexpectedAttribute) {
EXPECT_EQ(p->error(), "1:2: unexpected attributes"); EXPECT_EQ(p->error(), "1:2: unexpected attributes");
} }
TEST_F(ParserImplTest, GlobalDecl_StaticAssert_WithParen) { TEST_F(ParserImplTest, GlobalDecl_ConstAssert_WithParen) {
auto p = parser("const_assert(true);");
p->global_decl();
ASSERT_FALSE(p->has_error()) << p->error();
auto program = p->program();
ASSERT_EQ(program.AST().ConstAsserts().Length(), 1u);
auto* sa = program.AST().ConstAsserts()[0];
EXPECT_EQ(sa->source.range.begin.line, 1u);
EXPECT_EQ(sa->source.range.begin.column, 1u);
EXPECT_EQ(sa->source.range.end.line, 1u);
EXPECT_EQ(sa->source.range.end.column, 19u);
EXPECT_TRUE(sa->condition->Is<ast::BoolLiteralExpression>());
EXPECT_EQ(sa->condition->source.range.begin.line, 1u);
EXPECT_EQ(sa->condition->source.range.begin.column, 14u);
EXPECT_EQ(sa->condition->source.range.end.line, 1u);
EXPECT_EQ(sa->condition->source.range.end.column, 18u);
}
TEST_F(ParserImplTest, GlobalDecl_ConstAssert_WithoutParen) {
auto p = parser("const_assert true;");
p->global_decl();
ASSERT_FALSE(p->has_error()) << p->error();
auto program = p->program();
ASSERT_EQ(program.AST().ConstAsserts().Length(), 1u);
auto* sa = program.AST().ConstAsserts()[0];
EXPECT_TRUE(sa->condition->Is<ast::BoolLiteralExpression>());
EXPECT_EQ(sa->source.range.begin.line, 1u);
EXPECT_EQ(sa->source.range.begin.column, 1u);
EXPECT_EQ(sa->source.range.end.line, 1u);
EXPECT_EQ(sa->source.range.end.column, 19u);
EXPECT_TRUE(sa->condition->Is<ast::BoolLiteralExpression>());
EXPECT_EQ(sa->condition->source.range.begin.line, 1u);
EXPECT_EQ(sa->condition->source.range.begin.column, 15u);
EXPECT_EQ(sa->condition->source.range.end.line, 1u);
EXPECT_EQ(sa->condition->source.range.end.column, 19u);
}
// TODO(crbug.com/tint/1807)
TEST_F(ParserImplTest, DEPRECATED_GlobalDecl_StaticAssert_WithParen) {
auto p = parser("static_assert(true);"); auto p = parser("static_assert(true);");
p->global_decl(); p->global_decl();
ASSERT_FALSE(p->has_error()) << p->error(); ASSERT_FALSE(p->has_error()) << p->error();
auto program = p->program(); auto program = p->program();
ASSERT_EQ(program.AST().StaticAsserts().Length(), 1u); ASSERT_EQ(program.AST().ConstAsserts().Length(), 1u);
auto* sa = program.AST().StaticAsserts()[0]; auto* sa = program.AST().ConstAsserts()[0];
EXPECT_EQ(sa->source.range.begin.line, 1u); EXPECT_EQ(sa->source.range.begin.line, 1u);
EXPECT_EQ(sa->source.range.begin.column, 1u); EXPECT_EQ(sa->source.range.begin.column, 1u);
EXPECT_EQ(sa->source.range.end.line, 1u); EXPECT_EQ(sa->source.range.end.line, 1u);
@ -277,14 +320,15 @@ TEST_F(ParserImplTest, GlobalDecl_StaticAssert_WithParen) {
EXPECT_EQ(sa->condition->source.range.end.column, 19u); EXPECT_EQ(sa->condition->source.range.end.column, 19u);
} }
TEST_F(ParserImplTest, GlobalDecl_StaticAssert_WithoutParen) { // TODO(crbug.com/tint/1807)
TEST_F(ParserImplTest, DEPRECATED_GlobalDecl_StaticAssert_WithoutParen) {
auto p = parser("static_assert true;"); auto p = parser("static_assert true;");
p->global_decl(); p->global_decl();
ASSERT_FALSE(p->has_error()) << p->error(); ASSERT_FALSE(p->has_error()) << p->error();
auto program = p->program(); auto program = p->program();
ASSERT_EQ(program.AST().StaticAsserts().Length(), 1u); ASSERT_EQ(program.AST().ConstAsserts().Length(), 1u);
auto* sa = program.AST().StaticAsserts()[0]; auto* sa = program.AST().ConstAsserts()[0];
EXPECT_TRUE(sa->condition->Is<ast::BoolLiteralExpression>()); EXPECT_TRUE(sa->condition->Is<ast::BoolLiteralExpression>());
EXPECT_EQ(sa->source.range.begin.line, 1u); EXPECT_EQ(sa->source.range.begin.line, 1u);

View File

@ -272,14 +272,57 @@ TEST_F(ParserImplTest, Statement_Body_Invalid) {
EXPECT_EQ(p->error(), "1:3: expected '}'"); EXPECT_EQ(p->error(), "1:3: expected '}'");
} }
TEST_F(ParserImplTest, Statement_StaticAssert_WithParen) { TEST_F(ParserImplTest, Statement_ConstAssert_WithParen) {
auto p = parser("const_assert(true);");
auto e = p->statement();
ASSERT_FALSE(p->has_error()) << p->error();
EXPECT_TRUE(e.matched);
EXPECT_FALSE(e.errored);
auto* sa = As<ast::ConstAssert>(e.value);
ASSERT_NE(sa, nullptr);
EXPECT_EQ(sa->source.range.begin.line, 1u);
EXPECT_EQ(sa->source.range.begin.column, 1u);
EXPECT_EQ(sa->source.range.end.line, 1u);
EXPECT_EQ(sa->source.range.end.column, 19u);
EXPECT_TRUE(sa->condition->Is<ast::BoolLiteralExpression>());
EXPECT_EQ(sa->condition->source.range.begin.line, 1u);
EXPECT_EQ(sa->condition->source.range.begin.column, 14u);
EXPECT_EQ(sa->condition->source.range.end.line, 1u);
EXPECT_EQ(sa->condition->source.range.end.column, 18u);
}
TEST_F(ParserImplTest, Statement_ConstAssert_WithoutParen) {
auto p = parser("const_assert true;");
auto e = p->statement();
ASSERT_FALSE(p->has_error()) << p->error();
EXPECT_TRUE(e.matched);
EXPECT_FALSE(e.errored);
auto* sa = As<ast::ConstAssert>(e.value);
ASSERT_NE(sa, nullptr);
EXPECT_EQ(sa->source.range.begin.line, 1u);
EXPECT_EQ(sa->source.range.begin.column, 1u);
EXPECT_EQ(sa->source.range.end.line, 1u);
EXPECT_EQ(sa->source.range.end.column, 19u);
EXPECT_TRUE(sa->condition->Is<ast::BoolLiteralExpression>());
EXPECT_EQ(sa->condition->source.range.begin.line, 1u);
EXPECT_EQ(sa->condition->source.range.begin.column, 15u);
EXPECT_EQ(sa->condition->source.range.end.line, 1u);
EXPECT_EQ(sa->condition->source.range.end.column, 19u);
}
// TODO(crbug.com/tint/1807)
TEST_F(ParserImplTest, DEPRECATED_Statement_StaticAssert_WithParen) {
auto p = parser("static_assert(true);"); auto p = parser("static_assert(true);");
auto e = p->statement(); auto e = p->statement();
ASSERT_FALSE(p->has_error()) << p->error(); ASSERT_FALSE(p->has_error()) << p->error();
EXPECT_TRUE(e.matched); EXPECT_TRUE(e.matched);
EXPECT_FALSE(e.errored); EXPECT_FALSE(e.errored);
auto* sa = As<ast::StaticAssert>(e.value); auto* sa = As<ast::ConstAssert>(e.value);
ASSERT_NE(sa, nullptr); ASSERT_NE(sa, nullptr);
EXPECT_EQ(sa->source.range.begin.line, 1u); EXPECT_EQ(sa->source.range.begin.line, 1u);
EXPECT_EQ(sa->source.range.begin.column, 1u); EXPECT_EQ(sa->source.range.begin.column, 1u);
@ -293,14 +336,15 @@ TEST_F(ParserImplTest, Statement_StaticAssert_WithParen) {
EXPECT_EQ(sa->condition->source.range.end.column, 19u); EXPECT_EQ(sa->condition->source.range.end.column, 19u);
} }
TEST_F(ParserImplTest, Statement_StaticAssert_WithoutParen) { // TODO(crbug.com/tint/1807)
TEST_F(ParserImplTest, DEPRECATED_Statement_StaticAssert_WithoutParen) {
auto p = parser("static_assert true;"); auto p = parser("static_assert true;");
auto e = p->statement(); auto e = p->statement();
ASSERT_FALSE(p->has_error()) << p->error(); ASSERT_FALSE(p->has_error()) << p->error();
EXPECT_TRUE(e.matched); EXPECT_TRUE(e.matched);
EXPECT_FALSE(e.errored); EXPECT_FALSE(e.errored);
auto* sa = As<ast::StaticAssert>(e.value); auto* sa = As<ast::ConstAssert>(e.value);
ASSERT_NE(sa, nullptr); ASSERT_NE(sa, nullptr);
EXPECT_EQ(sa->source.range.begin.line, 1u); EXPECT_EQ(sa->source.range.begin.line, 1u);
EXPECT_EQ(sa->source.range.begin.column, 1u); EXPECT_EQ(sa->source.range.begin.column, 1u);

View File

@ -151,6 +151,8 @@ std::string_view Token::TypeToName(Type type) {
return "case"; return "case";
case Token::Type::kConst: case Token::Type::kConst:
return "const"; return "const";
case Token::Type::kConstAssert:
return "const_assert";
case Token::Type::kContinue: case Token::Type::kContinue:
return "continue"; return "continue";
case Token::Type::kContinuing: case Token::Type::kContinuing:

View File

@ -161,6 +161,8 @@ class Token {
kCase, kCase,
/// A 'const' /// A 'const'
kConst, kConst,
/// A 'const_assert'
kConstAssert,
/// A 'continue' /// A 'continue'
kContinue, kContinue,
/// A 'continuing' /// A 'continuing'

View File

@ -0,0 +1,107 @@
// Copyright 2022 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/tint/resolver/resolver.h"
#include "gmock/gmock.h"
#include "src/tint/resolver/resolver_test_helper.h"
using namespace tint::number_suffixes; // NOLINT
namespace tint::resolver {
namespace {
using ResolverConstAssertTest = ResolverTest;
TEST_F(ResolverConstAssertTest, Global_True_Pass) {
GlobalConstAssert(true);
ASSERT_TRUE(r()->Resolve()) << r()->error();
}
TEST_F(ResolverConstAssertTest, Global_False_Fail) {
GlobalConstAssert(Source{{12, 34}}, false);
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), "12:34 error: const assertion failed");
}
TEST_F(ResolverConstAssertTest, Global_Const_Pass) {
GlobalConst("C", ty.bool_(), Expr(true));
GlobalConstAssert("C");
ASSERT_TRUE(r()->Resolve()) << r()->error();
}
TEST_F(ResolverConstAssertTest, Global_Const_Fail) {
GlobalConst("C", ty.bool_(), Expr(false));
GlobalConstAssert(Source{{12, 34}}, "C");
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), "12:34 error: const assertion failed");
}
TEST_F(ResolverConstAssertTest, Global_LessThan_Pass) {
GlobalConstAssert(LessThan(2_i, 3_i));
ASSERT_TRUE(r()->Resolve()) << r()->error();
}
TEST_F(ResolverConstAssertTest, Global_LessThan_Fail) {
GlobalConstAssert(Source{{12, 34}}, LessThan(4_i, 3_i));
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), "12:34 error: const assertion failed");
}
TEST_F(ResolverConstAssertTest, Local_True_Pass) {
WrapInFunction(ConstAssert(true));
ASSERT_TRUE(r()->Resolve()) << r()->error();
}
TEST_F(ResolverConstAssertTest, Local_False_Fail) {
WrapInFunction(ConstAssert(Source{{12, 34}}, false));
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), "12:34 error: const assertion failed");
}
TEST_F(ResolverConstAssertTest, Local_Const_Pass) {
GlobalConst("C", ty.bool_(), Expr(true));
WrapInFunction(ConstAssert("C"));
ASSERT_TRUE(r()->Resolve()) << r()->error();
}
TEST_F(ResolverConstAssertTest, Local_Const_Fail) {
GlobalConst("C", ty.bool_(), Expr(false));
WrapInFunction(ConstAssert(Source{{12, 34}}, "C"));
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), "12:34 error: const assertion failed");
}
TEST_F(ResolverConstAssertTest, Local_NonConst) {
GlobalVar("V", ty.bool_(), Expr(true), type::AddressSpace::kPrivate);
WrapInFunction(ConstAssert(Expr(Source{{12, 34}}, "V")));
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
"12:34 error: const assertion requires a const-expression, but expression is a "
"runtime-expression");
}
TEST_F(ResolverConstAssertTest, Local_LessThan_Pass) {
WrapInFunction(ConstAssert(LessThan(2_i, 3_i)));
ASSERT_TRUE(r()->Resolve()) << r()->error();
}
TEST_F(ResolverConstAssertTest, Local_LessThan_Fail) {
WrapInFunction(ConstAssert(Source{{12, 34}}, LessThan(4_i, 3_i)));
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), "12:34 error: const assertion failed");
}
} // namespace
} // namespace tint::resolver

View File

@ -207,7 +207,7 @@ class DependencyScanner {
[&](const ast::Enable*) { [&](const ast::Enable*) {
// Enable directives do not effect the dependency graph. // Enable directives do not effect the dependency graph.
}, },
[&](const ast::StaticAssert* assertion) { TraverseExpression(assertion->condition); }, [&](const ast::ConstAssert* assertion) { TraverseExpression(assertion->condition); },
[&](Default) { UnhandledNode(diagnostics_, global->node); }); [&](Default) { UnhandledNode(diagnostics_, global->node); });
} }
@ -319,7 +319,7 @@ class DependencyScanner {
TraverseExpression(w->condition); TraverseExpression(w->condition);
TraverseStatement(w->body); TraverseStatement(w->body);
}, },
[&](const ast::StaticAssert* assertion) { TraverseExpression(assertion->condition); }, [&](const ast::ConstAssert* assertion) { TraverseExpression(assertion->condition); },
[&](Default) { [&](Default) {
if (TINT_UNLIKELY((!stmt->IsAnyOf<ast::BreakStatement, ast::ContinueStatement, if (TINT_UNLIKELY((!stmt->IsAnyOf<ast::BreakStatement, ast::ContinueStatement,
ast::DiscardStatement>()))) { ast::DiscardStatement>()))) {
@ -556,7 +556,7 @@ struct DependencyAnalysis {
[&](const ast::Function* func) { return func->symbol; }, [&](const ast::Function* func) { return func->symbol; },
[&](const ast::Variable* var) { return var->symbol; }, [&](const ast::Variable* var) { return var->symbol; },
[&](const ast::Enable*) { return Symbol(); }, [&](const ast::Enable*) { return Symbol(); },
[&](const ast::StaticAssert*) { return Symbol(); }, [&](const ast::ConstAssert*) { return Symbol(); },
[&](Default) { [&](Default) {
UnhandledNode(diagnostics_, node); UnhandledNode(diagnostics_, node);
return Symbol{}; return Symbol{};
@ -580,7 +580,7 @@ struct DependencyAnalysis {
[&](const ast::Alias*) { return "alias"; }, // [&](const ast::Alias*) { return "alias"; }, //
[&](const ast::Function*) { return "function"; }, // [&](const ast::Function*) { return "function"; }, //
[&](const ast::Variable* v) { return v->Kind(); }, // [&](const ast::Variable* v) { return v->Kind(); }, //
[&](const ast::StaticAssert*) { return "static_assert"; }, // [&](const ast::ConstAssert*) { return "const_assert"; }, //
[&](Default) { [&](Default) {
UnhandledNode(diagnostics_, node); UnhandledNode(diagnostics_, node);
return "<error>"; return "<error>";

View File

@ -155,7 +155,7 @@ bool Resolver::ResolveInternal() {
[&](const ast::TypeDecl* td) { return TypeDecl(td); }, [&](const ast::TypeDecl* td) { return TypeDecl(td); },
[&](const ast::Function* func) { return Function(func); }, [&](const ast::Function* func) { return Function(func); },
[&](const ast::Variable* var) { return GlobalVariable(var); }, [&](const ast::Variable* var) { return GlobalVariable(var); },
[&](const ast::StaticAssert* sa) { return StaticAssert(sa); }, [&](const ast::ConstAssert* ca) { return ConstAssert(ca); },
[&](Default) { [&](Default) {
TINT_UNREACHABLE(Resolver, diagnostics_) TINT_UNREACHABLE(Resolver, diagnostics_)
<< "unhandled global declaration: " << decl->TypeInfo().name; << "unhandled global declaration: " << decl->TypeInfo().name;
@ -936,8 +936,8 @@ sem::GlobalVariable* Resolver::GlobalVariable(const ast::Variable* v) {
return sem; return sem;
} }
sem::Statement* Resolver::StaticAssert(const ast::StaticAssert* assertion) { sem::Statement* Resolver::ConstAssert(const ast::ConstAssert* assertion) {
ExprEvalStageConstraint constraint{sem::EvaluationStage::kConstant, "static assertion"}; ExprEvalStageConstraint constraint{sem::EvaluationStage::kConstant, "const assertion"};
TINT_SCOPED_ASSIGNMENT(expr_eval_stage_constraint_, constraint); TINT_SCOPED_ASSIGNMENT(expr_eval_stage_constraint_, constraint);
auto* expr = Expression(assertion->condition); auto* expr = Expression(assertion->condition);
if (!expr) { if (!expr) {
@ -946,12 +946,12 @@ sem::Statement* Resolver::StaticAssert(const ast::StaticAssert* assertion) {
auto* cond = expr->ConstantValue(); auto* cond = expr->ConstantValue();
if (auto* ty = cond->Type(); !ty->Is<type::Bool>()) { if (auto* ty = cond->Type(); !ty->Is<type::Bool>()) {
AddError( AddError(
"static assertion condition must be a bool, got '" + builder_->FriendlyName(ty) + "'", "const assertion condition must be a bool, got '" + builder_->FriendlyName(ty) + "'",
assertion->condition->source); assertion->condition->source);
return nullptr; return nullptr;
} }
if (!cond->ValueAs<bool>()) { if (!cond->ValueAs<bool>()) {
AddError("static assertion failed", assertion->source); AddError("const assertion failed", assertion->source);
return nullptr; return nullptr;
} }
auto* sem = auto* sem =
@ -1258,7 +1258,7 @@ sem::Statement* Resolver::Statement(const ast::Statement* stmt) {
[&](const ast::IncrementDecrementStatement* i) { return IncrementDecrementStatement(i); }, [&](const ast::IncrementDecrementStatement* i) { return IncrementDecrementStatement(i); },
[&](const ast::ReturnStatement* r) { return ReturnStatement(r); }, [&](const ast::ReturnStatement* r) { return ReturnStatement(r); },
[&](const ast::VariableDeclStatement* v) { return VariableDeclStatement(v); }, [&](const ast::VariableDeclStatement* v) { return VariableDeclStatement(v); },
[&](const ast::StaticAssert* sa) { return StaticAssert(sa); }, [&](const ast::ConstAssert* sa) { return ConstAssert(sa); },
// Error cases // Error cases
[&](const ast::CaseStatement*) { [&](const ast::CaseStatement*) {

View File

@ -230,6 +230,7 @@ class Resolver {
sem::CaseStatement* CaseStatement(const ast::CaseStatement*, const type::Type*); sem::CaseStatement* CaseStatement(const ast::CaseStatement*, const type::Type*);
sem::Statement* CompoundAssignmentStatement(const ast::CompoundAssignmentStatement*); sem::Statement* CompoundAssignmentStatement(const ast::CompoundAssignmentStatement*);
sem::Statement* ContinueStatement(const ast::ContinueStatement*); sem::Statement* ContinueStatement(const ast::ContinueStatement*);
sem::Statement* ConstAssert(const ast::ConstAssert*);
sem::Statement* DiscardStatement(const ast::DiscardStatement*); sem::Statement* DiscardStatement(const ast::DiscardStatement*);
sem::ForLoopStatement* ForLoopStatement(const ast::ForLoopStatement*); sem::ForLoopStatement* ForLoopStatement(const ast::ForLoopStatement*);
sem::WhileStatement* WhileStatement(const ast::WhileStatement*); sem::WhileStatement* WhileStatement(const ast::WhileStatement*);
@ -240,7 +241,6 @@ class Resolver {
sem::LoopStatement* LoopStatement(const ast::LoopStatement*); sem::LoopStatement* LoopStatement(const ast::LoopStatement*);
sem::Statement* ReturnStatement(const ast::ReturnStatement*); sem::Statement* ReturnStatement(const ast::ReturnStatement*);
sem::Statement* Statement(const ast::Statement*); sem::Statement* Statement(const ast::Statement*);
sem::Statement* StaticAssert(const ast::StaticAssert*);
sem::SwitchStatement* SwitchStatement(const ast::SwitchStatement* s); sem::SwitchStatement* SwitchStatement(const ast::SwitchStatement* s);
sem::Statement* VariableDeclStatement(const ast::VariableDeclStatement*); sem::Statement* VariableDeclStatement(const ast::VariableDeclStatement*);
bool Statements(utils::VectorRef<const ast::Statement*>); bool Statements(utils::VectorRef<const ast::Statement*>);

View File

@ -1,107 +0,0 @@
// Copyright 2022 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/tint/resolver/resolver.h"
#include "gmock/gmock.h"
#include "src/tint/resolver/resolver_test_helper.h"
using namespace tint::number_suffixes; // NOLINT
namespace tint::resolver {
namespace {
using ResolverStaticAssertTest = ResolverTest;
TEST_F(ResolverStaticAssertTest, Global_True_Pass) {
GlobalStaticAssert(true);
ASSERT_TRUE(r()->Resolve()) << r()->error();
}
TEST_F(ResolverStaticAssertTest, Global_False_Fail) {
GlobalStaticAssert(Source{{12, 34}}, false);
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), "12:34 error: static assertion failed");
}
TEST_F(ResolverStaticAssertTest, Global_Const_Pass) {
GlobalConst("C", ty.bool_(), Expr(true));
GlobalStaticAssert("C");
ASSERT_TRUE(r()->Resolve()) << r()->error();
}
TEST_F(ResolverStaticAssertTest, Global_Const_Fail) {
GlobalConst("C", ty.bool_(), Expr(false));
GlobalStaticAssert(Source{{12, 34}}, "C");
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), "12:34 error: static assertion failed");
}
TEST_F(ResolverStaticAssertTest, Global_LessThan_Pass) {
GlobalStaticAssert(LessThan(2_i, 3_i));
ASSERT_TRUE(r()->Resolve()) << r()->error();
}
TEST_F(ResolverStaticAssertTest, Global_LessThan_Fail) {
GlobalStaticAssert(Source{{12, 34}}, LessThan(4_i, 3_i));
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), "12:34 error: static assertion failed");
}
TEST_F(ResolverStaticAssertTest, Local_True_Pass) {
WrapInFunction(StaticAssert(true));
ASSERT_TRUE(r()->Resolve()) << r()->error();
}
TEST_F(ResolverStaticAssertTest, Local_False_Fail) {
WrapInFunction(StaticAssert(Source{{12, 34}}, false));
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), "12:34 error: static assertion failed");
}
TEST_F(ResolverStaticAssertTest, Local_Const_Pass) {
GlobalConst("C", ty.bool_(), Expr(true));
WrapInFunction(StaticAssert("C"));
ASSERT_TRUE(r()->Resolve()) << r()->error();
}
TEST_F(ResolverStaticAssertTest, Local_Const_Fail) {
GlobalConst("C", ty.bool_(), Expr(false));
WrapInFunction(StaticAssert(Source{{12, 34}}, "C"));
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), "12:34 error: static assertion failed");
}
TEST_F(ResolverStaticAssertTest, Local_NonConst) {
GlobalVar("V", ty.bool_(), Expr(true), type::AddressSpace::kPrivate);
WrapInFunction(StaticAssert(Expr(Source{{12, 34}}, "V")));
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
"12:34 error: static assertion requires a const-expression, but expression is a "
"runtime-expression");
}
TEST_F(ResolverStaticAssertTest, Local_LessThan_Pass) {
WrapInFunction(StaticAssert(LessThan(2_i, 3_i)));
ASSERT_TRUE(r()->Resolve()) << r()->error();
}
TEST_F(ResolverStaticAssertTest, Local_LessThan_Fail) {
WrapInFunction(StaticAssert(Source{{12, 34}}, LessThan(4_i, 3_i)));
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), "12:34 error: static assertion failed");
}
} // namespace
} // namespace tint::resolver

View File

@ -1067,7 +1067,7 @@ class UniformityGraph {
return cf; return cf;
}, },
[&](const ast::StaticAssert*) { [&](const ast::ConstAssert*) {
return cf; // No impact on uniformity return cf; // No impact on uniformity
}, },

View File

@ -250,7 +250,7 @@ bool GeneratorImpl::Generate() {
auto* mod = builder_.Sem().Module(); auto* mod = builder_.Sem().Module();
for (auto* decl : mod->DependencyOrderedDeclarations()) { for (auto* decl : mod->DependencyOrderedDeclarations()) {
if (decl->IsAnyOf<ast::Alias, ast::StaticAssert>()) { if (decl->IsAnyOf<ast::Alias, ast::ConstAssert>()) {
continue; // These are not emitted. continue; // These are not emitted.
} }
@ -2796,7 +2796,7 @@ bool GeneratorImpl::EmitStatement(const ast::Statement* stmt) {
return false; return false;
}); });
}, },
[&](const ast::StaticAssert*) { [&](const ast::ConstAssert*) {
return true; // Not emitted return true; // Not emitted
}, },
[&](Default) { [&](Default) {

View File

@ -310,7 +310,7 @@ bool GeneratorImpl::Generate() {
auto* mod = builder_.Sem().Module(); auto* mod = builder_.Sem().Module();
for (auto* decl : mod->DependencyOrderedDeclarations()) { for (auto* decl : mod->DependencyOrderedDeclarations()) {
if (decl->IsAnyOf<ast::Alias, ast::Enable, ast::StaticAssert>()) { if (decl->IsAnyOf<ast::Alias, ast::Enable, ast::ConstAssert>()) {
continue; // These are not emitted. continue; // These are not emitted.
} }
@ -3842,7 +3842,7 @@ bool GeneratorImpl::EmitStatement(const ast::Statement* stmt) {
return false; return false;
}); });
}, },
[&](const ast::StaticAssert*) { [&](const ast::ConstAssert*) {
return true; // Not emitted return true; // Not emitted
}, },
[&](Default) { // [&](Default) { //

View File

@ -21,23 +21,23 @@ namespace {
using HlslGeneratorImplTest = TestHelper; using HlslGeneratorImplTest = TestHelper;
TEST_F(HlslGeneratorImplTest, Emit_GlobalStaticAssert) { TEST_F(HlslGeneratorImplTest, Emit_GlobalConstAssert) {
GlobalStaticAssert(true); GlobalConstAssert(true);
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error(); ASSERT_TRUE(gen.Generate()) << gen.error();
// static asserts are not emitted // const asserts are not emitted
EXPECT_EQ(gen.result(), ""); EXPECT_EQ(gen.result(), "");
} }
TEST_F(HlslGeneratorImplTest, Emit_FunctionStaticAssert) { TEST_F(HlslGeneratorImplTest, Emit_FunctionConstAssert) {
Func("f", utils::Empty, ty.void_(), utils::Vector{StaticAssert(true)}); Func("f", utils::Empty, ty.void_(), utils::Vector{ConstAssert(true)});
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error(); ASSERT_TRUE(gen.Generate()) << gen.error();
// static asserts are not emitted // const asserts are not emitted
EXPECT_EQ(gen.result(), R"(void f() { EXPECT_EQ(gen.result(), R"(void f() {
} }
)"); )");

View File

@ -317,7 +317,7 @@ bool GeneratorImpl::Generate() {
// Do nothing for enabling extension in MSL // Do nothing for enabling extension in MSL
return true; return true;
}, },
[&](const ast::StaticAssert*) { [&](const ast::ConstAssert*) {
return true; // Not emitted return true; // Not emitted
}, },
[&](Default) { [&](Default) {
@ -2469,7 +2469,7 @@ bool GeneratorImpl::EmitStatement(const ast::Statement* stmt) {
return false; return false;
}); });
}, },
[&](const ast::StaticAssert*) { [&](const ast::ConstAssert*) {
return true; // Not emitted return true; // Not emitted
}, },
[&](Default) { [&](Default) {

View File

@ -21,26 +21,26 @@ namespace {
using MslGeneratorImplTest = TestHelper; using MslGeneratorImplTest = TestHelper;
TEST_F(MslGeneratorImplTest, Emit_GlobalStaticAssert) { TEST_F(MslGeneratorImplTest, Emit_GlobalConstAssert) {
GlobalStaticAssert(true); GlobalConstAssert(true);
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error(); ASSERT_TRUE(gen.Generate()) << gen.error();
// static asserts are not emitted // const asserts are not emitted
EXPECT_EQ(gen.result(), R"(#include <metal_stdlib> EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
using namespace metal; using namespace metal;
)"); )");
} }
TEST_F(MslGeneratorImplTest, Emit_FunctionStaticAssert) { TEST_F(MslGeneratorImplTest, Emit_FunctionConstAssert) {
Func("f", utils::Empty, ty.void_(), utils::Vector{StaticAssert(true)}); Func("f", utils::Empty, ty.void_(), utils::Vector{ConstAssert(true)});
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error(); ASSERT_TRUE(gen.Generate()) << gen.error();
// static asserts are not emitted // const asserts are not emitted
EXPECT_EQ(gen.result(), R"(#include <metal_stdlib> EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
using namespace metal; using namespace metal;

View File

@ -3614,7 +3614,7 @@ bool Builder::GenerateStatement(const ast::Statement* stmt) {
[&](const ast::ReturnStatement* r) { return GenerateReturnStatement(r); }, [&](const ast::ReturnStatement* r) { return GenerateReturnStatement(r); },
[&](const ast::SwitchStatement* s) { return GenerateSwitchStatement(s); }, [&](const ast::SwitchStatement* s) { return GenerateSwitchStatement(s); },
[&](const ast::VariableDeclStatement* v) { return GenerateVariableDeclStatement(v); }, [&](const ast::VariableDeclStatement* v) { return GenerateVariableDeclStatement(v); },
[&](const ast::StaticAssert*) { [&](const ast::ConstAssert*) {
return true; // Not emitted return true; // Not emitted
}, },
[&](Default) { [&](Default) {

View File

@ -22,26 +22,26 @@ namespace {
using BuilderTest = TestHelper; using BuilderTest = TestHelper;
TEST_F(BuilderTest, GlobalStaticAssert) { TEST_F(BuilderTest, GlobalConstAssert) {
GlobalStaticAssert(true); GlobalConstAssert(true);
spirv::Builder& b = Build(); spirv::Builder& b = Build();
ASSERT_TRUE(b.Build()) << b.error(); ASSERT_TRUE(b.Build()) << b.error();
// static asserts are not emitted // const asserts are not emitted
EXPECT_EQ(DumpInstructions(b.types()), ""); EXPECT_EQ(DumpInstructions(b.types()), "");
EXPECT_EQ(b.functions().size(), 0u); EXPECT_EQ(b.functions().size(), 0u);
} }
TEST_F(BuilderTest, FunctionStaticAssert) { TEST_F(BuilderTest, FunctionConstAssert) {
Func("f", utils::Empty, ty.void_(), utils::Vector{StaticAssert(true)}); Func("f", utils::Empty, ty.void_(), utils::Vector{ConstAssert(true)});
spirv::Builder& b = Build(); spirv::Builder& b = Build();
ASSERT_TRUE(b.Build()) << b.error(); ASSERT_TRUE(b.Build()) << b.error();
// static asserts are not emitted // const asserts are not emitted
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2 %1 = OpTypeFunction %2
)"); )");

View File

@ -82,7 +82,7 @@ bool GeneratorImpl::Generate() {
[&](const ast::TypeDecl* td) { return EmitTypeDecl(td); }, [&](const ast::TypeDecl* td) { return EmitTypeDecl(td); },
[&](const ast::Function* func) { return EmitFunction(func); }, [&](const ast::Function* func) { return EmitFunction(func); },
[&](const ast::Variable* var) { return EmitVariable(line(), var); }, [&](const ast::Variable* var) { return EmitVariable(line(), var); },
[&](const ast::StaticAssert* sa) { return EmitStaticAssert(sa); }, [&](const ast::ConstAssert* ca) { return EmitConstAssert(ca); },
[&](Default) { [&](Default) {
TINT_UNREACHABLE(Writer, diagnostics_); TINT_UNREACHABLE(Writer, diagnostics_);
return false; return false;
@ -992,7 +992,7 @@ bool GeneratorImpl::EmitStatement(const ast::Statement* stmt) {
[&](const ast::ForLoopStatement* l) { return EmitForLoop(l); }, [&](const ast::ForLoopStatement* l) { return EmitForLoop(l); },
[&](const ast::WhileStatement* l) { return EmitWhile(l); }, [&](const ast::WhileStatement* l) { return EmitWhile(l); },
[&](const ast::ReturnStatement* r) { return EmitReturn(r); }, [&](const ast::ReturnStatement* r) { return EmitReturn(r); },
[&](const ast::StaticAssert* s) { return EmitStaticAssert(s); }, [&](const ast::ConstAssert* c) { return EmitConstAssert(c); },
[&](const ast::SwitchStatement* s) { return EmitSwitch(s); }, [&](const ast::SwitchStatement* s) { return EmitSwitch(s); },
[&](const ast::VariableDeclStatement* v) { return EmitVariable(line(), v->variable); }, [&](const ast::VariableDeclStatement* v) { return EmitVariable(line(), v->variable); },
[&](Default) { [&](Default) {
@ -1299,7 +1299,7 @@ bool GeneratorImpl::EmitReturn(const ast::ReturnStatement* stmt) {
return true; return true;
} }
bool GeneratorImpl::EmitStaticAssert(const ast::StaticAssert* stmt) { bool GeneratorImpl::EmitConstAssert(const ast::ConstAssert* stmt) {
auto out = line(); auto out = line();
out << "static_assert "; out << "static_assert ";
if (!EmitExpression(out, stmt->condition)) { if (!EmitExpression(out, stmt->condition)) {

View File

@ -165,10 +165,10 @@ class GeneratorImpl : public TextGenerator {
/// @param stmt the statement to emit /// @param stmt the statement to emit
/// @returns true if the statement was successfully emitted /// @returns true if the statement was successfully emitted
bool EmitReturn(const ast::ReturnStatement* stmt); bool EmitReturn(const ast::ReturnStatement* stmt);
/// Handles static assertion statements /// Handles const assertion statements
/// @param stmt the statement to emit /// @param stmt the statement to emit
/// @returns true if the statement was successfully emitted /// @returns true if the statement was successfully emitted
bool EmitStaticAssert(const ast::StaticAssert* stmt); bool EmitConstAssert(const ast::ConstAssert* stmt);
/// Handles statement /// Handles statement
/// @param stmt the statement to emit /// @param stmt the statement to emit
/// @returns true if the statement was emitted /// @returns true if the statement was emitted

View File

@ -21,8 +21,8 @@ namespace {
using WgslGeneratorImplTest = TestHelper; using WgslGeneratorImplTest = TestHelper;
TEST_F(WgslGeneratorImplTest, Emit_GlobalStaticAssert) { TEST_F(WgslGeneratorImplTest, Emit_GlobalConstAssert) {
GlobalStaticAssert(true); GlobalConstAssert(true);
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
@ -31,8 +31,8 @@ TEST_F(WgslGeneratorImplTest, Emit_GlobalStaticAssert) {
)"); )");
} }
TEST_F(WgslGeneratorImplTest, Emit_FunctionStaticAssert) { TEST_F(WgslGeneratorImplTest, Emit_FunctionConstAssert) {
Func("f", utils::Empty, ty.void_(), utils::Vector{StaticAssert(true)}); Func("f", utils::Empty, ty.void_(), utils::Vector{ConstAssert(true)});
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();