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, From, PartialEq)]
191#[non_exhaustive]
192pub enum ExtensionCollectionError<N: HugrNode = Node> {
193 #[display(
195 "{op}{} contains custom types for which have lost the reference to their defining extensions. Dropped extensions: {}",
196 if let Some(node) = node { format!(" ({node})") } else { String::new() },
197 missing_extensions.join(", ")
198 )]
199 DroppedOpExtensions {
200 node: Option<N>,
202 op: OpName,
204 missing_extensions: Vec<ExtensionId>,
206 },
207 #[display(
209 "Signature {signature} contains custom types for which have lost the reference to their defining extensions. Dropped extensions: {}",
210 missing_extensions.join(", ")
211 )]
212 DroppedSignatureExtensions {
213 signature: String,
215 missing_extensions: Vec<ExtensionId>,
217 },
218 #[display(
220 "Type {typ} contains custom types which have lost the reference to their defining extensions. Dropped extensions: {}",
221 missing_extensions.join(", ")
222 )]
223 #[from(ignore)]
224 DroppedTypeExtensions {
225 typ: String,
227 missing_extensions: Vec<ExtensionId>,
229 },
230}
231
232impl<N: HugrNode> ExtensionCollectionError<N> {
233 pub fn dropped_op_extension(
235 node: Option<N>,
236 op: &OpType,
237 missing_extension: impl IntoIterator<Item = ExtensionId>,
238 ) -> Self {
239 Self::DroppedOpExtensions {
240 node,
241 op: NamedOp::name(op),
242 missing_extensions: missing_extension.into_iter().collect(),
243 }
244 }
245
246 pub fn dropped_signature<RV: MaybeRV>(
248 signature: &FuncTypeBase<RV>,
249 missing_extension: impl IntoIterator<Item = ExtensionId>,
250 ) -> Self {
251 Self::DroppedSignatureExtensions {
252 signature: format!("{signature}"),
253 missing_extensions: missing_extension.into_iter().collect(),
254 }
255 }
256
257 pub fn dropped_type<RV: MaybeRV>(
259 typ: &TypeBase<RV>,
260 missing_extension: impl IntoIterator<Item = ExtensionId>,
261 ) -> Self {
262 Self::DroppedTypeExtensions {
263 typ: format!("{typ}"),
264 missing_extensions: missing_extension.into_iter().collect(),
265 }
266 }
267}
268
269#[cfg(test)]
270mod test;