From b7dfe1677fd8f92d3bbf0af658515e077b96cd1a Mon Sep 17 00:00:00 2001 From: Jakob Hellermann Date: Fri, 4 Feb 2022 03:37:38 +0000 Subject: [PATCH] include sources in shader validation error (#3724) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Objective When print shader validation error messages, we didn't print the sources and error message text, which led to some confusing error messages. ```cs error: ┌─ wgsl:15:11 │ 15 │ return material.color + 1u; │ ^^^^^^^^^^^^^^^^^^^^ naga::Expression [11] ``` ## Solution New error message: ```cs error: Entry point fragment at Vertex is invalid ┌─ wgsl:15:11 │ 15 │ return material.color + 1u; │ ^^^^^^^^^^^^^^^^^^^^ naga::Expression [11] │ = Expression [11] is invalid = Operation Add can't work with [8] and [10] ``` --- .../src/render_resource/pipeline_cache.rs | 47 +++++++++++++++---- 1 file changed, 38 insertions(+), 9 deletions(-) diff --git a/crates/bevy_render/src/render_resource/pipeline_cache.rs b/crates/bevy_render/src/render_resource/pipeline_cache.rs index e5fcede3cb..d4ec249133 100644 --- a/crates/bevy_render/src/render_resource/pipeline_cache.rs +++ b/crates/bevy_render/src/render_resource/pipeline_cache.rs @@ -464,15 +464,22 @@ fn log_shader_error(source: &ProcessedShader, error: &AsModuleDescriptorError) { let config = term::Config::default(); let mut writer = term::termcolor::Ansi::new(Vec::new()); - let diagnostic = Diagnostic::error().with_labels( - error - .spans() - .map(|(span, desc)| { - Label::primary((), span.to_range().unwrap()) - .with_message(desc.to_owned()) - }) - .collect(), - ); + let diagnostic = Diagnostic::error() + .with_message(error.to_string()) + .with_labels( + error + .spans() + .map(|(span, desc)| { + Label::primary((), span.to_range().unwrap()) + .with_message(desc.to_owned()) + }) + .collect(), + ) + .with_notes( + ErrorSources::of(error) + .map(|source| source.to_string()) + .collect(), + ); term::emit(&mut writer, &config, &files, &diagnostic).expect("cannot write error"); @@ -490,3 +497,25 @@ fn log_shader_error(source: &ProcessedShader, error: &AsModuleDescriptorError) { } } } + +struct ErrorSources<'a> { + current: Option<&'a (dyn std::error::Error + 'static)>, +} + +impl<'a> ErrorSources<'a> { + fn of(error: &'a dyn std::error::Error) -> Self { + Self { + current: error.source(), + } + } +} + +impl<'a> Iterator for ErrorSources<'a> { + type Item = &'a (dyn std::error::Error + 'static); + + fn next(&mut self) -> Option { + let current = self.current; + self.current = self.current.and_then(std::error::Error::source); + current + } +}