Skip to main content

wgsl_rs/
source_error.rs

1//! Errors produced by [`Source`]-level operations.
2//!
3//! These errors are about the *source* (the spec the user wrote) —
4//! distinct from the `crate::linkage::wgpu::Error` type, which is about
5//! producing a wgpu `WgpuLinkage` from an already-analyzed `ir::Module`.
6//! (That error type only exists when the `linkage-wgpu` feature is
7//! enabled, so it's referenced here as a plain code span rather than an
8//! intra-doc link to keep default-feature doc builds warning-free.)
9
10use crate::Source;
11
12/// Errors that [`Source::wgsl_source`] can produce.
13///
14/// The lifetime parameter `'a` is the borrow of the source that triggered
15/// the error. A template `Source` is typically a `&'static Source` (it
16/// lives in static storage, emitted by the macro), so the error is
17/// usually `SourceError<'static>`. The lifetime parameter is present so
18/// the error can borrow from `&self` of a non-static source if needed.
19#[derive(Debug)]
20pub enum SourceError<'a> {
21    /// The source is a template (unresolved module-level type parameters);
22    /// the caller must use the macro-emitted `instantiate::<…>()` to
23    /// obtain a concrete [`crate::ir::Module`] first, then call
24    /// [`crate::ir::Module::wgsl_source`] on that.
25    TemplateWgsl {
26        /// The uninstantiated source that triggered the error.
27        uninstantiated_source: &'a Source,
28    },
29    /// No candidate source declares a template with the requested name.
30    /// This is a configuration error in the source graph (e.g. a missing
31    /// `wgsl!` module import), not a runtime data error.
32    TemplateNotFound {
33        template_name: String,
34        mangled_type_args: Vec<String>,
35        available_templates: Vec<String>,
36    },
37    /// More than one candidate source declares a template with the
38    /// requested name, so the instantiation is ambiguous. Disambiguate
39    /// by removing one of the matching sources from the import graph.
40    AmbiguousTemplate {
41        template_name: String,
42        mangled_type_args: Vec<String>,
43        matching_source_names: Vec<String>,
44        available_templates: Vec<String>,
45    },
46}
47
48impl<'a> std::fmt::Display for SourceError<'a> {
49    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
50        match self {
51            SourceError::TemplateWgsl {
52                uninstantiated_source,
53            } => {
54                write!(
55                    f,
56                    "source '{}' is a template (has module-level type parameters {:?}); call the \
57                     macro-emitted `instantiate::<…>()` (types in `module_type_params` order) \
58                     then `.wgsl_source()` to render concrete WGSL",
59                    uninstantiated_source.name, uninstantiated_source.module_type_params,
60                )
61            }
62            SourceError::TemplateNotFound {
63                template_name,
64                mangled_type_args,
65                available_templates,
66            } => {
67                write!(
68                    f,
69                    "unable to resolve template '{template_name}' for type args \
70                     {mangled_type_args:?}; available templates: {available_templates:?}",
71                )
72            }
73            SourceError::AmbiguousTemplate {
74                template_name,
75                mangled_type_args,
76                matching_source_names,
77                available_templates,
78            } => {
79                write!(
80                    f,
81                    "ambiguous template instantiation '{template_name}' for type args \
82                     {mangled_type_args:?}; matching sources: {matching_source_names:?}; \
83                     available templates: {available_templates:?}",
84                )
85            }
86        }
87    }
88}
89
90impl<'a> std::error::Error for SourceError<'a> {}