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> {}