wgsl: Deprecate 'const' for 'let'

Renamed with:
https://github.com/gpuweb/gpuweb/pull/1574

Bug: tint:699
Change-Id: I4dda868abe4c5bc0cba46bc81d9eb297a0663717
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/47141
Commit-Queue: Ben Clayton <bclayton@google.com>
Reviewed-by: David Neto <dneto@google.com>
This commit is contained in:
Ben Clayton 2021-04-08 15:46:17 +00:00 committed by Commit Bot service account
parent fae0aa6e72
commit 571f2b7363
29 changed files with 232 additions and 179 deletions

View File

@ -33,8 +33,8 @@ struct S {
m1 : array<u32>; m1 : array<u32>;
}; };
const c0 : i32 = 10; let c0 : i32 = 10;
const c1 : bool = true; let c1 : bool = true;
type t0 = [[stride(16)]] array<vec4<f32>>; type t0 = [[stride(16)]] array<vec4<f32>>;
type t1 = array<vec4<f32>>; type t1 = array<vec4<f32>>;
@ -102,7 +102,7 @@ fn main() {
f1(1.0, 2); f1(1.0, 2);
} }
const declaration_order_check_0 : i32 = 1; let declaration_order_check_0 : i32 = 1;
type declaration_order_check_1 = f32; type declaration_order_check_1 = f32;
@ -110,7 +110,7 @@ fn declaration_order_check_2() {}
type declaration_order_check_2 = f32; type declaration_order_check_2 = f32;
const declaration_order_check_3 : i32 = 1; let declaration_order_check_3 : i32 = 1;
)"); )");

View File

@ -46,9 +46,9 @@ class LocationDecoration;
/// var computed_depth : i32; /// var computed_depth : i32;
/// var area : i32 = compute_area(width, height); /// var area : i32 = compute_area(width, height);
/// ///
/// 2. A "const" declaration is a name for a typed value. Examples: /// 2. A "let" declaration is a name for a typed value. Examples:
/// ///
/// const twice_depth : i32 = width + width; // Must have initializer /// let twice_depth : i32 = width + width; // Must have initializer
/// ///
/// 3. A formal parameter to a function is a name for a typed value to /// 3. A formal parameter to a function is a name for a typed value to
/// be passed into a function. Example: /// be passed into a function. Example:

View File

