diff --git a/CHANGELOG.md b/CHANGELOG.md index a903d4f5ee..5dcdcbacf9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -173,6 +173,7 @@ By @brodycj in [#6924](https://github.com/gfx-rs/wgpu/pull/6924). - Fix some instances of functions which have a return type but don't return a value being incorrectly validated. By @jamienicol in [#7013](https://github.com/gfx-rs/wgpu/pull/7013). - Allow abstract expressions to be used in WGSL function return statements. By @jamienicol in [#7035](https://github.com/gfx-rs/wgpu/pull/7035). - Error if structs have two fields with the same name. By @SparkyPotato in [#7088](https://github.com/gfx-rs/wgpu/pull/7088). +- Allow template lists to have a trailing comma. By @KentSlaney in [#7142](https://github.com/gfx-rs/wgpu/pull/7142). #### General diff --git a/naga/src/front/wgsl/parse/lexer.rs b/naga/src/front/wgsl/parse/lexer.rs index d55720972e..955643e62c 100644 --- a/naga/src/front/wgsl/parse/lexer.rs +++ b/naga/src/front/wgsl/parse/lexer.rs @@ -352,6 +352,10 @@ impl<'a> Lexer<'a> { } } + pub(in crate::front::wgsl) fn end_of_generic_arguments(&mut self) -> bool { + self.skip(Token::Separator(',')) && self.peek().0 != Token::Paren('>') + } + /// If the next token matches it is skipped and true is returned pub(in crate::front::wgsl) fn skip(&mut self, what: Token<'_>) -> bool { let (peeked_token, rest) = self.peek_token_and_rest(); diff --git a/naga/src/front/wgsl/parse/mod.rs b/naga/src/front/wgsl/parse/mod.rs index 23b2984e75..ad229b2170 100644 --- a/naga/src/front/wgsl/parse/mod.rs +++ b/naga/src/front/wgsl/parse/mod.rs @@ -576,8 +576,9 @@ impl Parser { (Token::Paren('<'), ast::ConstructorType::PartialArray) => { lexer.expect_generic_paren('<')?; let base = self.type_decl(lexer, ctx)?; - let size = if lexer.skip(Token::Separator(',')) { + let size = if lexer.end_of_generic_arguments() { let expr = self.const_generic_expression(lexer, ctx)?; + lexer.skip(Token::Separator(',')); ast::ArraySize::Constant(expr) } else { ast::ArraySize::Dynamic @@ -1244,6 +1245,7 @@ impl Parser { let start = lexer.start_byte_offset(); let ty = self.type_decl(lexer, ctx)?; let span = lexer.span_from(start); + lexer.skip(Token::Separator(',')); lexer.expect_generic_paren('>')?; Ok((ty, span)) } @@ -1436,8 +1438,10 @@ impl Parser { lexer.expect(Token::Separator(','))?; let base = self.type_decl(lexer, ctx)?; if let crate::AddressSpace::Storage { ref mut access } = space { - *access = if lexer.skip(Token::Separator(',')) { - lexer.next_storage_access()? + *access = if lexer.end_of_generic_arguments() { + let result = lexer.next_storage_access()?; + lexer.skip(Token::Separator(',')); + result } else { crate::StorageAccess::LOAD }; @@ -1448,8 +1452,9 @@ impl Parser { "array" => { lexer.expect_generic_paren('<')?; let base = self.type_decl(lexer, ctx)?; - let size = if lexer.skip(Token::Separator(',')) { + let size = if lexer.end_of_generic_arguments() { let size = self.const_generic_expression(lexer, ctx)?; + lexer.skip(Token::Separator(',')); ast::ArraySize::Constant(size) } else { ast::ArraySize::Dynamic @@ -1461,8 +1466,9 @@ impl Parser { "binding_array" => { lexer.expect_generic_paren('<')?; let base = self.type_decl(lexer, ctx)?; - let size = if lexer.skip(Token::Separator(',')) { + let size = if lexer.end_of_generic_arguments() { let size = self.unary_expression(lexer, ctx)?; + lexer.skip(Token::Separator(',')); ast::ArraySize::Constant(size) } else { ast::ArraySize::Dynamic diff --git a/tests/tests/shader/array_size_overrides.rs b/tests/tests/shader/array_size_overrides.rs index 2fd96f02a5..c05b0147c5 100644 --- a/tests/tests/shader/array_size_overrides.rs +++ b/tests/tests/shader/array_size_overrides.rs @@ -6,10 +6,10 @@ use wgpu_test::{fail_if, gpu_test, GpuTestConfiguration, TestParameters, Testing const SHADER: &str = r#" override n = 8; - var arr: array; + var arr: array; @group(0) @binding(0) - var output: array; + var output: array; @compute @workgroup_size(1) fn main() { // 1d spiral