mirror of
https://github.com/gfx-rs/wgpu.git
synced 2025-12-08 21:26:17 +00:00
Add stderr and termcolor features to Naga (#7482)
Co-authored-by: Connor Fitzgerald <connorwadefitzgerald@gmail.com> Co-authored-by: Erich Gubler <erichdongubler@gmail.com>
This commit is contained in:
parent
6666d528b2
commit
bf8cc43a15
@ -351,6 +351,7 @@ By @cwfitzgerald in [#6811](https://github.com/gfx-rs/wgpu/pull/6811), [#6815](h
|
||||
- Refactored `use` statements to simplify future `no_std` support. By @bushrat011899 in [#7256](https://github.com/gfx-rs/wgpu/pull/7256)
|
||||
- Naga's WGSL frontend no longer allows using the `&` operator to take the address of a component of a vector,
|
||||
which is not permitted by the WGSL specification. By @andyleiserson in [#7284](https://github.com/gfx-rs/wgpu/pull/7284)
|
||||
- Naga's use of `termcolor` and `stderr` are now optional behind features of the same names. By @bushrat011899 in [#7482](https://github.com/gfx-rs/wgpu/pull/7482)
|
||||
|
||||
#### Vulkan
|
||||
|
||||
|
||||
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -2407,6 +2407,7 @@ dependencies = [
|
||||
"arrayvec",
|
||||
"bit-set 0.8.0",
|
||||
"bitflags 2.9.0",
|
||||
"cfg-if",
|
||||
"cfg_aliases 0.2.1",
|
||||
"codespan-reporting",
|
||||
"diff",
|
||||
|
||||
@ -37,6 +37,8 @@ naga = { workspace = true, features = [
|
||||
"dot-out",
|
||||
"serialize",
|
||||
"deserialize",
|
||||
"termcolor",
|
||||
"stderr",
|
||||
] }
|
||||
|
||||
bincode.workspace = true
|
||||
|
||||
@ -80,15 +80,19 @@ hlsl-out-if-target-windows = []
|
||||
|
||||
compact = []
|
||||
|
||||
## Enables colored output through codespan-reporting and termcolor.
|
||||
termcolor = ["codespan-reporting/termcolor"]
|
||||
|
||||
## Enables writing output to stderr.
|
||||
stderr = ["codespan-reporting/std"]
|
||||
|
||||
[dependencies]
|
||||
arbitrary = { version = "1.4", features = ["derive"], optional = true }
|
||||
arrayvec.workspace = true
|
||||
bitflags.workspace = true
|
||||
bit-set.workspace = true
|
||||
codespan-reporting = { workspace = true, default-features = false, features = [
|
||||
"std",
|
||||
"termcolor",
|
||||
] }
|
||||
cfg-if.workspace = true
|
||||
codespan-reporting = { workspace = true, default-features = false }
|
||||
hashbrown.workspace = true
|
||||
half = { workspace = true, default-features = false, features = ["num-traits"] }
|
||||
rustc-hash.workspace = true
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
use alloc::{boxed::Box, string::String, vec::Vec};
|
||||
use alloc::{boxed::Box, string::String};
|
||||
use core::{error::Error, fmt};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
@ -43,14 +43,88 @@ impl fmt::Display for ShaderError<crate::WithSpan<crate::valid::ValidationError>
|
||||
let label = self.label.as_deref().unwrap_or_default();
|
||||
let files = SimpleFile::new(label, &self.source);
|
||||
let config = term::Config::default();
|
||||
let mut writer = term::termcolor::NoColor::new(Vec::new());
|
||||
term::emit(&mut writer, &config, &files, &self.inner.diagnostic())
|
||||
|
||||
let writer = {
|
||||
let mut writer = DiagnosticBuffer::new();
|
||||
term::emit(
|
||||
writer.inner_mut(),
|
||||
&config,
|
||||
&files,
|
||||
&self.inner.diagnostic(),
|
||||
)
|
||||
.expect("cannot write error");
|
||||
write!(
|
||||
f,
|
||||
"\nShader validation {}",
|
||||
String::from_utf8_lossy(&writer.into_inner())
|
||||
writer.into_string()
|
||||
};
|
||||
|
||||
write!(f, "\nShader validation {}", writer)
|
||||
}
|
||||
}
|
||||
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(feature = "termcolor")] {
|
||||
type DiagnosticBufferInner = codespan_reporting::term::termcolor::NoColor<alloc::vec::Vec<u8>>;
|
||||
pub(crate) use codespan_reporting::term::termcolor::WriteColor as _ErrorWrite;
|
||||
} else if #[cfg(feature = "stderr")] {
|
||||
type DiagnosticBufferInner = alloc::vec::Vec<u8>;
|
||||
pub(crate) use std::io::Write as _ErrorWrite;
|
||||
} else {
|
||||
type DiagnosticBufferInner = String;
|
||||
pub(crate) use core::fmt::Write as _ErrorWrite;
|
||||
}
|
||||
}
|
||||
|
||||
// Using this indirect export to avoid duplicating the expect(...) for all three cases above.
|
||||
#[cfg_attr(
|
||||
not(any(feature = "spv-in", feature = "glsl-in")),
|
||||
expect(
|
||||
unused_imports,
|
||||
reason = "only need `ErrorWrite` with an appropriate front-end."
|
||||
)
|
||||
)]
|
||||
pub(crate) use _ErrorWrite as ErrorWrite;
|
||||
|
||||
pub(crate) struct DiagnosticBuffer {
|
||||
inner: DiagnosticBufferInner,
|
||||
}
|
||||
|
||||
impl DiagnosticBuffer {
|
||||
#[cfg_attr(
|
||||
not(feature = "termcolor"),
|
||||
expect(
|
||||
clippy::missing_const_for_fn,
|
||||
reason = "`NoColor::new` isn't `const`, but other `inner`s are."
|
||||
)
|
||||
)]
|
||||
pub fn new() -> Self {
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(feature = "termcolor")] {
|
||||
let inner = codespan_reporting::term::termcolor::NoColor::new(alloc::vec::Vec::new());
|
||||
} else if #[cfg(feature = "stderr")] {
|
||||
let inner = alloc::vec::Vec::new();
|
||||
} else {
|
||||
let inner = String::new();
|
||||
}
|
||||
};
|
||||
|
||||
Self { inner }
|
||||
}
|
||||
|
||||
pub fn inner_mut(&mut self) -> &mut DiagnosticBufferInner {
|
||||
&mut self.inner
|
||||
}
|
||||
|
||||
pub fn into_string(self) -> String {
|
||||
let Self { inner } = self;
|
||||
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(feature = "termcolor")] {
|
||||
String::from_utf8(inner.into_inner()).unwrap()
|
||||
} else if #[cfg(feature = "stderr")] {
|
||||
String::from_utf8(inner).unwrap()
|
||||
} else {
|
||||
inner
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -8,13 +8,12 @@ use alloc::{
|
||||
use codespan_reporting::diagnostic::{Diagnostic, Label};
|
||||
use codespan_reporting::files::SimpleFile;
|
||||
use codespan_reporting::term;
|
||||
use codespan_reporting::term::termcolor::{NoColor, WriteColor};
|
||||
use pp_rs::token::PreprocessorError;
|
||||
use thiserror::Error;
|
||||
|
||||
use super::token::TokenValue;
|
||||
use crate::SourceLocation;
|
||||
use crate::{proc::ConstantEvaluatorError, Span};
|
||||
use crate::{error::ErrorWrite, proc::ConstantEvaluatorError, Span};
|
||||
|
||||
fn join_with_comma(list: &[ExpectedToken]) -> String {
|
||||
let mut string = "".to_string();
|
||||
@ -166,11 +165,11 @@ pub struct ParseErrors {
|
||||
}
|
||||
|
||||
impl ParseErrors {
|
||||
pub fn emit_to_writer(&self, writer: &mut impl WriteColor, source: &str) {
|
||||
pub fn emit_to_writer(&self, writer: &mut impl ErrorWrite, source: &str) {
|
||||
self.emit_to_writer_with_path(writer, source, "glsl");
|
||||
}
|
||||
|
||||
pub fn emit_to_writer_with_path(&self, writer: &mut impl WriteColor, source: &str, path: &str) {
|
||||
pub fn emit_to_writer_with_path(&self, writer: &mut impl ErrorWrite, source: &str, path: &str) {
|
||||
let path = path.to_string();
|
||||
let files = SimpleFile::new(path, source);
|
||||
let config = term::Config::default();
|
||||
@ -187,9 +186,9 @@ impl ParseErrors {
|
||||
}
|
||||
|
||||
pub fn emit_to_string(&self, source: &str) -> String {
|
||||
let mut writer = NoColor::new(Vec::new());
|
||||
self.emit_to_writer(&mut writer, source);
|
||||
String::from_utf8(writer.into_inner()).unwrap()
|
||||
let mut writer = crate::error::DiagnosticBuffer::new();
|
||||
self.emit_to_writer(writer.inner_mut(), source);
|
||||
writer.into_string()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,16 +1,14 @@
|
||||
use alloc::{
|
||||
format,
|
||||
string::{String, ToString},
|
||||
vec::Vec,
|
||||
};
|
||||
|
||||
use codespan_reporting::diagnostic::Diagnostic;
|
||||
use codespan_reporting::files::SimpleFile;
|
||||
use codespan_reporting::term;
|
||||
use codespan_reporting::term::termcolor::{NoColor, WriteColor};
|
||||
|
||||
use super::ModuleState;
|
||||
use crate::{arena::Handle, front::atomic_upgrade};
|
||||
use crate::{arena::Handle, error::ErrorWrite, front::atomic_upgrade};
|
||||
|
||||
#[derive(Clone, Debug, thiserror::Error)]
|
||||
pub enum Error {
|
||||
@ -153,11 +151,11 @@ pub enum Error {
|
||||
}
|
||||
|
||||
impl Error {
|
||||
pub fn emit_to_writer(&self, writer: &mut impl WriteColor, source: &str) {
|
||||
pub fn emit_to_writer(&self, writer: &mut impl ErrorWrite, source: &str) {
|
||||
self.emit_to_writer_with_path(writer, source, "glsl");
|
||||
}
|
||||
|
||||
pub fn emit_to_writer_with_path(&self, writer: &mut impl WriteColor, source: &str, path: &str) {
|
||||
pub fn emit_to_writer_with_path(&self, writer: &mut impl ErrorWrite, source: &str, path: &str) {
|
||||
let path = path.to_string();
|
||||
let files = SimpleFile::new(path, source);
|
||||
let config = term::Config::default();
|
||||
@ -167,9 +165,9 @@ impl Error {
|
||||
}
|
||||
|
||||
pub fn emit_to_string(&self, source: &str) -> String {
|
||||
let mut writer = NoColor::new(Vec::new());
|
||||
self.emit_to_writer(&mut writer, source);
|
||||
String::from_utf8(writer.into_inner()).unwrap()
|
||||
let mut writer = crate::error::DiagnosticBuffer::new();
|
||||
self.emit_to_writer(writer.inner_mut(), source);
|
||||
writer.into_string()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -14,7 +14,6 @@ use super::parse::lexer::Token;
|
||||
use codespan_reporting::diagnostic::{Diagnostic, Label};
|
||||
use codespan_reporting::files::SimpleFile;
|
||||
use codespan_reporting::term;
|
||||
use codespan_reporting::term::termcolor::{ColorChoice, NoColor, StandardStream};
|
||||
use thiserror::Error;
|
||||
|
||||
use alloc::{
|
||||
@ -68,11 +67,13 @@ impl ParseError {
|
||||
}
|
||||
|
||||
/// Emits a summary of the error to standard error stream.
|
||||
#[cfg(feature = "stderr")]
|
||||
pub fn emit_to_stderr(&self, source: &str) {
|
||||
self.emit_to_stderr_with_path(source, "wgsl")
|
||||
}
|
||||
|
||||
/// Emits a summary of the error to standard error stream.
|
||||
#[cfg(feature = "stderr")]
|
||||
pub fn emit_to_stderr_with_path<P>(&self, source: &str, path: P)
|
||||
where
|
||||
P: AsRef<std::path::Path>,
|
||||
@ -80,7 +81,15 @@ impl ParseError {
|
||||
let path = path.as_ref().display().to_string();
|
||||
let files = SimpleFile::new(path, source);
|
||||
let config = term::Config::default();
|
||||
let writer = StandardStream::stderr(ColorChoice::Auto);
|
||||
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(feature = "termcolor")] {
|
||||
let writer = term::termcolor::StandardStream::stderr(term::termcolor::ColorChoice::Auto);
|
||||
} else {
|
||||
let writer = std::io::stderr();
|
||||
}
|
||||
}
|
||||
|
||||
term::emit(&mut writer.lock(), &config, &files, &self.diagnostic())
|
||||
.expect("cannot write error");
|
||||
}
|
||||
@ -98,9 +107,11 @@ impl ParseError {
|
||||
let path = path.as_ref().display().to_string();
|
||||
let files = SimpleFile::new(path, source);
|
||||
let config = term::Config::default();
|
||||
let mut writer = NoColor::new(Vec::new());
|
||||
term::emit(&mut writer, &config, &files, &self.diagnostic()).expect("cannot write error");
|
||||
String::from_utf8(writer.into_inner()).unwrap()
|
||||
|
||||
let mut writer = crate::error::DiagnosticBuffer::new();
|
||||
term::emit(writer.inner_mut(), &config, &files, &self.diagnostic())
|
||||
.expect("cannot write error");
|
||||
writer.into_string()
|
||||
}
|
||||
|
||||
/// Returns a [`SourceLocation`] for the first label in the error message.
|
||||
|
||||
@ -110,7 +110,9 @@ void main() {
|
||||
wgsl_out,
|
||||
|
||||
feature = "spv-in",
|
||||
feature = "wgsl-in"
|
||||
feature = "wgsl-in",
|
||||
|
||||
feature = "stderr",
|
||||
))]
|
||||
extern crate std;
|
||||
|
||||
|
||||
@ -273,6 +273,7 @@ impl<E> WithSpan<E> {
|
||||
}
|
||||
|
||||
/// Emits a summary of the error to standard error stream.
|
||||
#[cfg(feature = "stderr")]
|
||||
pub fn emit_to_stderr(&self, source: &str)
|
||||
where
|
||||
E: Error,
|
||||
@ -281,16 +282,24 @@ impl<E> WithSpan<E> {
|
||||
}
|
||||
|
||||
/// Emits a summary of the error to standard error stream.
|
||||
#[cfg(feature = "stderr")]
|
||||
pub fn emit_to_stderr_with_path(&self, source: &str, path: &str)
|
||||
where
|
||||
E: Error,
|
||||
{
|
||||
use codespan_reporting::term::termcolor::{ColorChoice, StandardStream};
|
||||
use codespan_reporting::{files, term};
|
||||
|
||||
let files = files::SimpleFile::new(path, source);
|
||||
let config = term::Config::default();
|
||||
let writer = StandardStream::stderr(ColorChoice::Auto);
|
||||
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(feature = "termcolor")] {
|
||||
let writer = term::termcolor::StandardStream::stderr(term::termcolor::ColorChoice::Auto);
|
||||
} else {
|
||||
let writer = std::io::stderr();
|
||||
}
|
||||
}
|
||||
|
||||
term::emit(&mut writer.lock(), &config, &files, &self.diagnostic())
|
||||
.expect("cannot write error");
|
||||
}
|
||||
@ -308,14 +317,15 @@ impl<E> WithSpan<E> {
|
||||
where
|
||||
E: Error,
|
||||
{
|
||||
use codespan_reporting::term::termcolor::NoColor;
|
||||
use codespan_reporting::{files, term};
|
||||
|
||||
let files = files::SimpleFile::new(path, source);
|
||||
let config = term::Config::default();
|
||||
let mut writer = NoColor::new(Vec::new());
|
||||
term::emit(&mut writer, &config, &files, &self.diagnostic()).expect("cannot write error");
|
||||
String::from_utf8(writer.into_inner()).unwrap()
|
||||
|
||||
let mut writer = crate::error::DiagnosticBuffer::new();
|
||||
term::emit(writer.inner_mut(), &config, &files, &self.diagnostic())
|
||||
.expect("cannot write error");
|
||||
writer.into_string()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -324,9 +324,9 @@ cfg_aliases.workspace = true
|
||||
[dev-dependencies]
|
||||
cfg-if.workspace = true
|
||||
env_logger.workspace = true
|
||||
glam.workspace = true # for ray-traced-triangle example
|
||||
naga = { workspace = true, features = ["wgsl-in"] }
|
||||
winit.workspace = true # for "halmark" example
|
||||
glam.workspace = true # for ray-traced-triangle example
|
||||
naga = { workspace = true, features = ["wgsl-in", "termcolor"] }
|
||||
winit.workspace = true # for "halmark" example
|
||||
|
||||
### Platform: Windows + MacOS + Linux for "raw-gles" example ###
|
||||
[target.'cfg(not(any(target_arch = "wasm32", target_os = "ios", target_os = "visionos")))'.dev-dependencies]
|
||||
|
||||
@ -153,7 +153,7 @@ fragile-send-sync-non-atomic-wasm = [
|
||||
#########################
|
||||
|
||||
[dependencies]
|
||||
naga = { workspace = true, optional = true }
|
||||
naga = { workspace = true, optional = true, features = ["termcolor"] }
|
||||
wgpu-core = { workspace = true, optional = true }
|
||||
wgpu-types.workspace = true
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user