@ -4948,7 +4948,7 @@ bool FunctionEmitter::MakeVectorInsertDynamic(
// //
// var temp : type = src_vector; // var temp : type = src_vector;
// temp[index] = component; // temp[index] = component;
// const result : type = temp; // let result : type = temp;
// //
// Then use result everywhere the original SPIR-V id is used. Using a const // Then use result everywhere the original SPIR-V id is used. Using a const
// like this avoids constantly reloading the value many times. // like this avoids constantly reloading the value many times.
@ -4989,7 +4989,7 @@ bool FunctionEmitter::MakeCompositeInsert(
// //
// var temp : type = composite; // var temp : type = composite;
// temp[index].x = object; // temp[index].x = object;
// const result : type = temp; // let result : type = temp;
// //
// Then use result everywhere the original SPIR-V id is used. Using a const // Then use result everywhere the original SPIR-V id is used. Using a const
// like this avoids constantly reloading the value many times. // like this avoids constantly reloading the value many times.

View File

@ -584,6 +584,8 @@ Token Lexer::check_keyword(const Source& source, const std::string& str) {
return {Token::Type::kImport, source, "import"}; return {Token::Type::kImport, source, "import"};
if (str == "in") if (str == "in")
return {Token::Type::kIn, source, "in"}; return {Token::Type::kIn, source, "in"};
if (str == "let")
return {Token::Type::kLet, source, "let"};
if (str == "loop") if (str == "loop")
return {Token::Type::kLoop, source, "loop"}; return {Token::Type::kLoop, source, "loop"};
if (str == "mat2x2") if (str == "mat2x2")
@ -709,8 +711,6 @@ Token Lexer::check_reserved(const Source& source, const std::string& str) {
return {Token::Type::kReservedKeyword, source, "i16"}; return {Token::Type::kReservedKeyword, source, "i16"};
if (str == "i64") if (str == "i64")
return {Token::Type::kReservedKeyword, source, "i64"}; return {Token::Type::kReservedKeyword, source, "i64"};
if (str == "let")
return {Token::Type::kReservedKeyword, source, "let"};
if (str == "premerge") if (str == "premerge")
return {Token::Type::kReservedKeyword, source, "premerge"}; return {Token::Type::kReservedKeyword, source, "premerge"};
if (str == "regardless") if (str == "regardless")

View File

@ -476,6 +476,7 @@ INSTANTIATE_TEST_SUITE_P(
TokenData{"image", Token::Type::kImage}, TokenData{"image", Token::Type::kImage},
TokenData{"import", Token::Type::kImport}, TokenData{"import", Token::Type::kImport},
TokenData{"in", Token::Type::kIn}, TokenData{"in", Token::Type::kIn},
TokenData{"let", Token::Type::kLet},
TokenData{"loop", Token::Type::kLoop}, TokenData{"loop", Token::Type::kLoop},
TokenData{"mat2x2", Token::Type::kMat2x2}, TokenData{"mat2x2", Token::Type::kMat2x2},
TokenData{"mat2x3", Token::Type::kMat2x3}, TokenData{"mat2x3", Token::Type::kMat2x3},
@ -547,7 +548,6 @@ INSTANTIATE_TEST_SUITE_P(LexerTest,
"i8", "i8",
"i16", "i16",
"i64", "i64",
"let",
"premerge", "premerge",
"typedef", "typedef",
"u8", "u8",

View File

@ -306,7 +306,7 @@ Expect<bool> ParserImpl::expect_global_decl() {
return Failure::kErrored; return Failure::kErrored;
if (gc.matched) { if (gc.matched) {
if (!expect("constant declaration", Token::Type::kSemicolon)) if (!expect("let declaration", Token::Type::kSemicolon))
return Failure::kErrored; return Failure::kErrored;
builder_.AST().AddGlobalVariable(gc.value); builder_.AST().AddGlobalVariable(gc.value);
@ -418,10 +418,17 @@ Maybe<ast::Variable*> ParserImpl::global_variable_decl(
// : variable_decoration_list* CONST variable_ident_decl EQUAL const_expr // : variable_decoration_list* CONST variable_ident_decl EQUAL const_expr
Maybe<ast::Variable*> ParserImpl::global_constant_decl( Maybe<ast::Variable*> ParserImpl::global_constant_decl(
ast::DecorationList& decos) { ast::DecorationList& decos) {
if (!match(Token::Type::kConst)) if (!match(Token::Type::kLet)) {
return Failure::kNoMatch; Source source;
if (match(Token::Type::kConst, &source)) {
// crbug.com/tint/699: 'const' renamed to 'let'
deprecated(source, "use 'let' instead of 'const'");
} else {
return Failure::kNoMatch;
}
}
const char* use = "constant declaration"; const char* use = "let declaration";
auto decl = expect_variable_ident_decl(use); auto decl = expect_variable_ident_decl(use);
if (decl.errored) if (decl.errored)
@ -1555,19 +1562,29 @@ Maybe<ast::ReturnStatement*> ParserImpl::return_stmt() {
// | variable_decl EQUAL logical_or_expression // | variable_decl EQUAL logical_or_expression
// | CONST variable_ident_decl EQUAL logical_or_expression // | CONST variable_ident_decl EQUAL logical_or_expression
Maybe<ast::VariableDeclStatement*> ParserImpl::variable_stmt() { Maybe<ast::VariableDeclStatement*> ParserImpl::variable_stmt() {
if (match(Token::Type::kConst)) { bool is_const = match(Token::Type::kLet);
auto decl = expect_variable_ident_decl("constant declaration"); if (!is_const) {
Source source;
if (match(Token::Type::kConst, &source)) {
// crbug.com/tint/699: 'const' renamed to 'let'
deprecated(source, "use 'let' instead of 'const'");
is_const = true;
}
}
if (is_const) {
auto decl = expect_variable_ident_decl("let declaration");
if (decl.errored) if (decl.errored)
return Failure::kErrored; return Failure::kErrored;
if (!expect("constant declaration", Token::Type::kEqual)) if (!expect("let declaration", Token::Type::kEqual))
return Failure::kErrored; return Failure::kErrored;
auto constructor = logical_or_expression(); auto constructor = logical_or_expression();
if (constructor.errored) if (constructor.errored)
return Failure::kErrored; return Failure::kErrored;
if (!constructor.matched) if (!constructor.matched)
return add_error(peek(), "missing constructor for const declaration"); return add_error(peek(), "missing constructor for let declaration");
auto* var = create<ast::Variable>( auto* var = create<ast::Variable>(
decl->source, // source decl->source, // source
@ -2746,7 +2763,7 @@ Expect<ast::ConstructorExpression*> ParserImpl::expect_const_expr() {
if (lit.errored) if (lit.errored)
return Failure::kErrored; return Failure::kErrored;
if (!lit.matched) if (!lit.matched)
return add_error(peek(), "unable to parse const literal"); return add_error(peek(), "unable to parse constant literal");
return create<ast::ScalarConstructorExpression>(source, lit.value); return create<ast::ScalarConstructorExpression>(source, lit.value);
} }

View File

@ -71,7 +71,7 @@ TEST_F(ParserImplTest, ConstExpr_TypeDecl_HangingComma) {
ASSERT_TRUE(p->has_error()); ASSERT_TRUE(p->has_error());
ASSERT_TRUE(e.errored); ASSERT_TRUE(e.errored);
ASSERT_EQ(e.value, nullptr); ASSERT_EQ(e.value, nullptr);
EXPECT_EQ(p->error(), "1:14: unable to parse const literal"); EXPECT_EQ(p->error(), "1:14: unable to parse constant literal");
} }
TEST_F(ParserImplTest, ConstExpr_TypeDecl_MissingComma) { TEST_F(ParserImplTest, ConstExpr_TypeDecl_MissingComma) {
@ -89,7 +89,7 @@ TEST_F(ParserImplTest, ConstExpr_MissingExpr) {
ASSERT_TRUE(p->has_error()); ASSERT_TRUE(p->has_error());
ASSERT_TRUE(e.errored); ASSERT_TRUE(e.errored);
ASSERT_EQ(e.value, nullptr); ASSERT_EQ(e.value, nullptr);
EXPECT_EQ(p->error(), "1:11: unable to parse const literal"); EXPECT_EQ(p->error(), "1:11: unable to parse constant literal");
} }
TEST_F(ParserImplTest, ConstExpr_InvalidExpr) { TEST_F(ParserImplTest, ConstExpr_InvalidExpr) {
@ -98,7 +98,7 @@ TEST_F(ParserImplTest, ConstExpr_InvalidExpr) {
ASSERT_TRUE(p->has_error()); ASSERT_TRUE(p->has_error());
ASSERT_TRUE(e.errored); ASSERT_TRUE(e.errored);
ASSERT_EQ(e.value, nullptr); ASSERT_EQ(e.value, nullptr);
EXPECT_EQ(p->error(), "1:15: unable to parse const literal"); EXPECT_EQ(p->error(), "1:15: unable to parse constant literal");
} }
TEST_F(ParserImplTest, ConstExpr_ConstLiteral) { TEST_F(ParserImplTest, ConstExpr_ConstLiteral) {

View File

@ -172,24 +172,24 @@ TEST_F(ParserImplErrorTest, ConstructorExprMissingRParen) {
} }
TEST_F(ParserImplErrorTest, ConstVarStmtInvalid) { TEST_F(ParserImplErrorTest, ConstVarStmtInvalid) {
EXPECT("fn f() { const >; }", EXPECT("fn f() { let >; }",
"test.wgsl:1:16 error: expected identifier for constant declaration\n" "test.wgsl:1:14 error: expected identifier for let declaration\n"
"fn f() { const >; }\n" "fn f() { let >; }\n"
" ^\n"); " ^\n");
} }
TEST_F(ParserImplErrorTest, ConstVarStmtMissingAssignment) { TEST_F(ParserImplErrorTest, ConstVarStmtMissingAssignment) {
EXPECT("fn f() { const a : i32; }", EXPECT("fn f() { let a : i32; }",
"test.wgsl:1:23 error: expected '=' for constant declaration\n" "test.wgsl:1:21 error: expected '=' for let declaration\n"
"fn f() { const a : i32; }\n" "fn f() { let a : i32; }\n"
" ^\n"); " ^\n");
} }
TEST_F(ParserImplErrorTest, ConstVarStmtMissingConstructor) { TEST_F(ParserImplErrorTest, ConstVarStmtMissingConstructor) {
EXPECT("fn f() { const a : i32 = >; }", EXPECT("fn f() { let a : i32 = >; }",
"test.wgsl:1:26 error: missing constructor for const declaration\n" "test.wgsl:1:24 error: missing constructor for let declaration\n"
"fn f() { const a : i32 = >; }\n" "fn f() { let a : i32 = >; }\n"
" ^\n"); " ^\n");
} }
TEST_F(ParserImplErrorTest, ContinueStmtMissingSemicolon) { TEST_F(ParserImplErrorTest, ContinueStmtMissingSemicolon) {
@ -468,7 +468,7 @@ TEST_F(ParserImplErrorTest, FunctionDeclMissingRBrace) {
} }
TEST_F(ParserImplErrorTest, FunctionMissingOpenLine) { TEST_F(ParserImplErrorTest, FunctionMissingOpenLine) {
EXPECT(R"(const bar : vec2<f32> = vec2<f32>(1., 2.); EXPECT(R"(let bar : vec2<f32> = vec2<f32>(1., 2.);
var a : f32 = bar[0]; var a : f32 = bar[0];
return; return;
})", })",
@ -482,45 +482,45 @@ TEST_F(ParserImplErrorTest, FunctionMissingOpenLine) {
} }
TEST_F(ParserImplErrorTest, GlobalDeclConstInvalidIdentifier) { TEST_F(ParserImplErrorTest, GlobalDeclConstInvalidIdentifier) {
EXPECT("const ^ : i32 = 1;", EXPECT("let ^ : i32 = 1;",
"test.wgsl:1:7 error: expected identifier for constant declaration\n" "test.wgsl:1:5 error: expected identifier for let declaration\n"
"const ^ : i32 = 1;\n" "let ^ : i32 = 1;\n"
" ^\n"); " ^\n");
} }
TEST_F(ParserImplErrorTest, GlobalDeclConstMissingSemicolon) { TEST_F(ParserImplErrorTest, GlobalDeclConstMissingSemicolon) {
EXPECT("const i : i32 = 1", EXPECT("let i : i32 = 1",
"test.wgsl:1:18 error: expected ';' for constant declaration\n" "test.wgsl:1:16 error: expected ';' for let declaration\n"
"const i : i32 = 1\n" "let i : i32 = 1\n"
" ^\n"); " ^\n");
} }
TEST_F(ParserImplErrorTest, GlobalDeclConstMissingLParen) { TEST_F(ParserImplErrorTest, GlobalDeclConstMissingLParen) {
EXPECT("const i : vec2<i32> = vec2<i32>;", EXPECT("let i : vec2<i32> = vec2<i32>;",
"test.wgsl:1:32 error: expected '(' for type constructor\n" "test.wgsl:1:30 error: expected '(' for type constructor\n"
"const i : vec2<i32> = vec2<i32>;\n" "let i : vec2<i32> = vec2<i32>;\n"
" ^\n"); " ^\n");
} }
TEST_F(ParserImplErrorTest, GlobalDeclConstMissingRParen) { TEST_F(ParserImplErrorTest, GlobalDeclConstMissingRParen) {
EXPECT("const i : vec2<i32> = vec2<i32>(1., 2.;", EXPECT("let i : vec2<i32> = vec2<i32>(1., 2.;",
"test.wgsl:1:39 error: expected ')' for type constructor\n" "test.wgsl:1:37 error: expected ')' for type constructor\n"
"const i : vec2<i32> = vec2<i32>(1., 2.;\n" "let i : vec2<i32> = vec2<i32>(1., 2.;\n"
" ^\n"); " ^\n");
} }
TEST_F(ParserImplErrorTest, GlobalDeclConstMissingAssignment) { TEST_F(ParserImplErrorTest, GlobalDeclConstMissingAssignment) {
EXPECT("const i : vec2<i32>;", EXPECT("let i : vec2<i32>;",
"test.wgsl:1:20 error: expected '=' for constant declaration\n" "test.wgsl:1:18 error: expected '=' for let declaration\n"
"const i : vec2<i32>;\n" "let i : vec2<i32>;\n"
" ^\n"); " ^\n");
} }
TEST_F(ParserImplErrorTest, GlobalDeclConstBadConstLiteral) { TEST_F(ParserImplErrorTest, GlobalDeclConstBadConstLiteral) {
EXPECT("const i : vec2<i32> = vec2<i32>(!);", EXPECT("let i : vec2<i32> = vec2<i32>(!);",
"test.wgsl:1:33 error: unable to parse const literal\n" "test.wgsl:1:31 error: unable to parse constant literal\n"
"const i : vec2<i32> = vec2<i32>(!);\n" "let i : vec2<i32> = vec2<i32>(!);\n"
" ^\n"); " ^\n");
} }
TEST_F(ParserImplErrorTest, GlobalDeclConstExprMaxDepth) { TEST_F(ParserImplErrorTest, GlobalDeclConstExprMaxDepth) {
@ -528,8 +528,8 @@ TEST_F(ParserImplErrorTest, GlobalDeclConstExprMaxDepth) {
std::stringstream src; std::stringstream src;
std::stringstream mkr; std::stringstream mkr;
src << "const i : i32 = "; src << "let i : i32 = ";
mkr << " "; mkr << " ";
for (size_t i = 0; i < kMaxDepth + 8; i++) { for (size_t i = 0; i < kMaxDepth + 8; i++) {
src << "f32("; src << "f32(";
if (i < kMaxDepth) { if (i < kMaxDepth) {
@ -544,24 +544,24 @@ TEST_F(ParserImplErrorTest, GlobalDeclConstExprMaxDepth) {
} }
src << ";"; src << ";";
std::stringstream err; std::stringstream err;
err << "test.wgsl:1:529 error: maximum parser recursive depth reached\n" err << "test.wgsl:1:527 error: maximum parser recursive depth reached\n"
<< src.str() << "\n" << src.str() << "\n"
<< mkr.str() << "\n"; << mkr.str() << "\n";
EXPECT(src.str().c_str(), err.str().c_str()); EXPECT(src.str().c_str(), err.str().c_str());
} }
TEST_F(ParserImplErrorTest, GlobalDeclConstExprMissingLParen) { TEST_F(ParserImplErrorTest, GlobalDeclConstExprMissingLParen) {
EXPECT("const i : vec2<i32> = vec2<i32> 1, 2);", EXPECT("let i : vec2<i32> = vec2<i32> 1, 2);",
"test.wgsl:1:33 error: expected '(' for type constructor\n" "test.wgsl:1:31 error: expected '(' for type constructor\n"
"const i : vec2<i32> = vec2<i32> 1, 2);\n" "let i : vec2<i32> = vec2<i32> 1, 2);\n"
" ^\n"); " ^\n");
} }
TEST_F(ParserImplErrorTest, GlobalDeclConstExprMissingRParen) { TEST_F(ParserImplErrorTest, GlobalDeclConstExprMissingRParen) {
EXPECT("const i : vec2<i32> = vec2<i32>(1, 2;", EXPECT("let i : vec2<i32> = vec2<i32>(1, 2;",
"test.wgsl:1:37 error: expected ')' for type constructor\n" "test.wgsl:1:35 error: expected ')' for type constructor\n"
"const i : vec2<i32> = vec2<i32>(1, 2;\n" "let i : vec2<i32> = vec2<i32>(1, 2;\n"
" ^\n"); " ^\n");
} }
TEST_F(ParserImplErrorTest, GlobalDeclSampledTextureMissingLessThan) { TEST_F(ParserImplErrorTest, GlobalDeclSampledTextureMissingLessThan) {

View File

@ -73,8 +73,8 @@ TEST_F(ForStmtTest, InitializerStatementDeclEqual) {
// Test a for loop declaring a const variable in the initializer statement. // Test a for loop declaring a const variable in the initializer statement.
TEST_F(ForStmtTest, InitializerStatementConstDecl) { TEST_F(ForStmtTest, InitializerStatementConstDecl) {
std::string for_str = "for (const i: i32 = 0 ;;) { }"; std::string for_str = "for (let i: i32 = 0 ;;) { }";
std::string loop_str = "{ const i: i32 = 0; loop { } }"; std::string loop_str = "{ let i: i32 = 0; loop { } }";
TestForLoop(loop_str, for_str); TestForLoop(loop_str, for_str);
} }
@ -215,8 +215,8 @@ TEST_F(ForStmtErrorTest, MissingRightBrace) {
// Test a for loop with an invalid initializer statement. // Test a for loop with an invalid initializer statement.
TEST_F(ForStmtErrorTest, InvalidInitializerAsConstDecl) { TEST_F(ForStmtErrorTest, InvalidInitializerAsConstDecl) {
std::string for_str = "for (const x: i32;;) { }"; std::string for_str = "for (let x: i32;;) { }";
std::string error_str = "1:18: expected '=' for constant declaration"; std::string error_str = "1:16: expected '=' for let declaration";
TestForWithError(for_str, error_str); TestForWithError(for_str, error_str);
} }
@ -266,8 +266,8 @@ TEST_F(ForStmtErrorTest, InvalidContinuingMatch) {
// Test a for loop with an invalid body. // Test a for loop with an invalid body.
TEST_F(ForStmtErrorTest, InvalidBody) { TEST_F(ForStmtErrorTest, InvalidBody) {
std::string for_str = "for (;;) { const x: i32; }"; std::string for_str = "for (;;) { let x: i32; }";
std::string error_str = "1:24: expected '=' for constant declaration"; std::string error_str = "1:22: expected '=' for let declaration";
TestForWithError(for_str, error_str); TestForWithError(for_str, error_str);
} }

View File

@ -20,7 +20,7 @@ namespace wgsl {
namespace { namespace {
TEST_F(ParserImplTest, GlobalConstantDecl) { TEST_F(ParserImplTest, GlobalConstantDecl) {
auto p = parser("const a : f32 = 1."); auto p = parser("let a : f32 = 1.");
auto decos = p->decoration_list(); auto decos = p->decoration_list();
EXPECT_FALSE(decos.errored); EXPECT_FALSE(decos.errored);
EXPECT_FALSE(decos.matched); EXPECT_FALSE(decos.matched);
@ -36,9 +36,9 @@ TEST_F(ParserImplTest, GlobalConstantDecl) {
EXPECT_TRUE(e->declared_type()->Is<type::F32>()); EXPECT_TRUE(e->declared_type()->Is<type::F32>());
EXPECT_EQ(e->source().range.begin.line, 1u); EXPECT_EQ(e->source().range.begin.line, 1u);
EXPECT_EQ(e->source().range.begin.column, 7u); EXPECT_EQ(e->source().range.begin.column, 5u);
EXPECT_EQ(e->source().range.end.line, 1u); EXPECT_EQ(e->source().range.end.line, 1u);
EXPECT_EQ(e->source().range.end.column, 8u); EXPECT_EQ(e->source().range.end.column, 6u);
ASSERT_NE(e->constructor(), nullptr); ASSERT_NE(e->constructor(), nullptr);
EXPECT_TRUE(e->constructor()->Is<ast::ConstructorExpression>()); EXPECT_TRUE(e->constructor()->Is<ast::ConstructorExpression>());
@ -47,7 +47,7 @@ TEST_F(ParserImplTest, GlobalConstantDecl) {
} }
TEST_F(ParserImplTest, GlobalConstantDecl_MissingEqual) { TEST_F(ParserImplTest, GlobalConstantDecl_MissingEqual) {
auto p = parser("const a: f32 1."); auto p = parser("let a : f32 1.");
auto decos = p->decoration_list(); auto decos = p->decoration_list();
EXPECT_FALSE(decos.errored); EXPECT_FALSE(decos.errored);
EXPECT_FALSE(decos.matched); EXPECT_FALSE(decos.matched);
@ -56,11 +56,11 @@ TEST_F(ParserImplTest, GlobalConstantDecl_MissingEqual) {
EXPECT_TRUE(e.errored); EXPECT_TRUE(e.errored);
EXPECT_FALSE(e.matched); EXPECT_FALSE(e.matched);
EXPECT_EQ(e.value, nullptr); EXPECT_EQ(e.value, nullptr);
EXPECT_EQ(p->error(), "1:14: expected '=' for constant declaration"); EXPECT_EQ(p->error(), "1:13: expected '=' for let declaration");
} }
TEST_F(ParserImplTest, GlobalConstantDecl_InvalidVariable) { TEST_F(ParserImplTest, GlobalConstantDecl_InvalidVariable) {
auto p = parser("const a: invalid = 1."); auto p = parser("let a : invalid = 1.");
auto decos = p->decoration_list(); auto decos = p->decoration_list();
EXPECT_FALSE(decos.errored); EXPECT_FALSE(decos.errored);
EXPECT_FALSE(decos.matched); EXPECT_FALSE(decos.matched);
@ -69,11 +69,11 @@ TEST_F(ParserImplTest, GlobalConstantDecl_InvalidVariable) {
EXPECT_TRUE(e.errored); EXPECT_TRUE(e.errored);
EXPECT_FALSE(e.matched); EXPECT_FALSE(e.matched);
EXPECT_EQ(e.value, nullptr); EXPECT_EQ(e.value, nullptr);
EXPECT_EQ(p->error(), "1:10: unknown constructed type 'invalid'"); EXPECT_EQ(p->error(), "1:9: unknown constructed type 'invalid'");
} }
TEST_F(ParserImplTest, GlobalConstantDecl_InvalidExpression) { TEST_F(ParserImplTest, GlobalConstantDecl_InvalidExpression) {
auto p = parser("const a: f32 = if (a) {}"); auto p = parser("let a : f32 = if (a) {}");
auto decos = p->decoration_list(); auto decos = p->decoration_list();
EXPECT_FALSE(decos.errored); EXPECT_FALSE(decos.errored);
EXPECT_FALSE(decos.matched); EXPECT_FALSE(decos.matched);
@ -82,11 +82,11 @@ TEST_F(ParserImplTest, GlobalConstantDecl_InvalidExpression) {
EXPECT_TRUE(e.errored); EXPECT_TRUE(e.errored);
EXPECT_FALSE(e.matched); EXPECT_FALSE(e.matched);
EXPECT_EQ(e.value, nullptr); EXPECT_EQ(e.value, nullptr);
EXPECT_EQ(p->error(), "1:16: unable to parse const literal"); EXPECT_EQ(p->error(), "1:15: unable to parse constant literal");
} }
TEST_F(ParserImplTest, GlobalConstantDecl_MissingExpression) { TEST_F(ParserImplTest, GlobalConstantDecl_MissingExpression) {
auto p = parser("const a: f32 ="); auto p = parser("let a : f32 =");
auto decos = p->decoration_list(); auto decos = p->decoration_list();
EXPECT_FALSE(decos.errored); EXPECT_FALSE(decos.errored);
EXPECT_FALSE(decos.matched); EXPECT_FALSE(decos.matched);
@ -95,11 +95,11 @@ TEST_F(ParserImplTest, GlobalConstantDecl_MissingExpression) {
EXPECT_TRUE(e.errored); EXPECT_TRUE(e.errored);
EXPECT_FALSE(e.matched); EXPECT_FALSE(e.matched);
EXPECT_EQ(e.value, nullptr); EXPECT_EQ(e.value, nullptr);
EXPECT_EQ(p->error(), "1:15: unable to parse const literal"); EXPECT_EQ(p->error(), "1:14: unable to parse constant literal");
} }
TEST_F(ParserImplTest, GlobalConstantDec_ConstantId) { TEST_F(ParserImplTest, GlobalConstantDec_ConstantId) {
auto p = parser("[[constant_id(7)]] const a : f32 = 1."); auto p = parser("[[constant_id(7)]] let a : f32 = 1.");
auto decos = p->decoration_list(); auto decos = p->decoration_list();
EXPECT_FALSE(decos.errored); EXPECT_FALSE(decos.errored);
EXPECT_TRUE(decos.matched); EXPECT_TRUE(decos.matched);
@ -116,9 +116,9 @@ TEST_F(ParserImplTest, GlobalConstantDec_ConstantId) {
EXPECT_TRUE(e->declared_type()->Is<type::F32>()); EXPECT_TRUE(e->declared_type()->Is<type::F32>());
EXPECT_EQ(e->source().range.begin.line, 1u); EXPECT_EQ(e->source().range.begin.line, 1u);
EXPECT_EQ(e->source().range.begin.column, 26u); EXPECT_EQ(e->source().range.begin.column, 24u);
EXPECT_EQ(e->source().range.end.line, 1u); EXPECT_EQ(e->source().range.end.line, 1u);
EXPECT_EQ(e->source().range.end.column, 27u); EXPECT_EQ(e->source().range.end.column, 25u);
ASSERT_NE(e->constructor(), nullptr); ASSERT_NE(e->constructor(), nullptr);
EXPECT_TRUE(e->constructor()->Is<ast::ConstructorExpression>()); EXPECT_TRUE(e->constructor()->Is<ast::ConstructorExpression>());
@ -128,7 +128,7 @@ TEST_F(ParserImplTest, GlobalConstantDec_ConstantId) {
} }
TEST_F(ParserImplTest, GlobalConstantDec_ConstantId_Missing) { TEST_F(ParserImplTest, GlobalConstantDec_ConstantId_Missing) {
auto p = parser("[[constant_id()]] const a : f32 = 1."); auto p = parser("[[constant_id()]] let a : f32 = 1.");
auto decos = p->decoration_list(); auto decos = p->decoration_list();
EXPECT_TRUE(decos.errored); EXPECT_TRUE(decos.errored);
EXPECT_FALSE(decos.matched); EXPECT_FALSE(decos.matched);
@ -144,7 +144,7 @@ TEST_F(ParserImplTest, GlobalConstantDec_ConstantId_Missing) {
} }
TEST_F(ParserImplTest, GlobalConstantDec_ConstantId_Invalid) { TEST_F(ParserImplTest, GlobalConstantDec_ConstantId_Invalid) {
auto p = parser("[[constant_id(-7)]] const a : f32 = 1."); auto p = parser("[[constant_id(-7)]] let a : f32 = 1.");
auto decos = p->decoration_list(); auto decos = p->decoration_list();
EXPECT_TRUE(decos.errored); EXPECT_TRUE(decos.errored);
EXPECT_FALSE(decos.matched); EXPECT_FALSE(decos.matched);
@ -158,6 +158,23 @@ TEST_F(ParserImplTest, GlobalConstantDec_ConstantId_Invalid) {
EXPECT_EQ(p->error(), "1:15: constant_id decoration must be positive"); EXPECT_EQ(p->error(), "1:15: constant_id decoration must be positive");
} }
TEST_F(ParserImplTest, GlobalConstantDec_ConstantId_Const) {
auto p = parser("const a : i32 = 1");
auto decos = p->decoration_list();
EXPECT_FALSE(decos.errored);
EXPECT_FALSE(decos.matched);
auto e = p->global_constant_decl(decos.value);
EXPECT_TRUE(e.matched);
EXPECT_FALSE(e.errored);
EXPECT_EQ(
p->builder().Diagnostics().str(),
R"(test.wgsl:1:1 warning: use of deprecated language feature: use 'let' instead of 'const'
const a : i32 = 1
^^^^^
)");
}
} // namespace } // namespace
} // namespace wgsl } // namespace wgsl
} // namespace reader } // namespace reader

View File

@ -52,7 +52,7 @@ TEST_F(ParserImplTest, GlobalDecl_GlobalVariable_MissingSemicolon) {
} }
TEST_F(ParserImplTest, GlobalDecl_GlobalConstant) { TEST_F(ParserImplTest, GlobalDecl_GlobalConstant) {
auto p = parser("const a : i32 = 2;"); auto p = parser("let a : i32 = 2;");
p->expect_global_decl(); p->expect_global_decl();
ASSERT_FALSE(p->has_error()) << p->error(); ASSERT_FALSE(p->has_error()) << p->error();
@ -64,17 +64,17 @@ TEST_F(ParserImplTest, GlobalDecl_GlobalConstant) {
} }
TEST_F(ParserImplTest, GlobalDecl_GlobalConstant_Invalid) { TEST_F(ParserImplTest, GlobalDecl_GlobalConstant_Invalid) {
auto p = parser("const a : vec2<i32>;"); auto p = parser("let a : vec2<i32>;");
p->expect_global_decl(); p->expect_global_decl();
ASSERT_TRUE(p->has_error()); ASSERT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:20: expected '=' for constant declaration"); EXPECT_EQ(p->error(), "1:18: expected '=' for let declaration");
} }
TEST_F(ParserImplTest, GlobalDecl_GlobalConstant_MissingSemicolon) { TEST_F(ParserImplTest, GlobalDecl_GlobalConstant_MissingSemicolon) {
auto p = parser("const a : vec2<i32> = vec2<i32>(1, 2)"); auto p = parser("let a : vec2<i32> = vec2<i32>(1, 2)");
p->expect_global_decl(); p->expect_global_decl();
ASSERT_TRUE(p->has_error()); ASSERT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:38: expected ';' for constant declaration"); EXPECT_EQ(p->error(), "1:36: expected ';' for let declaration");
} }
TEST_F(ParserImplTest, GlobalDecl_TypeAlias) { TEST_F(ParserImplTest, GlobalDecl_TypeAlias) {

View File

@ -152,7 +152,7 @@ TEST_F(ParserImplTest, GlobalVariableDecl_InvalidConstExpr) {
EXPECT_TRUE(e.errored); EXPECT_TRUE(e.errored);
EXPECT_FALSE(e.matched); EXPECT_FALSE(e.matched);
EXPECT_EQ(e.value, nullptr); EXPECT_EQ(e.value, nullptr);
EXPECT_EQ(p->error(), "1:20: unable to parse const literal"); EXPECT_EQ(p->error(), "1:20: unable to parse constant literal");
} }
TEST_F(ParserImplTest, GlobalVariableDecl_InvalidVariableDecl) { TEST_F(ParserImplTest, GlobalVariableDecl_InvalidVariableDecl) {

View File

@ -138,8 +138,8 @@ TEST_F(ParserImplTest, VariableStmt_VariableDecl_VecInit_NoSpace) {
EXPECT_TRUE(e->variable()->constructor()->Is<ast::ConstructorExpression>()); EXPECT_TRUE(e->variable()->constructor()->Is<ast::ConstructorExpression>());
} }
TEST_F(ParserImplTest, VariableStmt_Const) { TEST_F(ParserImplTest, VariableStmt_Let) {
auto p = parser("const a : i32 = 1"); auto p = parser("let a : i32 = 1");
auto e = p->variable_stmt(); auto e = p->variable_stmt();
EXPECT_TRUE(e.matched); EXPECT_TRUE(e.matched);
EXPECT_FALSE(e.errored); EXPECT_FALSE(e.errored);
@ -148,49 +148,62 @@ TEST_F(ParserImplTest, VariableStmt_Const) {
ASSERT_TRUE(e->Is<ast::VariableDeclStatement>()); ASSERT_TRUE(e->Is<ast::VariableDeclStatement>());
ASSERT_EQ(e->source().range.begin.line, 1u); ASSERT_EQ(e->source().range.begin.line, 1u);
ASSERT_EQ(e->source().range.begin.column, 7u); ASSERT_EQ(e->source().range.begin.column, 5u);
ASSERT_EQ(e->source().range.end.line, 1u); ASSERT_EQ(e->source().range.end.line, 1u);
ASSERT_EQ(e->source().range.end.column, 8u); ASSERT_EQ(e->source().range.end.column, 6u);
} }
TEST_F(ParserImplTest, VariableStmt_Const_InvalidVarIdent) { TEST_F(ParserImplTest, VariableStmt_Let_InvalidVarIdent) {
auto p = parser("const a : invalid = 1"); auto p = parser("let a : invalid = 1");
auto e = p->variable_stmt(); auto e = p->variable_stmt();
EXPECT_FALSE(e.matched); EXPECT_FALSE(e.matched);
EXPECT_TRUE(e.errored); EXPECT_TRUE(e.errored);
EXPECT_EQ(e.value, nullptr); EXPECT_EQ(e.value, nullptr);
EXPECT_TRUE(p->has_error()); EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:11: unknown constructed type 'invalid'"); EXPECT_EQ(p->error(), "1:9: unknown constructed type 'invalid'");
} }
TEST_F(ParserImplTest, VariableStmt_Const_MissingEqual) { TEST_F(ParserImplTest, VariableStmt_Let_MissingEqual) {
auto p = parser("const a : i32 1"); auto p = parser("let a : i32 1");
auto e = p->variable_stmt(); auto e = p->variable_stmt();
EXPECT_FALSE(e.matched); EXPECT_FALSE(e.matched);
EXPECT_TRUE(e.errored); EXPECT_TRUE(e.errored);
EXPECT_EQ(e.value, nullptr); EXPECT_EQ(e.value, nullptr);
EXPECT_TRUE(p->has_error()); EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:15: expected '=' for constant declaration"); EXPECT_EQ(p->error(), "1:13: expected '=' for let declaration");
} }
TEST_F(ParserImplTest, VariableStmt_Const_MissingConstructor) { TEST_F(ParserImplTest, VariableStmt_Let_MissingConstructor) {
auto p = parser("const a : i32 ="); auto p = parser("let a : i32 =");
auto e = p->variable_stmt(); auto e = p->variable_stmt();
EXPECT_FALSE(e.matched); EXPECT_FALSE(e.matched);
EXPECT_TRUE(e.errored); EXPECT_TRUE(e.errored);
EXPECT_EQ(e.value, nullptr); EXPECT_EQ(e.value, nullptr);
EXPECT_TRUE(p->has_error()); EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:16: missing constructor for const declaration"); EXPECT_EQ(p->error(), "1:14: missing constructor for let declaration");
} }
TEST_F(ParserImplTest, VariableStmt_Const_InvalidConstructor) { TEST_F(ParserImplTest, VariableStmt_Let_InvalidConstructor) {
auto p = parser("const a : i32 = if (a) {}"); auto p = parser("let a : i32 = if (a) {}");
auto e = p->variable_stmt(); auto e = p->variable_stmt();
EXPECT_FALSE(e.matched); EXPECT_FALSE(e.matched);
EXPECT_TRUE(e.errored); EXPECT_TRUE(e.errored);
EXPECT_EQ(e.value, nullptr); EXPECT_EQ(e.value, nullptr);
EXPECT_TRUE(p->has_error()); EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:17: missing constructor for const declaration"); EXPECT_EQ(p->error(), "1:15: missing constructor for let declaration");
}
TEST_F(ParserImplTest, VariableStmt_Const) {
auto p = parser("const a : i32 = 1");
auto e = p->variable_stmt();
EXPECT_TRUE(e.matched);
EXPECT_FALSE(e.errored);
EXPECT_EQ(
p->builder().Diagnostics().str(),
R"(test.wgsl:1:1 warning: use of deprecated language feature: use 'let' instead of 'const'
const a : i32 = 1
^^^^^
)");
} }
} // namespace } // namespace

View File

@ -221,6 +221,8 @@ std::string Token::TypeToName(Type type) {
return "import"; return "import";
case Token::Type::kIn: case Token::Type::kIn:
return "in"; return "in";
case Token::Type::kLet:
return "let";
case Token::Type::kLoop: case Token::Type::kLoop:
return "loop"; return "loop";
case Token::Type::kMat2x2: case Token::Type::kMat2x2:

View File

@ -229,6 +229,8 @@ class Token {
kImport, kImport,
/// A 'in' /// A 'in'
kIn, kIn,
/// A 'let'
kLet,
/// A 'loop' /// A 'loop'
kLoop, kLoop,
/// A 'mat2x2' /// A 'mat2x2'
@ -574,6 +576,8 @@ class Token {
bool IsImport() const { return type_ == Type::kImport; } bool IsImport() const { return type_ == Type::kImport; }
/// @returns true if token is a 'in' /// @returns true if token is a 'in'
bool IsIn() const { return type_ == Type::kIn; } bool IsIn() const { return type_ == Type::kIn; }
/// @returns true if token is a 'let'
bool IsLet() const { return type_ == Type::kLet; }
/// @returns true if token is a 'loop' /// @returns true if token is a 'loop'
bool IsLoop() const { return type_ == Type::kLoop; } bool IsLoop() const { return type_ == Type::kLoop; }
/// @returns true if token is a 'mat2x2' /// @returns true if token is a 'mat2x2'

View File

@ -48,7 +48,7 @@ TEST_F(ResolverAssignmentValidationTest, AssignIncompatibleTypes) {
TEST_F(ResolverAssignmentValidationTest, TEST_F(ResolverAssignmentValidationTest,
AssignThroughPointerWrongeStoreType_Fail) { AssignThroughPointerWrongeStoreType_Fail) {
// var a : f32; // var a : f32;
// const b : ptr<function,f32> = a; // let b : ptr<function,f32> = a;
// b = 2; // b = 2;
const auto priv = ast::StorageClass::kFunction; const auto priv = ast::StorageClass::kFunction;
auto* var_a = Var("a", ty.f32(), priv); auto* var_a = Var("a", ty.f32(), priv);
@ -211,7 +211,7 @@ TEST_F(ResolverAssignmentValidationTest,
TEST_F(ResolverAssignmentValidationTest, AssignThroughPointer_Pass) { TEST_F(ResolverAssignmentValidationTest, AssignThroughPointer_Pass) {
// var a :i32; // var a :i32;
// const b : ptr<function,i32> = a; // let b : ptr<function,i32> = a;
// b = 2; // b = 2;
const auto func = ast::StorageClass::kFunction; const auto func = ast::StorageClass::kFunction;
auto* var_a = Var("a", ty.i32(), func, Expr(2), {}); auto* var_a = Var("a", ty.i32(), func, Expr(2), {});
@ -229,7 +229,7 @@ TEST_F(ResolverAssignmentValidationTest, AssignThroughPointer_Pass) {
TEST_F(ResolverAssignmentValidationTest, AssignToConstant_Fail) { TEST_F(ResolverAssignmentValidationTest, AssignToConstant_Fail) {
// { // {
// const a :i32 = 2; // let a : i32 = 2;
// a = 2 // a = 2
// } // }
auto* var = Const("a", ty.i32(), Expr(2)); auto* var = Const("a", ty.i32(), Expr(2));

View File

@ -259,7 +259,7 @@ TEST_F(ResolverFunctionValidationTest, FunctionVarInitWithParam) {
TEST_F(ResolverFunctionValidationTest, FunctionConstInitWithParam) { TEST_F(ResolverFunctionValidationTest, FunctionConstInitWithParam) {
// fn foo(bar : f32){ // fn foo(bar : f32){
// const baz : f32 = bar; // let baz : f32 = bar;
// } // }
auto* bar = Var("bar", ty.f32(), ast::StorageClass::kFunction); auto* bar = Var("bar", ty.f32(), ast::StorageClass::kFunction);

View File

@ -78,7 +78,7 @@ TEST_F(ResolverTypeValidationTest, GlobalConstantWithStorageClass_Fail) {
} }
TEST_F(ResolverTypeValidationTest, GlobalConstNoStorageClass_Pass) { TEST_F(ResolverTypeValidationTest, GlobalConstNoStorageClass_Pass) {
// const global_var: f32; // let global_var: f32;
GlobalConst(Source{{12, 34}}, "global_var", ty.f32()); GlobalConst(Source{{12, 34}}, "global_var", ty.f32());
EXPECT_TRUE(r()->Resolve()) << r()->error(); EXPECT_TRUE(r()->Resolve()) << r()->error();

View File

@ -26,20 +26,20 @@ TEST_F(BoundArrayAccessorsTest, Ptrs_Clamp) {
auto* src = R"( auto* src = R"(
var<storage> a : array<f32, 3>; var<storage> a : array<f32, 3>;
const c : u32 = 1u; let c : u32 = 1u;
fn f() { fn f() {
const b : ptr<storage, f32> = a[c]; let b : ptr<storage, f32> = a[c];
} }
)"; )";
auto* expect = R"( auto* expect = R"(
var<storage> a : array<f32, 3>; var<storage> a : array<f32, 3>;
const c : u32 = 1u; let c : u32 = 1u;
fn f() { fn f() {
const b : ptr<storage, f32> = a[min(u32(c), 2u)]; let b : ptr<storage, f32> = a[min(u32(c), 2u)];
} }
)"; )";
@ -499,7 +499,7 @@ fn f() {
// TODO(dsinclair): Implement when constant_id exists // TODO(dsinclair): Implement when constant_id exists
TEST_F(BoundArrayAccessorsTest, DISABLED_Vector_Constant_Id_Clamps) { TEST_F(BoundArrayAccessorsTest, DISABLED_Vector_Constant_Id_Clamps) {
// [[constant_id(1300)]] const idx : i32; // [[constant_id(1300)]] let idx : i32;
// var a : vec3<f32> // var a : vec3<f32>
// var b : f32 = a[idx] // var b : f32 = a[idx]
// //
@ -508,7 +508,7 @@ TEST_F(BoundArrayAccessorsTest, DISABLED_Vector_Constant_Id_Clamps) {
// TODO(dsinclair): Implement when constant_id exists // TODO(dsinclair): Implement when constant_id exists
TEST_F(BoundArrayAccessorsTest, DISABLED_Array_Constant_Id_Clamps) { TEST_F(BoundArrayAccessorsTest, DISABLED_Array_Constant_Id_Clamps) {
// [[constant_id(1300)]] const idx : i32; // [[constant_id(1300)]] let idx : i32;
// var a : array<f32, 4> // var a : array<f32, 4>
// var b : f32 = a[idx] // var b : f32 = a[idx]
// //
@ -517,7 +517,7 @@ TEST_F(BoundArrayAccessorsTest, DISABLED_Array_Constant_Id_Clamps) {
// TODO(dsinclair): Implement when constant_id exists // TODO(dsinclair): Implement when constant_id exists
TEST_F(BoundArrayAccessorsTest, DISABLED_Matrix_Column_Constant_Id_Clamps) { TEST_F(BoundArrayAccessorsTest, DISABLED_Matrix_Column_Constant_Id_Clamps) {
// [[constant_id(1300)]] const idx : i32; // [[constant_id(1300)]] let idx : i32;
// var a : mat3x2<f32> // var a : mat3x2<f32>
// var b : f32 = a[idx][1] // var b : f32 = a[idx][1]
// //
@ -526,7 +526,7 @@ TEST_F(BoundArrayAccessorsTest, DISABLED_Matrix_Column_Constant_Id_Clamps) {
// TODO(dsinclair): Implement when constant_id exists // TODO(dsinclair): Implement when constant_id exists
TEST_F(BoundArrayAccessorsTest, DISABLED_Matrix_Row_Constant_Id_Clamps) { TEST_F(BoundArrayAccessorsTest, DISABLED_Matrix_Row_Constant_Id_Clamps) {
// [[constant_id(1300)]] const idx : i32; // [[constant_id(1300)]] let idx : i32;
// var a : mat3x2<f32> // var a : mat3x2<f32>
// var b : f32 = a[1][idx] // var b : f32 = a[1][idx]
// //

View File

@ -44,9 +44,9 @@ struct tint_symbol_5 {
[[stage(fragment)]] [[stage(fragment)]]
fn frag_main(tint_symbol_1 : tint_symbol_5) { fn frag_main(tint_symbol_1 : tint_symbol_5) {
const coord : vec4<f32> = tint_symbol_1.coord; let coord : vec4<f32> = tint_symbol_1.coord;
const loc1 : f32 = tint_symbol_1.loc1; let loc1 : f32 = tint_symbol_1.loc1;
const loc2 : vec4<u32> = tint_symbol_1.loc2; let loc2 : vec4<u32> = tint_symbol_1.loc2;
var col : f32 = (coord.x * loc1); var col : f32 = (coord.x * loc1);
} }
)"; )";
@ -76,7 +76,7 @@ struct tint_symbol_4 {
[[stage(fragment)]] [[stage(fragment)]]
fn frag_main(tint_symbol_1 : tint_symbol_4) { fn frag_main(tint_symbol_1 : tint_symbol_4) {
const loc1 : myf32 = tint_symbol_1.loc1; let loc1 : myf32 = tint_symbol_1.loc1;
var x : myf32 = loc1; var x : myf32 = loc1;
} }
)"; )";
@ -156,9 +156,9 @@ struct tint_symbol_10 {
[[stage(fragment)]] [[stage(fragment)]]
fn frag_main(tint_symbol_6 : tint_symbol_10) { fn frag_main(tint_symbol_6 : tint_symbol_10) {
const builtins : FragBuiltins = FragBuiltins(tint_symbol_6.coord); let builtins : FragBuiltins = FragBuiltins(tint_symbol_6.coord);
const locations : FragLocations = FragLocations(tint_symbol_6.loc1, tint_symbol_6.loc2); let locations : FragLocations = FragLocations(tint_symbol_6.loc1, tint_symbol_6.loc2);
const loc0 : f32 = tint_symbol_6.loc0; let loc0 : f32 = tint_symbol_6.loc0;
var col : f32 = ((builtins.coord.x * locations.loc1) + loc0); var col : f32 = ((builtins.coord.x * locations.loc1) + loc0);
} }
)"; )";
@ -283,7 +283,7 @@ struct tint_symbol_6 {
[[stage(fragment)]] [[stage(fragment)]]
fn frag_main1(tint_symbol_4 : tint_symbol_6) { fn frag_main1(tint_symbol_4 : tint_symbol_6) {
const inputs : FragmentInput = FragmentInput(tint_symbol_4.value, tint_symbol_4.mul); let inputs : FragmentInput = FragmentInput(tint_symbol_4.value, tint_symbol_4.mul);
var x : f32 = foo(inputs); var x : f32 = foo(inputs);
} }
@ -296,7 +296,7 @@ struct tint_symbol_11 {
[[stage(fragment)]] [[stage(fragment)]]
fn frag_main2(tint_symbol_10 : tint_symbol_11) { fn frag_main2(tint_symbol_10 : tint_symbol_11) {
const inputs : FragmentInput = FragmentInput(tint_symbol_10.value, tint_symbol_10.mul); let inputs : FragmentInput = FragmentInput(tint_symbol_10.value, tint_symbol_10.mul);
var x : f32 = foo(inputs); var x : f32 = foo(inputs);
} }
)"; )";
@ -356,7 +356,7 @@ struct tint_symbol_6 {
[[stage(fragment)]] [[stage(fragment)]]
fn frag_main1(tint_symbol_4 : tint_symbol_6) { fn frag_main1(tint_symbol_4 : tint_symbol_6) {
const inputs : FragmentInput = FragmentInput(tint_symbol_4.col1, tint_symbol_4.col2); let inputs : FragmentInput = FragmentInput(tint_symbol_4.col1, tint_symbol_4.col2);
global_inputs = inputs; global_inputs = inputs;
var r : f32 = foo(); var r : f32 = foo();
var g : f32 = bar(); var g : f32 = bar();
@ -434,9 +434,9 @@ struct tint_symbol_10 {
[[stage(fragment)]] [[stage(fragment)]]
fn frag_main(tint_symbol_6 : tint_symbol_9) -> tint_symbol_10 { fn frag_main(tint_symbol_6 : tint_symbol_9) -> tint_symbol_10 {
const inputs : MyFragmentInput = MyFragmentInput(tint_symbol_6.col1, tint_symbol_6.col2); let inputs : MyFragmentInput = MyFragmentInput(tint_symbol_6.col1, tint_symbol_6.col2);
var x : myf32 = foo(inputs); var x : myf32 = foo(inputs);
const tint_symbol_13 : FragmentOutput = MyFragmentOutput(x, inputs.col2); let tint_symbol_13 : FragmentOutput = MyFragmentOutput(x, inputs.col2);
return tint_symbol_10(tint_symbol_13.col1, tint_symbol_13.col2); return tint_symbol_10(tint_symbol_13.col1, tint_symbol_13.col2);
} }
)"; )";
@ -492,8 +492,8 @@ struct tint_symbol_8 {
[[stage(fragment)]] [[stage(fragment)]]
fn frag_main(tint_symbol_5 : tint_symbol_7) -> tint_symbol_8 { fn frag_main(tint_symbol_5 : tint_symbol_7) -> tint_symbol_8 {
const inputs : FragmentInput = FragmentInput(tint_symbol_5.value, tint_symbol_5.coord); let inputs : FragmentInput = FragmentInput(tint_symbol_5.value, tint_symbol_5.coord);
const tint_symbol_10 : FragmentOutput = FragmentOutput((inputs.coord.x * inputs.value)); let tint_symbol_10 : FragmentOutput = FragmentOutput((inputs.coord.x * inputs.value));
return tint_symbol_8(tint_symbol_10.value); return tint_symbol_8(tint_symbol_10.value);
} }
)"; )";

View File

@ -102,7 +102,7 @@ struct TintFirstIndexOffsetData {
[[builtin(vertex_index)]] var<in> tint_first_index_offset_vert_idx : u32; [[builtin(vertex_index)]] var<in> tint_first_index_offset_vert_idx : u32;
fn test() -> u32 { fn test() -> u32 {
const vert_idx : u32 = (tint_first_index_offset_vert_idx + tint_first_index_data.tint_first_vertex_index); let vert_idx : u32 = (tint_first_index_offset_vert_idx + tint_first_index_data.tint_first_vertex_index);
return vert_idx; return vert_idx;
} }
@ -150,7 +150,7 @@ struct TintFirstIndexOffsetData {
[[builtin(instance_index)]] var<in> tint_first_index_offset_inst_idx : u32; [[builtin(instance_index)]] var<in> tint_first_index_offset_inst_idx : u32;
fn test() -> u32 { fn test() -> u32 {
const inst_idx : u32 = (tint_first_index_offset_inst_idx + tint_first_index_data.tint_first_instance_index); let inst_idx : u32 = (tint_first_index_offset_inst_idx + tint_first_index_data.tint_first_instance_index);
return inst_idx; return inst_idx;
} }
@ -202,8 +202,8 @@ struct TintFirstIndexOffsetData {
[[builtin(vertex_index)]] var<in> tint_first_index_offset_vert_idx : u32; [[builtin(vertex_index)]] var<in> tint_first_index_offset_vert_idx : u32;
fn test() -> u32 { fn test() -> u32 {
const instance_idx : u32 = (tint_first_index_offset_instance_idx + tint_first_index_data.tint_first_instance_index); let instance_idx : u32 = (tint_first_index_offset_instance_idx + tint_first_index_data.tint_first_instance_index);
const vert_idx : u32 = (tint_first_index_offset_vert_idx + tint_first_index_data.tint_first_vertex_index); let vert_idx : u32 = (tint_first_index_offset_vert_idx + tint_first_index_data.tint_first_vertex_index);
return (instance_idx + vert_idx); return (instance_idx + vert_idx);
} }
@ -255,7 +255,7 @@ struct TintFirstIndexOffsetData {
[[builtin(vertex_index)]] var<in> tint_first_index_offset_vert_idx : u32; [[builtin(vertex_index)]] var<in> tint_first_index_offset_vert_idx : u32;
fn func1() -> u32 { fn func1() -> u32 {
const vert_idx : u32 = (tint_first_index_offset_vert_idx + tint_first_index_data.tint_first_vertex_index); let vert_idx : u32 = (tint_first_index_offset_vert_idx + tint_first_index_data.tint_first_vertex_index);
return vert_idx; return vert_idx;
} }

View File

@ -41,7 +41,7 @@ fn main() {
var f1 : f32 = 2.0; var f1 : f32 = 2.0;
var f2 : f32 = 3.0; var f2 : f32 = 3.0;
var f3 : f32 = 4.0; var f3 : f32 = 4.0;
const tint_symbol_1 : array<f32, 4> = array<f32, 4>(f0, f1, f2, f3); let tint_symbol_1 : array<f32, 4> = array<f32, 4>(f0, f1, f2, f3);
var i : f32 = tint_symbol_1[2]; var i : f32 = tint_symbol_1[2];
} }
)"; )";
@ -74,7 +74,7 @@ struct S {
[[stage(vertex)]] [[stage(vertex)]]
fn main() { fn main() {
const tint_symbol_1 : S = S(1, 2.0, vec3<f32>()); let tint_symbol_1 : S = S(1, 2.0, vec3<f32>());
var x : f32 = tint_symbol_1.b; var x : f32 = tint_symbol_1.b;
} }
)"; )";
@ -95,9 +95,9 @@ fn main() {
auto* expect = R"( auto* expect = R"(
[[stage(vertex)]] [[stage(vertex)]]
fn main() { fn main() {
const tint_symbol_1 : array<f32, 2> = array<f32, 2>(1.0, 2.0); let tint_symbol_1 : array<f32, 2> = array<f32, 2>(1.0, 2.0);
const tint_symbol_2 : array<f32, 2> = array<f32, 2>(3.0, 4.0); let tint_symbol_2 : array<f32, 2> = array<f32, 2>(3.0, 4.0);
const tint_symbol_3 : array<array<f32, 2>, 2> = array<array<f32, 2>, 2>(tint_symbol_1, tint_symbol_2); let tint_symbol_3 : array<array<f32, 2>, 2> = array<array<f32, 2>, 2>(tint_symbol_1, tint_symbol_2);
var i : f32 = tint_symbol_3[0][1]; var i : f32 = tint_symbol_3[0][1];
} }
)"; )";
@ -146,9 +146,9 @@ struct S3 {
[[stage(vertex)]] [[stage(vertex)]]
fn main() { fn main() {
const tint_symbol_1 : S1 = S1(2); let tint_symbol_1 : S1 = S1(2);
const tint_symbol_4 : S2 = S2(1, tint_symbol_1, 3); let tint_symbol_4 : S2 = S2(1, tint_symbol_1, 3);
const tint_symbol_8 : S3 = S3(tint_symbol_4); let tint_symbol_8 : S3 = S3(tint_symbol_4);
var x : i32 = tint_symbol_8.a.b.a; var x : i32 = tint_symbol_8.a.b.a;
} }
)"; )";
@ -185,11 +185,11 @@ struct S2 {
[[stage(vertex)]] [[stage(vertex)]]
fn main() { fn main() {
const tint_symbol_1 : S1 = S1(1); let tint_symbol_1 : S1 = S1(1);
const tint_symbol_4 : S1 = S1(2); let tint_symbol_4 : S1 = S1(2);
const tint_symbol_5 : S1 = S1(3); let tint_symbol_5 : S1 = S1(3);
const tint_symbol_6 : array<S1, 3> = array<S1, 3>(tint_symbol_1, tint_symbol_4, tint_symbol_5); let tint_symbol_6 : array<S1, 3> = array<S1, 3>(tint_symbol_1, tint_symbol_4, tint_symbol_5);
const tint_symbol_7 : S2 = S2(tint_symbol_6); let tint_symbol_7 : S2 = S2(tint_symbol_6);
var x : i32 = tint_symbol_7.a[1].a; var x : i32 = tint_symbol_7.a[1].a;
} }
)"; )";
@ -213,9 +213,9 @@ fn main() {
var local_str : S = S(1, 2.0, 3); var local_str : S = S(1, 2.0, 3);
} }
const module_arr : array<f32, 4> = array<f32, 4>(0.0, 1.0, 2.0, 3.0); let module_arr : array<f32, 4> = array<f32, 4>(0.0, 1.0, 2.0, 3.0);
const module_str : S = S(1, 2.0, 3); let module_str : S = S(1, 2.0, 3);
)"; )";
auto* expect = src; auto* expect = src;
@ -241,7 +241,7 @@ struct Uniforms {
[[stage(vertex)]] [[stage(vertex)]]
fn main() { fn main() {
const transform : mat2x2<f32> = ubo.transform; let transform : mat2x2<f32> = ubo.transform;
var coord : vec2<f32> = array<vec2<f32>, 3>( var coord : vec2<f32> = array<vec2<f32>, 3>(
vec2<f32>(-1.0, 1.0), vec2<f32>(-1.0, 1.0),
vec2<f32>( 1.0, 1.0), vec2<f32>( 1.0, 1.0),
@ -265,8 +265,8 @@ struct Uniforms {
[[stage(vertex)]] [[stage(vertex)]]
fn main() { fn main() {
const transform : mat2x2<f32> = ubo.transform; let transform : mat2x2<f32> = ubo.transform;
const tint_symbol_1 : array<vec2<f32>, 3> = array<vec2<f32>, 3>(vec2<f32>(-1.0, 1.0), vec2<f32>(1.0, 1.0), vec2<f32>(-1.0, -1.0)); let tint_symbol_1 : array<vec2<f32>, 3> = array<vec2<f32>, 3>(vec2<f32>(-1.0, 1.0), vec2<f32>(1.0, 1.0), vec2<f32>(-1.0, -1.0));
var coord : vec2<f32> = tint_symbol_1[vertex_index]; var coord : vec2<f32> = tint_symbol_1[vertex_index];
position = vec4<f32>((transform * coord), 0.0, 1.0); position = vec4<f32>((transform * coord), 0.0, 1.0);
} }

View File

@ -101,7 +101,7 @@ void Spirv::HandleEntryPointIOTypes(CloneContext& ctx) const {
// //
// [[stage(fragment)]] // [[stage(fragment)]]
// fn frag_main() { // fn frag_main() {
// const samples : FragmentInput(sample_index, sample_mask_in); // let samples : FragmentInput(sample_index, sample_mask_in);
// var output : FragmentOutput = FragmentOutput(1.0, // var output : FragmentOutput = FragmentOutput(1.0,
// samples.sample_mask_in); // samples.sample_mask_in);
// frag_main_ret(output); // frag_main_ret(output);

View File

@ -214,7 +214,7 @@ struct FragmentInput {
[[stage(fragment)]] [[stage(fragment)]]
fn frag_main() { fn frag_main() {
const tint_symbol_7 : FragmentInput = FragmentInput(tint_symbol_4, tint_symbol_5); let tint_symbol_7 : FragmentInput = FragmentInput(tint_symbol_4, tint_symbol_5);
var col : f32 = (tint_symbol_7.coord.x * tint_symbol_7.value); var col : f32 = (tint_symbol_7.coord.x * tint_symbol_7.value);
} }
)"; )";
@ -328,7 +328,7 @@ fn tint_symbol_5(tint_symbol_6 : Interface) {
[[stage(vertex)]] [[stage(vertex)]]
fn vert_main() { fn vert_main() {
const tint_symbol_8 : Interface = Interface(tint_symbol_3); let tint_symbol_8 : Interface = Interface(tint_symbol_3);
tint_symbol_5(tint_symbol_8); tint_symbol_5(tint_symbol_8);
return; return;
} }
@ -377,7 +377,7 @@ fn vert_main() {
[[stage(fragment)]] [[stage(fragment)]]
fn frag_main() { fn frag_main() {
const tint_symbol_9 : Interface = Interface(tint_symbol_7); let tint_symbol_9 : Interface = Interface(tint_symbol_7);
var x : f32 = tint_symbol_9.value; var x : f32 = tint_symbol_9.value;
} }
)"; )";
@ -431,7 +431,7 @@ fn tint_symbol_8(tint_symbol_9 : FragmentOutput) {
[[stage(fragment)]] [[stage(fragment)]]
fn frag_main() { fn frag_main() {
const tint_symbol_11 : FragmentInput = FragmentInput(tint_symbol_5, tint_symbol_6); let tint_symbol_11 : FragmentInput = FragmentInput(tint_symbol_5, tint_symbol_6);
tint_symbol_8(FragmentOutput((tint_symbol_11.coord.x * tint_symbol_11.value))); tint_symbol_8(FragmentOutput((tint_symbol_11.coord.x * tint_symbol_11.value)));
return; return;
} }

View File

@ -304,7 +304,7 @@ TEST_F(BuilderTest, MemberAccessor_NonPointer) {
// a : f32 // a : f32
// b : f32 // b : f32
// } // }
// const ident : my_struct = my_struct(); // let ident : my_struct = my_struct();
// ident.b // ident.b
auto* s = Structure("my_struct", { auto* s = Structure("my_struct", {
@ -343,7 +343,7 @@ TEST_F(BuilderTest, MemberAccessor_Nested_NonPointer) {
// inner : inner_struct // inner : inner_struct
// } // }
// //
// const ident : my_struct = my_struct(); // let ident : my_struct = my_struct();
// ident.inner.a // ident.inner.a
auto* inner_struct = Structure("Inner", { auto* inner_struct = Structure("Inner", {
Member("a", ty.f32()), Member("a", ty.f32()),
@ -748,7 +748,7 @@ TEST_F(BuilderTest, Accessor_Mixed_ArrayAndMember) {
} }
TEST_F(BuilderTest, Accessor_Array_Of_Vec) { TEST_F(BuilderTest, Accessor_Array_Of_Vec) {
// const pos : array<vec2<f32>, 3> = array<vec2<f32>, 3>( // let pos : array<vec2<f32>, 3> = array<vec2<f32>, 3>(
// vec2<f32>(0.0, 0.5), // vec2<f32>(0.0, 0.5),
// vec2<f32>(-0.5, -0.5), // vec2<f32>(-0.5, -0.5),
// vec2<f32>(0.5, -0.5)); // vec2<f32>(0.5, -0.5));
@ -797,7 +797,7 @@ TEST_F(BuilderTest, Accessor_Array_Of_Vec) {
} }
TEST_F(BuilderTest, Accessor_Const_Vec) { TEST_F(BuilderTest, Accessor_Const_Vec) {
// const pos : vec2<f32> = vec2<f32>(0.0, 0.5); // let pos : vec2<f32> = vec2<f32>(0.0, 0.5);
// pos[1] // pos[1]
auto* var = GlobalConst("pos", ty.vec2<f32>(), vec2<f32>(0.0f, 0.5f)); auto* var = GlobalConst("pos", ty.vec2<f32>(), vec2<f32>(0.0f, 0.5f));
@ -826,7 +826,7 @@ TEST_F(BuilderTest, Accessor_Const_Vec) {
} }
TEST_F(BuilderTest, DISABLED_Accessor_Array_NonPointer) { TEST_F(BuilderTest, DISABLED_Accessor_Array_NonPointer) {
// const a : array<f32, 3>; // let a : array<f32, 3>;
// a[2] // a[2]
// //
// This has to generate an OpConstantExtract and will need to read the 3 value // This has to generate an OpConstantExtract and will need to read the 3 value

View File

@ -137,7 +137,7 @@ OpStore %7 %6
TEST_F(BuilderTest, FunctionVar_ConstWithVarInitializer) { TEST_F(BuilderTest, FunctionVar_ConstWithVarInitializer) {
// var v : f32 = 1.0; // var v : f32 = 1.0;
// const v2 : f32 = v; // Should generate the load // let v2 : f32 = v; // Should generate the load
auto* v = Global("v", ty.f32(), ast::StorageClass::kFunction, Expr(1.f)); auto* v = Global("v", ty.f32(), ast::StorageClass::kFunction, Expr(1.f));

View File

@ -588,7 +588,7 @@ bool GeneratorImpl::EmitVariable(ast::Variable* var) {
} }
if (var->is_const()) { if (var->is_const()) {
out_ << "const"; out_ << "let";
} else { } else {
out_ << "var"; out_ << "var";
if (sem->StorageClass() != ast::StorageClass::kNone && if (sem->StorageClass() != ast::StorageClass::kNone &&

View File

@ -92,7 +92,7 @@ TEST_F(WgslGeneratorImplTest, EmitVariable_Const) {
GeneratorImpl& gen = Build(); GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.EmitVariable(v)) << gen.error(); ASSERT_TRUE(gen.EmitVariable(v)) << gen.error();
EXPECT_EQ(gen.result(), R"(const a : f32 = 1.0; EXPECT_EQ(gen.result(), R"(let a : f32 = 1.0;
)"); )");
} }

View File

@ -13,7 +13,7 @@
// limitations under the License. // limitations under the License.
// Vertex shader // Vertex shader
const pos : array<vec2<f32>, 3> = array<vec2<f32>, 3>( let pos : array<vec2<f32>, 3> = array<vec2<f32>, 3>(
vec2<f32>(0.0, 0.5), vec2<f32>(0.0, 0.5),
vec2<f32>(-0.5, -0.5), vec2<f32>(-0.5, -0.5),
vec2<f32>(0.5, -0.5)); vec2<f32>(0.5, -0.5));