1mod extension;
18mod ops;
19mod types;
20mod types_mut;
21mod weak_registry;
22
23pub use weak_registry::WeakExtensionRegistry;
24
25pub(crate) use ops::{collect_op_extension, resolve_op_extensions};
26pub(crate) use types::{collect_op_types_extensions, collect_signature_exts, collect_type_exts};
27pub(crate) use types_mut::resolve_op_types_extensions;
28use types_mut::{
29 resolve_custom_type_exts, resolve_term_exts, resolve_type_exts, resolve_value_exts,
30};
31
32use derive_more::{Display, Error, From};
33
34use super::{Extension, ExtensionId, ExtensionRegistry, ExtensionSet};
35use crate::Node;
36use crate::core::HugrNode;
37use crate::ops::constant::ValueName;
38use crate::ops::custom::OpaqueOpError;
39use crate::ops::{NamedOp, OpName, OpType, Value};
40use crate::types::{CustomType, FuncTypeBase, MaybeRV, TypeArg, TypeBase, TypeName};
41
42pub fn resolve_type_extensions<RV: MaybeRV>(
44 typ: &mut TypeBase<RV>,
45 extensions: &WeakExtensionRegistry,
46) -> Result<(), ExtensionResolutionError> {
47 let mut used_extensions = WeakExtensionRegistry::default();
48 resolve_type_exts(None, typ, extensions, &mut used_extensions)
49}
50
51pub fn resolve_custom_type_extensions(
53 typ: &mut CustomType,
54 extensions: &WeakExtensionRegistry,
55) -> Result<(), ExtensionResolutionError> {
56 let mut used_extensions = WeakExtensionRegistry::default();
57 resolve_custom_type_exts(None, typ, extensions, &mut used_extensions)
58}
59
60pub fn resolve_typearg_extensions(
62 arg: &mut TypeArg,
63 extensions: &WeakExtensionRegistry,
64) -> Result<(), ExtensionResolutionError> {
65 let mut used_extensions = WeakExtensionRegistry::default();
66 resolve_term_exts(None, arg, extensions, &mut used_extensions)
67}
68
69pub fn resolve_value_extensions(
71 value: &mut Value,
72 extensions: &WeakExtensionRegistry,
73) -> Result<(), ExtensionResolutionError> {
74 let mut used_extensions = WeakExtensionRegistry::default();
75 resolve_value_exts(None, value, extensions, &mut used_extensions)
76}
77
78#[derive(Debug, Display, Clone, Error, From, PartialEq)]
80#[non_exhaustive]
81pub enum ExtensionResolutionError<N: HugrNode = Node> {
82 #[display("Error resolving opaque operation: {_0}")]
84 #[from]
85 OpaqueOpError(OpaqueOpError<N>),
86 #[display(
88 "{op}{} requires extension {missing_extension}, but it could not be found in the extension list used during resolution. The available extensions are: {}",
89 node.map(|n| format!(" in {n}")).unwrap_or_default(),
90 available_extensions.join(", ")
91 )]
92 MissingOpExtension {
93 node: Option<N>,
95 op: OpName,
97 missing_extension: ExtensionId,
99 available_extensions: Vec<ExtensionId>,
101 },
102 #[display(
104 "Type {ty}{} requires extension {missing_extension}, but it could not be found in the extension list used during resolution. The available extensions are: {}",
105 node.map(|n| format!(" in {n}")).unwrap_or_default(),
106 available_extensions.join(", ")
107 )]
108 MissingTypeExtension {
109 node: Option<N>,
111 ty: TypeName,
113 missing_extension: ExtensionId,
115 available_extensions: Vec<ExtensionId>,
117 },
118 #[display(
120 "Type definition {def} in extension {extension} declares it was defined in {wrong_extension} instead."
121 )]
122 WrongTypeDefExtension {
123 extension: ExtensionId,
125 def: TypeName,
127 wrong_extension: ExtensionId,
129 },
130 #[display(
132 "Operation definition {def} in extension {extension} declares it was defined in {wrong_extension} instead."
133 )]
134 WrongOpDefExtension {
135 extension: ExtensionId,
137 def: OpName,
139 wrong_extension: ExtensionId,
141 },
142 #[display(
144 "The type of the opaque value '{value}' requires extensions {missing_extensions}, but does not reference their definition."
145 )]
146 InvalidConstTypes {
147 value: ValueName,
149 missing_extensions: ExtensionSet,
151 },
152}
153
154impl<N: HugrNode> ExtensionResolutionError<N> {
155 pub fn missing_op_extension(
157 node: Option<N>,
158 op: &OpType,
159 missing_extension: &ExtensionId,
160 extensions: &ExtensionRegistry,
161 ) -> Self {
162 Self::MissingOpExtension {
163 node,
164 op: NamedOp::name(op),
165 missing_extension: missing_extension.clone(),
166 available_extensions: extensions.ids().cloned().collect(),
167 }
168 }
169
170 pub fn missing_type_extension(
172 node: Option<N>,
173 ty: &TypeName,
174 missing_extension: &ExtensionId,
175 extensions: &WeakExtensionRegistry,
176 ) -> Self {
177 Self::MissingTypeExtension {
178 node,
179 ty: ty.clone(),
180 missing_extension: missing_extension.clone(),
181 available_extensions: extensions.ids().cloned().collect(),
182 }
183 }
184}
185
186#[derive(Debug, Display, Clone, Error, From, PartialEq)]
189#[non_exhaustive]
190pub enum ExtensionCollectionError<N: HugrNode = Node> {
191 #[display(
193 "{op}{} contains custom types for which have lost the reference to their defining extensions. Dropped extensions: {}",
194 if let Some(node) = node { format!(" ({node})") } else { String::new() },
195 missing_extensions.join(", ")
196 )]
197 DroppedOpExtensions {
198 node: Option<N>,
200 op: OpName,
202 missing_extensions: Vec<ExtensionId>,
204 },
205 #[display(
207 "Signature {signature} contains custom types for which have lost the reference to their defining extensions. Dropped extensions: {}",
208 missing_extensions.join(", ")
209 )]
210 DroppedSignatureExtensions {
211 signature: String,
213 missing_extensions: Vec<ExtensionId>,
215 },
216 #[display(
218 "Type {typ} contains custom types which have lost the reference to their defining extensions. Dropped extensions: {}",
219 missing_extensions.join(", ")
220 )]
221 #[from(ignore)]
222 DroppedTypeExtensions {
223 typ: String,
225 missing_extensions: Vec<ExtensionId>,
227 },
228}
229
230impl<N: HugrNode> ExtensionCollectionError<N> {
231 pub fn dropped_op_extension(
233 node: Option<N>,
234 op: &OpType,
235 missing_extension: impl IntoIterator<Item = ExtensionId>,
236 ) -> Self {
237 Self::DroppedOpExtensions {
238 node,
239 op: NamedOp::name(op),
240 missing_extensions: missing_extension.into_iter().collect(),
241 }
242 }
243
244 pub fn dropped_signature<RV: MaybeRV>(
246 signature: &FuncTypeBase<RV>,
247 missing_extension: impl IntoIterator<Item = ExtensionId>,
248 ) -> Self {
249 Self::DroppedSignatureExtensions {
250 signature: format!("{signature}"),
251 missing_extensions: missing_extension.into_iter().collect(),
252 }
253 }
254
255 pub fn dropped_type<RV: MaybeRV>(
257 typ: &TypeBase<RV>,
258 missing_extension: impl IntoIterator<Item = ExtensionId>,
259 ) -> Self {
260 Self::DroppedTypeExtensions {
261 typ: format!("{typ}"),
262 missing_extensions: missing_extension.into_iter().collect(),
263 }
264 }
265}
266
267#[cfg(test)]
268mod test;