Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Emit unimplemented errors for several @diagnostic(…) attribute parse sites #6533

Merged
45 changes: 12 additions & 33 deletions naga/src/diagnostic_filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,22 +27,6 @@ pub enum Severity {
}

impl Severity {
const ERROR: &'static str = "error";
const WARNING: &'static str = "warning";
const INFO: &'static str = "info";
const OFF: &'static str = "off";

/// Convert from a sentinel word in WGSL into its associated [`Severity`], if possible.
pub fn from_ident(s: &str) -> Option<Self> {
Some(match s {
Self::ERROR => Self::Error,
Self::WARNING => Self::Warning,
Self::INFO => Self::Info,
Self::OFF => Self::Off,
_ => return None,
})
}

/// Checks whether this severity is [`Self::Error`].
///
/// Naga does not yet support diagnostic items at lesser severities than
Expand Down Expand Up @@ -79,23 +63,6 @@ pub enum FilterableTriggeringRule {
}

impl FilterableTriggeringRule {
const DERIVATIVE_UNIFORMITY: &'static str = "derivative_uniformity";

/// Convert from a sentinel word in WGSL into its associated [`FilterableTriggeringRule`], if possible.
pub fn from_ident(s: &str) -> Option<Self> {
Some(match s {
Self::DERIVATIVE_UNIFORMITY => Self::DerivativeUniformity,
_ => return None,
})
}

/// Maps this [`FilterableTriggeringRule`] into the sentinel word associated with it in WGSL.
pub const fn to_ident(self) -> &'static str {
match self {
Self::DerivativeUniformity => Self::DERIVATIVE_UNIFORMITY,
}
}

/// The default severity associated with this triggering rule.
///
/// See <https://www.w3.org/TR/WGSL/#filterable-triggering-rules> for a table of default
Expand Down Expand Up @@ -162,6 +129,18 @@ impl DiagnosticFilterMap {
}
Ok(())
}

/// Were any rules specified?
pub(crate) fn is_empty(&self) -> bool {
let &Self(ref map) = self;
map.is_empty()
}

/// Returns the spans of all contained rules.
pub(crate) fn spans(&self) -> impl Iterator<Item = Span> + '_ {
let &Self(ref map) = self;
map.iter().map(|(_, &(_, span))| span)
}
}

#[cfg(feature = "wgsl-in")]
Expand Down
38 changes: 38 additions & 0 deletions naga/src/front/wgsl/diagnostic_filter.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
use crate::diagnostic_filter::{FilterableTriggeringRule, Severity};

impl Severity {
const ERROR: &'static str = "error";
const WARNING: &'static str = "warning";
const INFO: &'static str = "info";
const OFF: &'static str = "off";

/// Convert from a sentinel word in WGSL into its associated [`Severity`], if possible.
pub fn from_wgsl_ident(s: &str) -> Option<Self> {
Some(match s {
Self::ERROR => Self::Error,
Self::WARNING => Self::Warning,
Self::INFO => Self::Info,
Self::OFF => Self::Off,
_ => return None,
})
}
}

impl FilterableTriggeringRule {
const DERIVATIVE_UNIFORMITY: &'static str = "derivative_uniformity";

/// Convert from a sentinel word in WGSL into its associated [`FilterableTriggeringRule`], if possible.
pub fn from_wgsl_ident(s: &str) -> Option<Self> {
Some(match s {
Self::DERIVATIVE_UNIFORMITY => Self::DerivativeUniformity,
_ => return None,
})
}

/// Maps this [`FilterableTriggeringRule`] into the sentinel word associated with it in WGSL.
pub const fn to_wgsl_ident(self) -> &'static str {
match self {
Self::DerivativeUniformity => Self::DERIVATIVE_UNIFORMITY,
}
}
}
62 changes: 61 additions & 1 deletion naga/src/front/wgsl/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down Expand Up @@ -296,6 +298,14 @@ pub(crate) enum Error<'a> {
severity_control_name_span: Span,
},
DiagnosticDuplicateTriggeringRule(ConflictingDiagnosticRuleError),
DiagnosticAttributeNotYetImplementedAtParseSite {
site_name_plural: &'static str,
spans: Vec<Span>,
},
DiagnosticAttributeNotSupported {
on_what_plural: &'static str,
spans: Vec<Span>,
},
}

impl<'a> From<ConflictingDiagnosticRuleError> for Error<'a> {
Expand Down Expand Up @@ -380,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!(
Expand Down Expand Up @@ -1028,7 +1041,7 @@ impl<'a> Error<'a> {
ParseError {
message: format!(
"found conflicting `diagnostic(…)` rule(s) for `{}`",
triggering_rule.to_ident()
triggering_rule.to_wgsl_ident()
),
labels: vec![
(first_span, "first rule".into()),
Expand All @@ -1043,6 +1056,53 @@ impl<'a> Error<'a> {
.into()],
}
}
Error::DiagnosticAttributeNotYetImplementedAtParseSite {
site_name_plural,
ref spans,
} => ParseError {
message: "`@diagnostic(…)` attribute(s) not yet implemented".into(),
labels: {
let mut spans = spans.iter().cloned();
let first = spans
.next()
.map(|span| {
(
span,
format!("can't use this on {site_name_plural} (yet)").into(),
)
})
.expect("internal error: diag. attr. rejection on empty map");
std::iter::once(first)
.chain(spans.map(|span| (span, "".into())))
.collect()
},
notes: vec![format!(concat!(
"Let Naga maintainers know that you ran into this at ",
"<https://github.com/gfx-rs/wgpu/issues/5320>, ",
"so they can prioritize it!"
))],
},
Error::DiagnosticAttributeNotSupported {
on_what_plural,
ref spans,
} => ParseError {
message: format!(
"`@diagnostic(…)` attribute(s) on {on_what_plural} are not supported",
),
labels: spans
.iter()
.cloned()
.map(|span| (span, "".into()))
.collect(),
notes: vec![
concat!(
"`@diagnostic(…)` attributes are only permitted on `fn`s, ",
"some statements, and `switch`/`loop` bodies."
)
.into(),
"These attributes are well-formed, you likely just need to move them.".into(),
],
},
}
}
}
Expand Down
1 change: 1 addition & 0 deletions naga/src/front/wgsl/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ Frontend for [WGSL][wgsl] (WebGPU Shading Language).
[wgsl]: https://gpuweb.github.io/gpuweb/wgsl.html
*/

mod diagnostic_filter;
mod error;
mod index;
mod lower;
Expand Down
Loading