Skip to content

Commit 7721747

Browse files
committed
Reference counted Terms.
1 parent db6c910 commit 7721747

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+1003
-610
lines changed

Cargo.lock

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,14 @@ members = [
1313
"hugr-py",
1414
"hugr-persistent",
1515
]
16-
default-members = ["hugr", "hugr-core", "hugr-passes", "hugr-cli", "hugr-model"]
16+
default-members = [
17+
"hugr",
18+
"hugr-core",
19+
"hugr-passes",
20+
"hugr-cli",
21+
"hugr-model",
22+
"hugr-llvm",
23+
]
1724

1825
[workspace.package]
1926
rust-version = "1.85"

hugr-core/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ semver = { workspace = true, features = ["serde"] }
6363
zstd = { workspace = true, optional = true }
6464
ordered-float = { workspace = true, features = ["serde"] }
6565
base64.workspace = true
66+
once_cell = "1.21.3"
67+
servo_arc = "0.4.1"
6668

6769
[dev-dependencies]
6870
rstest = { workspace = true }

hugr-core/src/export.rs

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! Exporting HUGR graphs to their `hugr-model` representation.
22
use crate::extension::ExtensionRegistry;
33
use crate::hugr::internal::HugrInternals;
4-
use crate::types::type_param::Term;
4+
use crate::types::type_param::{Term, TermEnum};
55
use crate::{
66
Direction, Hugr, HugrView, IncomingPort, Node, NodeIndex as _, Port,
77
extension::{ExtensionId, OpDef, SignatureFunc},
@@ -935,8 +935,8 @@ impl<'a> Context<'a> {
935935
t: &Term,
936936
var: Option<(table::NodeId, table::VarIndex)>,
937937
) -> table::TermId {
938-
match t {
939-
Term::RuntimeType(b) => {
938+
match t.get() {
939+
TermEnum::RuntimeType(b) => {
940940
if let (Some((node, index)), TypeBound::Copyable) = (var, b) {
941941
let term = self.make_term(table::Term::Var(table::VarId(node, index)));
942942
let non_linear = self.make_term_apply(model::CORE_NON_LINEAR, &[term]);
@@ -945,46 +945,47 @@ impl<'a> Context<'a> {
945945

946946
self.make_term_apply(model::CORE_TYPE, &[])
947947
}
948-
Term::BoundedNatType { .. } => self.make_term_apply(model::CORE_NAT_TYPE, &[]),
949-
Term::StringType => self.make_term_apply(model::CORE_STR_TYPE, &[]),
950-
Term::BytesType => self.make_term_apply(model::CORE_BYTES_TYPE, &[]),
951-
Term::FloatType => self.make_term_apply(model::CORE_FLOAT_TYPE, &[]),
952-
Term::ListType(item_type) => {
948+
TermEnum::BoundedNatType(_) => self.make_term_apply(model::CORE_NAT_TYPE, &[]),
949+
TermEnum::StringType => self.make_term_apply(model::CORE_STR_TYPE, &[]),
950+
TermEnum::BytesType => self.make_term_apply(model::CORE_BYTES_TYPE, &[]),
951+
TermEnum::FloatType => self.make_term_apply(model::CORE_FLOAT_TYPE, &[]),
952+
TermEnum::ListType(item_type) => {
953953
let item_type = self.export_term(item_type, None);
954954
self.make_term_apply(model::CORE_LIST_TYPE, &[item_type])
955955
}
956-
Term::TupleType(params) => {
956+
TermEnum::TupleType(item_types) => {
957957
let item_types = self.bump.alloc_slice_fill_iter(
958-
params
958+
item_types
959959
.iter()
960960
.map(|param| table::SeqPart::Item(self.export_term(param, None))),
961961
);
962962
let types = self.make_term(table::Term::List(item_types));
963963
self.make_term_apply(model::CORE_TUPLE_TYPE, &[types])
964964
}
965-
Term::Runtime(ty) => self.export_type(ty),
966-
Term::BoundedNat(value) => self.make_term(model::Literal::Nat(*value).into()),
967-
Term::String(value) => self.make_term(model::Literal::Str(value.into()).into()),
968-
Term::Float(value) => self.make_term(model::Literal::Float(*value).into()),
969-
Term::Bytes(value) => self.make_term(model::Literal::Bytes(value.clone()).into()),
970-
Term::List(elems) => {
965+
TermEnum::Runtime(ty) => self.export_type(ty),
966+
TermEnum::BoundedNat(value) => self.make_term(model::Literal::Nat(value).into()),
967+
TermEnum::String(value) => self.make_term(model::Literal::Str(value.into()).into()),
968+
TermEnum::Float(value) => self.make_term(model::Literal::Float(value).into()),
969+
TermEnum::Bytes(value) => self.make_term(model::Literal::Bytes(value.clone()).into()),
970+
TermEnum::List(elems) => {
971+
// For now we assume that the sequence is meant to be a list.
971972
let parts = self.bump.alloc_slice_fill_iter(
972973
elems
973974
.iter()
974975
.map(|elem| table::SeqPart::Item(self.export_term(elem, None))),
975976
);
976977
self.make_term(table::Term::List(parts))
977978
}
978-
Term::Tuple(elems) => {
979+
TermEnum::Tuple(elems) => {
979980
let parts = self.bump.alloc_slice_fill_iter(
980981
elems
981982
.iter()
982983
.map(|elem| table::SeqPart::Item(self.export_term(elem, None))),
983984
);
984985
self.make_term(table::Term::Tuple(parts))
985986
}
986-
Term::Variable(v) => self.export_type_arg_var(v),
987-
Term::StaticType => self.make_term_apply(model::CORE_STATIC, &[]),
987+
TermEnum::Variable(v) => self.export_type_arg_var(v),
988+
TermEnum::StaticType => self.make_term_apply(model::CORE_STATIC, &[]),
988989
}
989990
}
990991

hugr-core/src/extension/declarative/types.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ use std::sync::Weak;
1111

1212
use crate::Extension;
1313
use crate::extension::{TypeDef, TypeDefBound};
14-
use crate::types::type_param::TypeParam;
15-
use crate::types::{TypeBound, TypeName};
14+
use crate::types::type_param::{TermEnum, TypeParam};
15+
use crate::types::{Term, TypeBound, TypeName};
1616

1717
use serde::{Deserialize, Serialize};
1818

@@ -129,6 +129,6 @@ impl TypeParamDeclaration {
129129
_extension: &Extension,
130130
_ctx: DeclarationContext<'_>,
131131
) -> Result<TypeParam, ExtensionDeclarationError> {
132-
Ok(TypeParam::StringType)
132+
Ok(Term::new(TermEnum::StringType))
133133
}
134134
}

hugr-core/src/extension/op_def.rs

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,7 @@ pub(super) mod test {
544544
use std::num::NonZeroU64;
545545

546546
use itertools::Itertools;
547+
use once_cell::sync::Lazy;
547548

548549
use super::SignatureFromArgs;
549550
use crate::builder::{DFGBuilder, Dataflow, DataflowHugr, endo_sig};
@@ -554,7 +555,7 @@ pub(super) mod test {
554555
use crate::ops::OpName;
555556
use crate::std_extensions::collections::list;
556557
use crate::types::type_param::{TermTypeError, TypeParam};
557-
use crate::types::{PolyFuncTypeRV, Signature, Type, TypeArg, TypeBound, TypeRV};
558+
use crate::types::{PolyFuncTypeRV, Signature, Term, Type, TypeArg, TypeBound, TypeRV};
558559
use crate::{Extension, const_extension_ids};
559560

560561
const_extension_ids! {
@@ -656,10 +657,12 @@ pub(super) mod test {
656657
const OP_NAME: OpName = OpName::new_inline("Reverse");
657658

658659
let ext = Extension::try_new_test_arc(EXT_ID, |ext, extension_ref| {
659-
const TP: TypeParam = TypeParam::RuntimeType(TypeBound::Any);
660-
let list_of_var =
661-
Type::new_extension(list_def.instantiate(vec![TypeArg::new_var_use(0, TP)])?);
662-
let type_scheme = PolyFuncTypeRV::new(vec![TP], Signature::new_endo(vec![list_of_var]));
660+
let tp: TypeParam = TypeBound::Any.into();
661+
let list_of_var = Type::new_extension(
662+
list_def.instantiate(vec![TypeArg::new_var_use(0, tp.clone())])?,
663+
);
664+
let type_scheme =
665+
PolyFuncTypeRV::new(vec![tp.clone()], Signature::new_endo(vec![list_of_var]));
663666

664667
let def = ext.add_op(OP_NAME, "desc".into(), type_scheme, extension_ref)?;
665668
def.add_lower_func(LowerFunc::FixedHugr {
@@ -702,31 +705,34 @@ pub(super) mod test {
702705
&self,
703706
arg_values: &[TypeArg],
704707
) -> Result<PolyFuncTypeRV, SignatureError> {
705-
const TP: TypeParam = TypeParam::RuntimeType(TypeBound::Any);
706-
let [TypeArg::BoundedNat(n)] = arg_values else {
708+
let [n] = arg_values else {
709+
return Err(SignatureError::InvalidTypeArgs);
710+
};
711+
712+
let Some(n) = n.as_nat() else {
707713
return Err(SignatureError::InvalidTypeArgs);
708714
};
709-
let n = *n as usize;
715+
710716
let tvs: Vec<Type> = (0..n)
711717
.map(|_| Type::new_var_use(0, TypeBound::Any))
712718
.collect();
713719
Ok(PolyFuncTypeRV::new(
714-
vec![TP.clone()],
720+
vec![TypeBound::Any.into()],
715721
Signature::new(tvs.clone(), vec![Type::new_tuple(tvs)]),
716722
))
717723
}
718724

719725
fn static_params(&self) -> &[TypeParam] {
720-
const MAX_NAT: &[TypeParam] = &[TypeParam::max_nat_type()];
721-
MAX_NAT
726+
static MAX_NAT: Lazy<[Term; 1]> = Lazy::new(|| [Term::max_nat_type()]);
727+
&*MAX_NAT
722728
}
723729
}
724730
let _ext = Extension::try_new_test_arc(EXT_ID, |ext, extension_ref| {
725731
let def: &mut crate::extension::OpDef =
726732
ext.add_op("MyOp".into(), String::new(), SigFun(), extension_ref)?;
727733

728734
// Base case, no type variables:
729-
let args = [TypeArg::BoundedNat(3), usize_t().into()];
735+
let args = [Term::from(3u64), usize_t().into()];
730736
assert_eq!(
731737
def.compute_signature(&args),
732738
Ok(Signature::new(
@@ -739,7 +745,7 @@ pub(super) mod test {
739745
// Second arg may be a variable (substitutable)
740746
let tyvar = Type::new_var_use(0, TypeBound::Copyable);
741747
let tyvars: Vec<Type> = vec![tyvar.clone(); 3];
742-
let args = [TypeArg::BoundedNat(3), tyvar.clone().into()];
748+
let args = [Term::from(3u64), tyvar.clone().into()];
743749
assert_eq!(
744750
def.compute_signature(&args),
745751
Ok(Signature::new(
@@ -797,7 +803,7 @@ pub(super) mod test {
797803
extension_ref,
798804
)?;
799805
let tv = Type::new_var_use(0, TypeBound::Copyable);
800-
let args = [tv.clone().into()];
806+
let args = [Term::from(tv.clone())];
801807
let decls = [TypeBound::Copyable.into()];
802808
def.validate_args(&args, &decls).unwrap();
803809
assert_eq!(def.compute_signature(&args), Ok(Signature::new_endo(tv)));

hugr-core/src/extension/prelude.rs

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use crate::extension::{
1616
use crate::ops::OpName;
1717
use crate::ops::constant::{CustomCheckFailure, CustomConst, ValueName};
1818
use crate::ops::{NamedOp, Value};
19-
use crate::types::type_param::{TypeArg, TypeParam};
19+
use crate::types::type_param::{TermEnum, TypeArg, TypeParam};
2020
use crate::types::{
2121
CustomType, FuncValueType, PolyFuncType, PolyFuncTypeRV, Signature, SumType, Term, Type,
2222
TypeBound, TypeName, TypeRV, TypeRow, TypeRowRV,
@@ -175,7 +175,7 @@ pub fn bool_t() -> Type {
175175
/// Name of the prelude panic operation.
176176
///
177177
/// This operation can have any input and any output wires; it is instantiated
178-
/// with two [`TypeArg::List`]s representing these. The first input to the
178+
/// with two lists of runtime types representing these. The first input to the
179179
/// operation is always an error type; the remaining inputs correspond to the
180180
/// first sequence of types in its instantiation; the outputs correspond to the
181181
/// second sequence of types in its instantiation. Note that the inputs and
@@ -189,7 +189,7 @@ pub const PANIC_OP_ID: OpName = OpName::new_inline("panic");
189189
/// Name of the prelude exit operation.
190190
///
191191
/// This operation can have any input and any output wires; it is instantiated
192-
/// with two [`TypeArg::List`]s representing these. The first input to the
192+
/// with two lists of types representing these. The first input to the
193193
/// operation is always an error type; the remaining inputs correspond to the
194194
/// first sequence of types in its instantiation; the outputs correspond to the
195195
/// second sequence of types in its instantiation. Note that the inputs and
@@ -678,21 +678,21 @@ impl MakeExtensionOp for MakeTuple {
678678
if def != TupleOpDef::MakeTuple {
679679
return Err(OpLoadError::NotMember(ext_op.unqualified_id().to_string()))?;
680680
}
681-
let [TypeArg::List(elems)] = ext_op.args() else {
681+
let [item_types] = ext_op.args() else {
682+
return Err(SignatureError::InvalidTypeArgs)?;
683+
};
684+
let TermEnum::List(elems) = item_types.get() else {
682685
return Err(SignatureError::InvalidTypeArgs)?;
683686
};
684687
let tys: Result<Vec<Type>, _> = elems
685688
.iter()
686-
.map(|a| match a {
687-
TypeArg::Runtime(ty) => Ok(ty.clone()),
688-
_ => Err(SignatureError::InvalidTypeArgs),
689-
})
689+
.map(|a| a.as_runtime().ok_or(SignatureError::InvalidTypeArgs))
690690
.collect();
691691
Ok(Self(tys?.into()))
692692
}
693693

694694
fn type_args(&self) -> Vec<TypeArg> {
695-
vec![Term::new_list(self.0.iter().map(|t| t.clone().into()))]
695+
vec![Term::new_list(self.0.iter().cloned().map(Term::from))]
696696
}
697697
}
698698

@@ -733,21 +733,21 @@ impl MakeExtensionOp for UnpackTuple {
733733
if def != TupleOpDef::UnpackTuple {
734734
return Err(OpLoadError::NotMember(ext_op.unqualified_id().to_string()))?;
735735
}
736-
let [Term::List(elems)] = ext_op.args() else {
736+
let [item_types] = ext_op.args() else {
737+
return Err(SignatureError::InvalidTypeArgs)?;
738+
};
739+
let TermEnum::List(elems) = item_types.get() else {
737740
return Err(SignatureError::InvalidTypeArgs)?;
738741
};
739742
let tys: Result<Vec<Type>, _> = elems
740743
.iter()
741-
.map(|a| match a {
742-
Term::Runtime(ty) => Ok(ty.clone()),
743-
_ => Err(SignatureError::InvalidTypeArgs),
744-
})
744+
.map(|a| a.as_runtime().ok_or(SignatureError::InvalidTypeArgs))
745745
.collect();
746746
Ok(Self(tys?.into()))
747747
}
748748

749-
fn type_args(&self) -> Vec<Term> {
750-
vec![Term::new_list(self.0.iter().map(|t| t.clone().into()))]
749+
fn type_args(&self) -> Vec<TypeArg> {
750+
vec![Term::new_list(self.0.iter().cloned().map(Term::from))]
751751
}
752752
}
753753

@@ -851,10 +851,13 @@ impl MakeExtensionOp for Noop {
851851
Self: Sized,
852852
{
853853
let _def = NoopDef::from_def(ext_op.def())?;
854-
let [TypeArg::Runtime(ty)] = ext_op.args() else {
854+
let [ty] = ext_op.args() else {
855855
return Err(SignatureError::InvalidTypeArgs)?;
856856
};
857-
Ok(Self(ty.clone()))
857+
858+
let ty = ty.as_runtime().ok_or(SignatureError::InvalidTypeArgs)?;
859+
860+
Ok(Self(ty))
858861
}
859862

860863
fn type_args(&self) -> Vec<TypeArg> {
@@ -957,24 +960,24 @@ impl MakeExtensionOp for Barrier {
957960
{
958961
let _def = BarrierDef::from_def(ext_op.def())?;
959962

960-
let [TypeArg::List(elems)] = ext_op.args() else {
963+
let [item_types] = ext_op.args() else {
964+
return Err(SignatureError::InvalidTypeArgs)?;
965+
};
966+
let TermEnum::List(elems) = item_types.get() else {
961967
return Err(SignatureError::InvalidTypeArgs)?;
962968
};
963969
let tys: Result<Vec<Type>, _> = elems
964970
.iter()
965-
.map(|a| match a {
966-
TypeArg::Runtime(ty) => Ok(ty.clone()),
967-
_ => Err(SignatureError::InvalidTypeArgs),
968-
})
971+
.map(|a| a.as_runtime().ok_or(SignatureError::InvalidTypeArgs))
969972
.collect();
970973
Ok(Self {
971974
type_row: tys?.into(),
972975
})
973976
}
974977

975978
fn type_args(&self) -> Vec<TypeArg> {
976-
vec![TypeArg::new_list(
977-
self.type_row.iter().map(|t| t.clone().into()),
979+
vec![Term::new_list(
980+
self.type_row.iter().cloned().map(Term::from),
978981
)]
979982
}
980983
}

0 commit comments

Comments
 (0)