diff --git a/hugr-core/src/export.rs b/hugr-core/src/export.rs index 8bae0f1cdc..e8dcfa33db 100644 --- a/hugr-core/src/export.rs +++ b/hugr-core/src/export.rs @@ -883,6 +883,7 @@ impl<'a> Context<'a> { self.make_term(table::Term::Tuple(parts)) } TypeArg::Variable { v } => self.export_type_arg_var(v), + TypeArg::Param { param } => self.export_type_param(param, None), } } @@ -991,6 +992,7 @@ impl<'a> Context<'a> { let types = self.make_term(table::Term::List(parts)); self.make_term_apply(model::CORE_TUPLE_TYPE, &[types]) } + TypeParam::Static => self.make_term_apply(model::CORE_STATIC, &[]), } } diff --git a/hugr-core/src/import.rs b/hugr-core/src/import.rs index 3336439f21..37fd7b5d3e 100644 --- a/hugr-core/src/import.rs +++ b/hugr-core/src/import.rs @@ -1027,29 +1027,12 @@ impl<'a> Context<'a> { return Ok(TypeParam::max_nat()); } - if let Some([]) = self.match_symbol(term_id, model::CORE_BYTES_TYPE)? { - return Err(error_unsupported!( - "`{}` as `TypeParam`", - model::CORE_BYTES_TYPE - )); - } - - if let Some([]) = self.match_symbol(term_id, model::CORE_FLOAT_TYPE)? { - return Err(error_unsupported!( - "`{}` as `TypeParam`", - model::CORE_FLOAT_TYPE - )); - } - if let Some([]) = self.match_symbol(term_id, model::CORE_TYPE)? { return Ok(TypeParam::Type { b: bound }); } if let Some([]) = self.match_symbol(term_id, model::CORE_STATIC)? { - return Err(error_unsupported!( - "`{}` as `TypeParam`", - model::CORE_STATIC - )); + return Ok(TypeParam::Static); } if let Some([]) = self.match_symbol(term_id, model::CORE_CONSTRAINT)? { @@ -1102,35 +1085,23 @@ impl<'a> Context<'a> { /// Import a `TypeArg` from a term that represents a static type or value. fn import_type_arg(&mut self, term_id: table::TermId) -> Result { if let Some([]) = self.match_symbol(term_id, model::CORE_STR_TYPE)? { - return Err(error_unsupported!( - "`{}` as `TypeArg`", - model::CORE_STR_TYPE - )); + return Ok(TypeParam::String.into()); } if let Some([]) = self.match_symbol(term_id, model::CORE_NAT_TYPE)? { - return Err(error_unsupported!( - "`{}` as `TypeArg`", - model::CORE_NAT_TYPE - )); + return Ok(TypeParam::max_nat().into()); } if let Some([]) = self.match_symbol(term_id, model::CORE_BYTES_TYPE)? { - return Err(error_unsupported!( - "`{}` as `TypeArg`", - model::CORE_BYTES_TYPE - )); + return Ok(TypeParam::Bytes.into()); } if let Some([]) = self.match_symbol(term_id, model::CORE_FLOAT_TYPE)? { - return Err(error_unsupported!( - "`{}` as `TypeArg`", - model::CORE_FLOAT_TYPE - )); + return Ok(TypeParam::Float.into()); } if let Some([]) = self.match_symbol(term_id, model::CORE_TYPE)? { - return Err(error_unsupported!("`{}` as `TypeArg`", model::CORE_TYPE)); + return Ok(TypeParam::Type { b: TypeBound::Any }.into()); } if let Some([]) = self.match_symbol(term_id, model::CORE_CONSTRAINT)? { @@ -1141,7 +1112,7 @@ impl<'a> Context<'a> { } if let Some([]) = self.match_symbol(term_id, model::CORE_STATIC)? { - return Err(error_unsupported!("`{}` as `TypeArg`", model::CORE_STATIC)); + return Ok(TypeParam::Static.into()); } if let Some([]) = self.match_symbol(term_id, model::CORE_CTRL_TYPE)? { @@ -1155,11 +1126,9 @@ impl<'a> Context<'a> { return Err(error_unsupported!("`{}` as `TypeArg`", model::CORE_CONST)); } - if let Some([]) = self.match_symbol(term_id, model::CORE_LIST_TYPE)? { - return Err(error_unsupported!( - "`{}` as `TypeArg`", - model::CORE_LIST_TYPE - )); + if let Some([item_type]) = self.match_symbol(term_id, model::CORE_LIST_TYPE)? { + let param = Box::new(self.import_type_param(item_type, TypeBound::Any)?); + return Ok(TypeParam::List { param }.into()); } match self.get_term(term_id)? { diff --git a/hugr-core/src/types/type_param.rs b/hugr-core/src/types/type_param.rs index 75e60e2de5..3d45d92677 100644 --- a/hugr-core/src/types/type_param.rs +++ b/hugr-core/src/types/type_param.rs @@ -98,6 +98,8 @@ pub enum TypeParam { /// The [`TypeParam`]s contained in the tuple. params: Vec, }, + /// The type of static types. + Static, } impl TypeParam { @@ -131,6 +133,9 @@ impl TypeParam { b1.contains(b2) } (TypeParam::String, TypeParam::String) => true, + (TypeParam::Float, TypeParam::Float) => true, + (TypeParam::Bytes, TypeParam::Bytes) => true, + (TypeParam::Static, TypeParam::Static) => true, (TypeParam::List { param: e1 }, TypeParam::List { param: e2 }) => e1.contains(e2), (TypeParam::Tuple { params: es1 }, TypeParam::Tuple { params: es2 }) => { es1.len() == es2.len() && es1.iter().zip(es2).all(|(e1, e2)| e1.contains(e2)) @@ -217,6 +222,11 @@ pub enum TypeArg { #[serde(flatten)] v: TypeArgVariable, }, + /// A static type passed as a parameter. + Param { + /// The static type. + param: Box, + }, } impl From> for TypeArg { @@ -254,6 +264,14 @@ impl From> for TypeArg { } } +impl From for TypeArg { + fn from(param: TypeParam) -> Self { + Self::Param { + param: Box::new(param), + } + } +} + /// Variable in a `TypeArg`, that is not a single [`TypeArg::Type`] (i.e. not a [`Type::new_var_use`] /// - it might be a [`Type::new_row_var_use`]). #[derive( @@ -339,6 +357,10 @@ impl TypeArg { check_typevar_decl(var_decls, *idx, cached_decl) } + TypeArg::Param { .. } => { + // TODO: Is there a validate method for this? + Ok(()) + } } } @@ -384,6 +406,10 @@ impl TypeArg { TypeArg::Variable { v: TypeArgVariable { idx, cached_decl }, } => t.apply_var(*idx, cached_decl), + TypeArg::Param { .. } => { + // TODO: There needs to be a substitute method on `TypeParam`s. + todo!() + } } } } @@ -399,6 +425,10 @@ impl Transformable for TypeArg { | TypeArg::Variable { .. } | TypeArg::Float { .. } | TypeArg::Bytes { .. } => Ok(false), + TypeArg::Param { param } => { + // TODO: There needs to a be transform method on `TypeParam`s. + todo!() + } } } }