Skip to main content

prebindgen_registry/expand/
error.rs

1//! Errors produced while resolving constructor-expansion declarations.
2
3/// Errors surfaced while resolving [`Expansions`](super::Expansions).
4#[derive(Debug)]
5pub enum ExpandError {
6    UnknownFunction(syn::Ident),
7    UnknownParam(syn::Ident, syn::Ident),
8    UnknownConstructor(syn::Ident),
9    NoConstructor {
10        func: syn::Ident,
11        param: syn::Ident,
12        target: String,
13    },
14    TargetMismatch {
15        ctor: String,
16        produces: String,
17        expected: String,
18    },
19    UnsupportedOptional {
20        func: syn::Ident,
21        param: syn::Ident,
22        reason: &'static str,
23    },
24    /// An explicit per-fn input flatten targeted a read accessor — accessors
25    /// are never parameter-composed.
26    ConstructOnAccessor {
27        func: syn::Ident,
28    },
29    /// A per-fn `.expand_param(name, expand_param!(T))` decl whose `T` does
30    /// not match the named parameter's peeled type.
31    ParamTypeMismatch {
32        func: syn::Ident,
33        param: syn::Ident,
34        declared: String,
35        actual: String,
36    },
37    /// Recursive input reached a type already on the build chain (`A → … → A`).
38    InputCycle {
39        ty: String,
40    },
41    /// A recursive-input shape that is declared-but-not-yet-supported (recursion
42    /// under a selector-dispatched variant, or on an `Option<…>` parameter).
43    UnsupportedRecursive {
44        func: syn::Ident,
45        reason: &'static str,
46    },
47    /// Structurally invalid declaration records — empty variant lists or
48    /// duplicate targets. All offenders are collected before failing
49    /// (mirrors `ScanError::DeclaredNotFound`).
50    InvalidDeclarations {
51        entries: Vec<ExpandDeclError>,
52    },
53}
54
55/// One structurally invalid expansion declaration (see
56/// [`ExpandError::InvalidDeclarations`]).
57#[derive(Debug)]
58pub enum ExpandDeclError {
59    /// A constructor declaration with no variants.
60    EmptyConstructor { target: String },
61    /// A per-fn expand with an empty variant subset.
62    EmptySubset { func: syn::Ident, param: syn::Ident },
63    /// Two constructor declarations for the same target type.
64    DuplicateConstructor { target: String },
65    /// Two per-fn expands for the same `(fn, param)`.
66    DuplicateExpand { func: syn::Ident, param: syn::Ident },
67}
68
69impl std::fmt::Display for ExpandDeclError {
70    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
71        match self {
72            ExpandDeclError::EmptyConstructor { target } => {
73                write!(f, "constructor for `{target}` declares no variants")
74            }
75            ExpandDeclError::EmptySubset { func, param } => write!(
76                f,
77                "expand for parameter `{param}` of `{func}` declares no variants"
78            ),
79            ExpandDeclError::DuplicateConstructor { target } => {
80                write!(f, "duplicate constructor declaration for `{target}`")
81            }
82            ExpandDeclError::DuplicateExpand { func, param } => write!(
83                f,
84                "duplicate expand declaration for parameter `{param}` of `{func}`"
85            ),
86        }
87    }
88}
89
90impl std::fmt::Display for ExpandError {
91    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
92        match self {
93            ExpandError::UnknownFunction(name) => {
94                write!(f, "expand: function `{}` is not a #[prebindgen] item", name)
95            }
96            ExpandError::ConstructOnAccessor { func } => write!(
97                f,
98                "expand: param-variant override on accessor fn `{}` — an accessor is never \
99                 parameter-composed (remove the override, or declare it as `.fun`)",
100                func
101            ),
102            ExpandError::InputCycle { ty } => write!(
103                f,
104                "expand: recursive input forms a cycle through `{}` — a constructor \
105                 parameter's type transitively constructs itself",
106                ty
107            ),
108            ExpandError::UnsupportedRecursive { func, reason } => write!(
109                f,
110                "expand: `{}`: recursive input not supported here: {}",
111                func, reason
112            ),
113            ExpandError::UnknownParam(func, param) => write!(
114                f,
115                "expand: function `{}` has no parameter named `{}`",
116                func, param
117            ),
118            ExpandError::ParamTypeMismatch {
119                func,
120                param,
121                declared,
122                actual,
123            } => write!(
124                f,
125                "expand: `{}`.expand_param(\"{}\", expand_param!({declared})): the parameter's \
126                 type is `{actual}`, not `{declared}` — declare the decl for the parameter's \
127                 actual type",
128                func, param
129            ),
130            ExpandError::UnknownConstructor(name) => write!(
131                f,
132                "expand: constructor `{}` is not a #[prebindgen] item",
133                name
134            ),
135            ExpandError::NoConstructor {
136                func,
137                param,
138                target,
139            } => write!(
140                f,
141                "expand: no constructor registered for `{}` (parameter `{}` of `{}`)",
142                target, param, func
143            ),
144            ExpandError::TargetMismatch {
145                ctor,
146                produces,
147                expected,
148            } => write!(
149                f,
150                "expand: constructor `{}` produces `{}` but the parameter expects `{}`",
151                ctor, produces, expected
152            ),
153            ExpandError::UnsupportedOptional {
154                func,
155                param,
156                reason,
157            } => write!(
158                f,
159                "expand: optional parameter `{}` of `{}` is not supported: {}",
160                param, func, reason
161            ),
162            ExpandError::InvalidDeclarations { entries } => {
163                writeln!(f, "expand: invalid declarations:")?;
164                for e in entries {
165                    writeln!(f, "  - {e}")?;
166                }
167                Ok(())
168            }
169        }
170    }
171}
172
173impl std::error::Error for ExpandError {}