mod extension;
mod ops;
mod types;
mod types_mut;
mod weak_registry;
pub use weak_registry::WeakExtensionRegistry;
pub(crate) use ops::{collect_op_extension, resolve_op_extensions};
pub(crate) use types::{collect_op_types_extensions, collect_signature_exts};
pub(crate) use types_mut::resolve_op_types_extensions;
use types_mut::{
resolve_custom_type_exts, resolve_type_exts, resolve_typearg_exts, resolve_value_exts,
};
use derive_more::{Display, Error, From};
use super::{Extension, ExtensionId, ExtensionRegistry, ExtensionSet};
use crate::ops::constant::ValueName;
use crate::ops::custom::OpaqueOpError;
use crate::ops::{NamedOp, OpName, OpType, Value};
use crate::types::{CustomType, FuncTypeBase, MaybeRV, TypeArg, TypeBase, TypeName};
use crate::Node;
pub fn resolve_type_extensions<RV: MaybeRV>(
typ: &mut TypeBase<RV>,
extensions: &WeakExtensionRegistry,
) -> Result<(), ExtensionResolutionError> {
let mut used_extensions = WeakExtensionRegistry::default();
resolve_type_exts(None, typ, extensions, &mut used_extensions)
}
pub fn resolve_custom_type_extensions(
typ: &mut CustomType,
extensions: &WeakExtensionRegistry,
) -> Result<(), ExtensionResolutionError> {
let mut used_extensions = WeakExtensionRegistry::default();
resolve_custom_type_exts(None, typ, extensions, &mut used_extensions)
}
pub fn resolve_typearg_extensions(
arg: &mut TypeArg,
extensions: &WeakExtensionRegistry,
) -> Result<(), ExtensionResolutionError> {
let mut used_extensions = WeakExtensionRegistry::default();
resolve_typearg_exts(None, arg, extensions, &mut used_extensions)
}
pub fn resolve_value_extensions(
value: &mut Value,
extensions: &WeakExtensionRegistry,
) -> Result<(), ExtensionResolutionError> {
let mut used_extensions = WeakExtensionRegistry::default();
resolve_value_exts(None, value, extensions, &mut used_extensions)
}
#[derive(Debug, Display, Clone, Error, From, PartialEq)]
#[non_exhaustive]
pub enum ExtensionResolutionError {
#[display("Error resolving opaque operation: {_0}")]
#[from]
OpaqueOpError(OpaqueOpError),
#[display(
"{op}{} requires extension {missing_extension}, but it could not be found in the extension list used during resolution. The available extensions are: {}",
node.map(|n| format!(" in {}", n)).unwrap_or_default(),
available_extensions.join(", ")
)]
MissingOpExtension {
node: Option<Node>,
op: OpName,
missing_extension: ExtensionId,
available_extensions: Vec<ExtensionId>,
},
#[display(
"Type {ty}{} requires extension {missing_extension}, but it could not be found in the extension list used during resolution. The available extensions are: {}",
node.map(|n| format!(" in {}", n)).unwrap_or_default(),
available_extensions.join(", ")
)]
MissingTypeExtension {
node: Option<Node>,
ty: TypeName,
missing_extension: ExtensionId,
available_extensions: Vec<ExtensionId>,
},
#[display(
"Type definition {def} in extension {extension} declares it was defined in {wrong_extension} instead."
)]
WrongTypeDefExtension {
extension: ExtensionId,
def: TypeName,
wrong_extension: ExtensionId,
},
#[display(
"Operation definition {def} in extension {extension} declares it was defined in {wrong_extension} instead."
)]
WrongOpDefExtension {
extension: ExtensionId,
def: OpName,
wrong_extension: ExtensionId,
},
#[display("The type of the opaque value '{value}' requires extensions {missing_extensions}, but does not reference their definition.")]
InvalidConstTypes {
value: ValueName,
missing_extensions: ExtensionSet,
},
}
impl ExtensionResolutionError {
pub fn missing_op_extension(
node: Option<Node>,
op: &OpType,
missing_extension: &ExtensionId,
extensions: &ExtensionRegistry,
) -> Self {
Self::MissingOpExtension {
node,
op: NamedOp::name(op),
missing_extension: missing_extension.clone(),
available_extensions: extensions.ids().cloned().collect(),
}
}
pub fn missing_type_extension(
node: Option<Node>,
ty: &TypeName,
missing_extension: &ExtensionId,
extensions: &WeakExtensionRegistry,
) -> Self {
Self::MissingTypeExtension {
node,
ty: ty.clone(),
missing_extension: missing_extension.clone(),
available_extensions: extensions.ids().cloned().collect(),
}
}
}
#[derive(Debug, Display, Clone, Error, From, PartialEq)]
#[non_exhaustive]
pub enum ExtensionCollectionError {
#[display(
"{op}{} contains custom types for which have lost the reference to their defining extensions. Dropped extensions: {}",
if let Some(node) = node { format!(" ({})", node) } else { "".to_string() },
missing_extensions.join(", ")
)]
DroppedOpExtensions {
node: Option<Node>,
op: OpName,
missing_extensions: Vec<ExtensionId>,
},
#[display(
"Signature {signature} contains custom types for which have lost the reference to their defining extensions. Dropped extensions: {}",
missing_extensions.join(", ")
)]
DroppedSignatureExtensions {
signature: String,
missing_extensions: Vec<ExtensionId>,
},
}
impl ExtensionCollectionError {
pub fn dropped_op_extension(
node: Option<Node>,
op: &OpType,
missing_extension: impl IntoIterator<Item = ExtensionId>,
) -> Self {
Self::DroppedOpExtensions {
node,
op: NamedOp::name(op),
missing_extensions: missing_extension.into_iter().collect(),
}
}
pub fn dropped_signature<RV: MaybeRV>(
signature: &FuncTypeBase<RV>,
missing_extension: impl IntoIterator<Item = ExtensionId>,
) -> Self {
Self::DroppedSignatureExtensions {
signature: format!("{signature}"),
missing_extensions: missing_extension.into_iter().collect(),
}
}
}
#[cfg(test)]
mod test;