1mod extension;
20mod ops;
21mod types;
22mod types_mut;
23mod weak_registry;
24
25pub use weak_registry::WeakExtensionRegistry;
26
27pub(crate) use ops::{collect_op_extension, resolve_op_extensions};
28pub(crate) use types::{collect_op_types_extensions, collect_signature_exts, collect_type_exts};
29pub(crate) use types_mut::resolve_op_types_extensions;
30use types_mut::{
31 resolve_custom_type_exts, resolve_term_exts, resolve_type_exts, resolve_value_exts,
32};
33
34use derive_more::{Display, Error, From};
35
36use super::{Extension, ExtensionId, ExtensionRegistry, ExtensionSet};
37use crate::Node;
38use crate::core::HugrNode;
39use crate::ops::constant::ValueName;
40use crate::ops::custom::OpaqueOpError;
41use crate::ops::{NamedOp, OpName, OpType, Value};
42use crate::types::{CustomType, FuncTypeBase, MaybeRV, TypeArg, TypeBase, TypeName};
43
44pub fn resolve_type_extensions<RV: MaybeRV>(
46 typ: &mut TypeBase<RV>,
47 extensions: &WeakExtensionRegistry,
48) -> Result<(), ExtensionResolutionError> {
49 let mut used_extensions = WeakExtensionRegistry::default();
50 resolve_type_exts(None, typ, extensions, &mut used_extensions)
51}
52
53pub fn resolve_custom_type_extensions(
55 typ: &mut CustomType,
56 extensions: &WeakExtensionRegistry,
57) -> Result<(), ExtensionResolutionError> {
58 let mut used_extensions = WeakExtensionRegistry::default();
59 resolve_custom_type_exts(None, typ, extensions, &mut used_extensions)
60}
61
62pub fn resolve_typearg_extensions(
64 arg: &mut TypeArg,
65 extensions: &WeakExtensionRegistry,
66) -> Result<(), ExtensionResolutionError> {
67 let mut used_extensions = WeakExtensionRegistry::default();
68 resolve_term_exts(None, arg, extensions, &mut used_extensions)
69}
70
71pub fn resolve_value_extensions(
73 value: &mut Value,
74 extensions: &WeakExtensionRegistry,
75) -> Result<(), ExtensionResolutionError> {
76 let mut used_extensions = WeakExtensionRegistry::default();
77 resolve_value_exts(None, value, extensions, &mut used_extensions)
78}
79
80#[derive(Debug, Display, Clone, Error, From, PartialEq)]
82#[non_exhaustive]
83pub enum ExtensionResolutionError<N: HugrNode = Node> {
84 #[display("Error resolving opaque operation: {_0}")]
86 #[from]
87 OpaqueOpError(OpaqueOpError<N>),
88 #[display(
90 "{op}{} requires extension {missing_extension}, but it could not be found in the extension list used during resolution. The available extensions are: {}",
91 node.map(|n| format!(" in {n}")).unwrap_or_default(),
92 available_extensions.join(", ")
93 )]
94 MissingOpExtension {
95 node: Option<N>,
97 op: OpName,
99 missing_extension: ExtensionId,
101 available_extensions: Vec<ExtensionId>,
103 },
104 #[display(
106 "Type {ty}{} requires extension {missing_extension}, but it could not be found in the extension list used during resolution. The available extensions are: {}",
107 node.map(|n| format!(" in {n}")).unwrap_or_default(),
108 available_extensions.join(", ")
109 )]
110 MissingTypeExtension {
111 node: Option<N>,
113 ty: TypeName,
115 missing_extension: ExtensionId,
117 available_extensions: Vec<ExtensionId>,
119 },
120 #[display(
122 "Type definition {def} in extension {extension} declares it was defined in {wrong_extension} instead."
123 )]
124 WrongTypeDefExtension {
125 extension: ExtensionId,
127 def: TypeName,
129 wrong_extension: ExtensionId,
131 },
132 #[display(
134 "Operation definition {def} in extension {extension} declares it was defined in {wrong_extension} instead."
135 )]
136 WrongOpDefExtension {
137 extension: ExtensionId,
139 def: OpName,
141 wrong_extension: ExtensionId,
143 },
144 #[display(
146 "The type of the opaque value '{value}' requires extensions {missing_extensions}, but does not reference their definition."
147 )]
148 InvalidConstTypes {
149 value: ValueName,
151 missing_extensions: ExtensionSet,
153 },
154}
155
156impl<N: HugrNode> ExtensionResolutionError<N> {
157 pub fn missing_op_extension(
159 node: Option<N>,
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<N>,
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, PartialEq)]
190#[non_exhaustive]
191pub enum ExtensionCollectionError<N: HugrNode = Node> {
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 { String::new() },
196 missing_extensions.join(", ")
197 )]
198 DroppedOpExtensions {
199 node: Option<N>,
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 #[display(
219 "Type {typ} contains custom types which have lost the reference to their defining extensions. Dropped extensions: {}",
220 missing_extensions.join(", ")
221 )]
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;