Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions hugr-core/src/export.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
}
}

Expand Down Expand Up @@ -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, &[]),
}
}

Expand Down
51 changes: 10 additions & 41 deletions hugr-core/src/import.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)? {
Expand Down Expand Up @@ -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<TypeArg, ImportError> {
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)? {
Expand All @@ -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)? {
Expand All @@ -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)? {
Expand Down
30 changes: 30 additions & 0 deletions hugr-core/src/types/type_param.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ pub enum TypeParam {
/// The [`TypeParam`]s contained in the tuple.
params: Vec<TypeParam>,
},
/// The type of static types.
Static,
}

impl TypeParam {
Expand Down Expand Up @@ -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))
Expand Down Expand Up @@ -217,6 +222,11 @@ pub enum TypeArg {
#[serde(flatten)]
v: TypeArgVariable,
},
/// A static type passed as a parameter.
Param {
/// The static type.
param: Box<TypeParam>,
},
}

impl<RV: MaybeRV> From<TypeBase<RV>> for TypeArg {
Expand Down Expand Up @@ -254,6 +264,14 @@ impl From<Vec<TypeArg>> for TypeArg {
}
}

impl From<TypeParam> 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(
Expand Down Expand Up @@ -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(())
}
}
}

Expand Down Expand Up @@ -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!()
}
}
}
}
Expand All @@ -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!()
}
}
}
}
Expand Down