1mod extension;
23mod ops;
24mod types;
25mod types_mut;
26mod weak_registry;
27
28pub use weak_registry::WeakExtensionRegistry;
29
30pub(crate) use ops::{collect_op_extension, resolve_op_extensions};
31pub(crate) use types::{collect_op_types_extensions, collect_signature_exts};
32pub(crate) use types_mut::resolve_op_types_extensions;
33use types_mut::{
34 resolve_custom_type_exts, resolve_type_exts, resolve_typearg_exts, resolve_value_exts,
35};
36
37use derive_more::{Display, Error, From};
38
39use super::{Extension, ExtensionId, ExtensionRegistry, ExtensionSet};
40use crate::ops::constant::ValueName;
41use crate::ops::custom::OpaqueOpError;
42use crate::ops::{NamedOp, OpName, OpType, Value};
43use crate::types::{CustomType, FuncTypeBase, MaybeRV, TypeArg, TypeBase, TypeName};
44use crate::Node;
45
46pub fn resolve_type_extensions<RV: MaybeRV>(
48 typ: &mut TypeBase<RV>,
49 extensions: &WeakExtensionRegistry,
50) -> Result<(), ExtensionResolutionError> {
51 let mut used_extensions = WeakExtensionRegistry::default();
52 resolve_type_exts(None, typ, extensions, &mut used_extensions)
53}
54
55pub fn resolve_custom_type_extensions(
57 typ: &mut CustomType,
58 extensions: &WeakExtensionRegistry,
59) -> Result<(), ExtensionResolutionError> {
60 let mut used_extensions = WeakExtensionRegistry::default();
61 resolve_custom_type_exts(None, typ, extensions, &mut used_extensions)
62}
63
64pub fn resolve_typearg_extensions(
66 arg: &mut TypeArg,
67 extensions: &WeakExtensionRegistry,
68) -> Result<(), ExtensionResolutionError> {
69 let mut used_extensions = WeakExtensionRegistry::default();
70 resolve_typearg_exts(None, arg, extensions, &mut used_extensions)
71}
72
73pub fn resolve_value_extensions(
75 value: &mut Value,
76 extensions: &WeakExtensionRegistry,
77) -> Result<(), ExtensionResolutionError> {
78 let mut used_extensions = WeakExtensionRegistry::default();
79 resolve_value_exts(None, value, extensions, &mut used_extensions)
80}
81
82#[derive(Debug, Display, Clone, Error, From, PartialEq)]
84#[non_exhaustive]
85pub enum ExtensionResolutionError {
86 #[display("Error resolving opaque operation: {_0}")]
88 #[from]
89 OpaqueOpError(OpaqueOpError),
90 #[display(
92 "{op}{} requires extension {missing_extension}, but it could not be found in the extension list used during resolution. The available extensions are: {}",
93 node.map(|n| format!(" in {}", n)).unwrap_or_default(),
94 available_extensions.join(", ")
95 )]
96 MissingOpExtension {
97 node: Option<Node>,
99 op: OpName,
101 missing_extension: ExtensionId,
103 available_extensions: Vec<ExtensionId>,
105 },
106 #[display(
108 "Type {ty}{} requires extension {missing_extension}, but it could not be found in the extension list used during resolution. The available extensions are: {}",
109 node.map(|n| format!(" in {}", n)).unwrap_or_default(),
110 available_extensions.join(", ")
111 )]
112 MissingTypeExtension {
113 node: Option<Node>,
115 ty: TypeName,
117 missing_extension: ExtensionId,
119 available_extensions: Vec<ExtensionId>,
121 },
122 #[display(
124 "Type definition {def} in extension {extension} declares it was defined in {wrong_extension} instead."
125 )]
126 WrongTypeDefExtension {
127 extension: ExtensionId,
129 def: TypeName,
131 wrong_extension: ExtensionId,
133 },
134 #[display(
136 "Operation definition {def} in extension {extension} declares it was defined in {wrong_extension} instead."
137 )]
138 WrongOpDefExtension {
139 extension: ExtensionId,
141 def: OpName,
143 wrong_extension: ExtensionId,
145 },
146 #[display("The type of the opaque value '{value}' requires extensions {missing_extensions}, but does not reference their definition.")]
148 InvalidConstTypes {
149 value: ValueName,
151 missing_extensions: ExtensionSet,
153 },
154}
155
156impl ExtensionResolutionError {
157 pub fn missing_op_extension(
159 node: Option<Node>,
160 op: &OpType,
161 missing_extension: &ExtensionId,
162 extensions: &ExtensionRegistry,
163 ) -> Self {
164 Self::MissingOpExtension {
165 node,
166 op: NamedOp::name(op),
167 missing_extension: missing_extension.clone(),
168 available_extensions: extensions.ids().cloned().collect(),
169 }
170 }
171
172 pub fn missing_type_extension(
174 node: Option<Node>,
175 ty: &TypeName,
176 missing_extension: &ExtensionId,
177 extensions: &WeakExtensionRegistry,
178 ) -> Self {
179 Self::MissingTypeExtension {
180 node,
181 ty: ty.clone(),
182 missing_extension: missing_extension.clone(),
183 available_extensions: extensions.ids().cloned().collect(),
184 }
185 }
186}
187
188#[derive(Debug, Display, Clone, Error, From, PartialEq)]
190#[non_exhaustive]
191pub enum ExtensionCollectionError {
192 #[display(
194 "{op}{} contains custom types for which have lost the reference to their defining extensions. Dropped extensions: {}",
195 if let Some(node) = node { format!(" ({})", node) } else { "".to_string() },
196 missing_extensions.join(", ")
197 )]
198 DroppedOpExtensions {
199 node: Option<Node>,
201 op: OpName,
203 missing_extensions: Vec<ExtensionId>,
205 },
206 #[display(
208 "Signature {signature} contains custom types for which have lost the reference to their defining extensions. Dropped extensions: {}",
209 missing_extensions.join(", ")
210 )]
211 DroppedSignatureExtensions {
212 signature: String,
214 missing_extensions: Vec<ExtensionId>,
216 },
217}
218
219impl ExtensionCollectionError {
220 pub fn dropped_op_extension(
222 node: Option<Node>,
223 op: &OpType,
224 missing_extension: impl IntoIterator<Item = ExtensionId>,
225 ) -> Self {
226 Self::DroppedOpExtensions {
227 node,
228 op: NamedOp::name(op),
229 missing_extensions: missing_extension.into_iter().collect(),
230 }
231 }
232
233 pub fn dropped_signature<RV: MaybeRV>(
235 signature: &FuncTypeBase<RV>,
236 missing_extension: impl IntoIterator<Item = ExtensionId>,
237 ) -> Self {
238 Self::DroppedSignatureExtensions {
239 signature: format!("{signature}"),
240 missing_extensions: missing_extension.into_iter().collect(),
241 }
242 }
243}
244
245#[cfg(test)]
246mod test;