diff --git a/naga/src/front/wgsl/error.rs b/naga/src/front/wgsl/error.rs index 1bd8ef57c..dfe324fa8 100644 --- a/naga/src/front/wgsl/error.rs +++ b/naga/src/front/wgsl/error.rs @@ -136,6 +136,8 @@ pub enum ExpectedToken<'a> { Variable, /// Access of a function Function, + /// The `diagnostic` identifier of the `@diagnostic(…)` attribute. + DiagnosticAttribute, } #[derive(Clone, Copy, Debug, Error, PartialEq)] @@ -388,6 +390,9 @@ impl<'a> Error<'a> { ExpectedToken::AfterIdentListComma => { "next argument or end of list (';')".to_string() } + ExpectedToken::DiagnosticAttribute => { + "the 'diagnostic' attribute identifier".to_string() + } }; ParseError { message: format!( diff --git a/naga/src/front/wgsl/parse/mod.rs b/naga/src/front/wgsl/parse/mod.rs index 881c56345..18261f8ad 100644 --- a/naga/src/front/wgsl/parse/mod.rs +++ b/naga/src/front/wgsl/parse/mod.rs @@ -2159,6 +2159,32 @@ impl Parser { ctx.local_table.push_scope(); + let mut diagnostic_filters = DiagnosticFilterMap::new(); + + self.push_rule_span(Rule::Attribute, lexer); + while lexer.skip(Token::Attribute) { + let (name, name_span) = lexer.next_ident_with_span()?; + if let Some(DirectiveKind::Diagnostic) = DirectiveKind::from_ident(name) { + if let Some(filter) = self.diagnostic_filter(lexer)? { + let span = self.peek_rule_span(lexer); + diagnostic_filters.add(filter, span)?; + } + } else { + return Err(Error::Unexpected( + name_span, + ExpectedToken::DiagnosticAttribute, + )); + } + } + self.pop_rule_span(lexer); + + if !diagnostic_filters.is_empty() { + return Err(Error::DiagnosticAttributeNotYetImplementedAtParseSite { + site_name_plural: "compound statements", + spans: diagnostic_filters.spans().collect(), + }); + } + let brace_span = lexer.expect_span(Token::Paren('{'))?; let brace_nesting_level = Self::increase_brace_nesting(brace_nesting_level, brace_span)?; let mut block = ast::Block::default();