Skip to content
Merged
Show file tree
Hide file tree
Changes from 85 commits
Commits
Show all changes
95 commits
Select commit Hold shift + click to select a range
3ec0890
Remove TypeRow(RV) from Type(RV), add from <const N: usize> [Type(RV)…
acl-cqc Jan 1, 2026
7e65a1b
Merge remote-tracking branch 'origin/main' into acl/no_1type_row
acl-cqc Jan 30, 2026
33618ba
Grab most type_param.rs changes
acl-cqc Feb 16, 2026
d383d39
And copy much of type_row.rs too
acl-cqc Feb 16, 2026
a3a5f2c
Remove TypeEnum, RowVar, MaybeRV, etc.
acl-cqc Feb 16, 2026
92083e2
GeneralSum (w/out bound), serialize.rs
acl-cqc Feb 23, 2026
ae898bd
copy signature.rs/poly_func.rs
acl-cqc Feb 16, 2026
c88231e
A bunch of others...onto another stage of typechecking
acl-cqc Feb 18, 2026
6948450
WIP types.rs/type_param.rs, conversions, etc.
acl-cqc Feb 23, 2026
94625c2
collections (matches vs TypeArg::Runtime), pub(crate) Term::lub/copyable
acl-cqc Feb 24, 2026
b7fc0b8
updates to hugr-passes; non-test code builds
acl-cqc Feb 24, 2026
041d536
many test fixes, except new_tuple
acl-cqc Feb 24, 2026
73c4cec
new_tuple takes term; tests compile; fix prelude
acl-cqc Feb 24, 2026
cc22ad5
clippy+fmt
acl-cqc Feb 24, 2026
573d59d
fix some tests, revert signature of SumType::new_tuple, Display for T…
acl-cqc Feb 25, 2026
9c43e4b
fix serialization of GeneralSum
acl-cqc Feb 25, 2026
57d7edf
Move as_sum/as_extension into Term; fmt; doc new_row_var_use
acl-cqc Feb 25, 2026
86b1e89
hugr-llvm
acl-cqc Feb 25, 2026
e10f2c5
docs
acl-cqc Feb 25, 2026
af2a6f9
clippy+benchmarks
acl-cqc Feb 25, 2026
8805064
update hugr-llvm snapshots
acl-cqc Feb 25, 2026
b996510
update snapshots more
acl-cqc Feb 25, 2026
4f7be66
Remove TypeRV (use Term)
acl-cqc Feb 25, 2026
0ac2b53
Make TypeRowRV a struct (the only panicking new); rm GeneralSum, SerT…
acl-cqc Feb 25, 2026
c563bde
docs
acl-cqc Feb 25, 2026
cfed69d
comment re. Type::validate
acl-cqc Feb 26, 2026
2b231ae
Merge remote-tracking branch 'origin/main' into acl/no_1type_row
acl-cqc Mar 11, 2026
3cbda59
Merge remote-tracking branch 'origin/main' into acl/no_1type_row
acl-cqc Mar 11, 2026
88a0c0d
move validate/substitute into trait Substitutable
acl-cqc Mar 12, 2026
62e67d9
Reparametrize signature
acl-cqc Mar 12, 2026
f42f66e
Add PartialEq<TypeRowRV> for TypeRow
acl-cqc Mar 12, 2026
9035f6b
Reintroduce parametrized PolyFuncTypeBase...problems with deriving AR…
acl-cqc Mar 12, 2026
cfe35bf
Manually impl the ARbitrary's, it's straightforward even if tedious
acl-cqc Mar 12, 2026
21d1db9
Move Substitutable into internals module to fix private_bounds warning
acl-cqc Mar 13, 2026
531719e
doc
acl-cqc Mar 13, 2026
16b4c5e
Merge branch 'acl/no_1type_row' into acl/type_wraps_term
acl-cqc Mar 13, 2026
34cb99d
Fix json-encoding of type variables (showed only in extension defs)
acl-cqc Mar 13, 2026
2962d96
TypeRowRV::new() is const no-args; use try_from, but use safe ctors more
acl-cqc Mar 13, 2026
2471156
fix doctests
acl-cqc Apr 2, 2026
07862d3
Use ? to convert TermTypeError -> SignatureError (*1)
acl-cqc Apr 2, 2026
cb877d0
Add From<TermTypeError> for OpLoadError
acl-cqc Apr 2, 2026
2864663
impl From<TermTypeError> for ImportErrorInner
acl-cqc Apr 2, 2026
c0badc6
Merge remote-tracking branch 'origin/main' into acl/type_wraps_term
acl-cqc Apr 3, 2026
83d9bde
reduce change to benchmark
acl-cqc Apr 3, 2026
77a74c5
Try "optimizing"(?) import_signature not to import_func_type
acl-cqc Apr 3, 2026
c5011b8
Expand doc-comment for Term
acl-cqc Apr 3, 2026
001055b
dataflow test no_outer_row_variables: use TypeRowRV::just_row_var to …
acl-cqc Apr 3, 2026
a764d14
small tweaks + change reduction
acl-cqc Apr 3, 2026
2641710
Arbitrary for TypeRowRV includes row vars; test Term<->TypeRowRV roun…
acl-cqc Apr 3, 2026
35ff825
avoid unwrap in validate/test row_variables
acl-cqc Apr 3, 2026
3ad01d7
more conversion tests
acl-cqc Apr 3, 2026
d71c564
controlflow.rs: pull out tup_ty
acl-cqc Apr 3, 2026
092ba1f
undo rename in array_scan...clarified code but confused change
acl-cqc Apr 3, 2026
3c612d7
Reduce change in poly_func.rs by parametrizing everything by Substitu…
acl-cqc Apr 3, 2026
fb063c1
comments in serialize.rs
acl-cqc Apr 3, 2026
f71314c
serialize.rs: revert TypeArgSer to contain Type not SerSimpleType...c…
acl-cqc Apr 3, 2026
d489a3e
signature.rs: remove bogus comment in Arbitrary
acl-cqc Apr 3, 2026
bf41550
export.rs: restore export_poly_func_type and export_func_type but bot…
acl-cqc Apr 5, 2026
6e354fd
Revert change to export_sum_variants
acl-cqc Apr 5, 2026
397a778
import.rs: reparametrize import_func_type, revert adding import_signa…
acl-cqc Apr 5, 2026
f8ee718
type_param.rs: bogus comment re. Term::List/TypeRow
acl-cqc Apr 6, 2026
9a64b77
type_param.rs tweaks
acl-cqc Apr 6, 2026
fb501c2
type_param.rs test tidies
acl-cqc Apr 6, 2026
cef21cd
type_param.rs doc-comment on validate
acl-cqc Apr 6, 2026
0cd842e
typerow.rs docs
acl-cqc Apr 7, 2026
e0004c0
TypeRowRV::is_empty, hide Term::is_empty_list
acl-cqc Apr 7, 2026
3a25e6e
Revert accidental widening of as_option() return-type, should be Opti…
acl-cqc Apr 7, 2026
c1fb66a
types.rs: comments
acl-cqc Apr 7, 2026
1c19ce2
types.rs: Arbitrary: use TypeRowRV not TypeRow; revert to using .as_e…
acl-cqc Apr 7, 2026
1ef81e5
Revert SumType::as_tuple -> return Opt<&TypeRowRV>
acl-cqc Apr 7, 2026
e58209f
types/custom.rs: unnecessary doc ref
acl-cqc Apr 7, 2026
749786f
Implement Substitutable only for TypeRow(RV)
acl-cqc Apr 7, 2026
e44bae7
Rename Substitutable -> TypeRowLike, move into type_row.rs
acl-cqc Apr 7, 2026
3a3bd42
type_param.rs: reduce change, move subst/validate back
acl-cqc Apr 7, 2026
2697658
drop From<SumType/CustomType> for Term
acl-cqc Apr 7, 2026
90b9fe3
easy comment removals
acl-cqc Apr 10, 2026
ca3aa2f
TypeRowRV::just_row_var=>new_var_use
acl-cqc Apr 10, 2026
983470b
Generalize Term::new_list, adding Term::EMPTY_LIST; simplify many places
acl-cqc Apr 10, 2026
b67372a
Remove impl From<Vec<Type>> for Term, and also from array
acl-cqc Apr 10, 2026
3cd0f44
hugr-llvm: use anyhow not expect
acl-cqc Apr 10, 2026
272a866
Move TypeRowRV stuff later
acl-cqc Apr 10, 2026
414e579
TypeRowRV: only from Vec or array of Type, not any IntoIter
acl-cqc Apr 10, 2026
3a41dda
FromIterator for both TypeRowRV and TypeRow
acl-cqc Apr 10, 2026
4646a1a
remove another ALAN
acl-cqc Apr 10, 2026
80f1934
comment out get_alias_type and friends
acl-cqc Apr 10, 2026
c301ffd
driveby fix to Term::substitute
acl-cqc Apr 27, 2026
43fedc2
hide TypeRowRV::new_unchecked
acl-cqc Apr 27, 2026
903ca84
Remove new_unchecked, use try_into+expect until shown to be performan…
acl-cqc Apr 28, 2026
9fe64c5
missing display specifier for Term::RuntimeExtension
acl-cqc Apr 28, 2026
9bc14d8
todo alias -> unimplemented
acl-cqc Apr 28, 2026
984cfba
fmt
acl-cqc Apr 28, 2026
884684e
remove commented-out references to aliases
acl-cqc Apr 28, 2026
aa82fb6
Merge remote-tracking branch 'origin/main' into acl/type_wraps_term
acl-cqc Apr 28, 2026
a00561c
More remove commented-out references to aliases
acl-cqc May 5, 2026
07490ea
Merge remote-tracking branch 'origin/main' into acl/type_wraps_term
acl-cqc May 5, 2026
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
29 changes: 20 additions & 9 deletions hugr-core/src/builder/dataflow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -481,8 +481,8 @@ pub(crate) mod test {
use crate::metadata::Metadata;
use crate::ops::{FuncDecl, FuncDefn, OpParent, OpTag, OpTrait, Value, handle::NodeHandle};
use crate::std_extensions::logic::test::and_op;
use crate::types::type_param::TypeParam;
use crate::types::{EdgeKind, FuncValueType, RowVariable, Signature, Type, TypeBound, TypeRV};
use crate::types::type_param::{TermTypeError, TypeParam};
use crate::types::{EdgeKind, FuncValueType, Signature, Term, Type, TypeBound, TypeRowRV};
use crate::utils::test_quantum_extension::h_gate;
use crate::{Wire, builder::test::n_identity, type_row};

Expand Down Expand Up @@ -926,7 +926,7 @@ pub(crate) mod test {
#[test]
fn no_outer_row_variables() -> Result<(), BuildError> {
let e = crate::hugr::validate::test::extension_with_eval_parallel();
let tv = TypeRV::new_row_var_use(0, TypeBound::Copyable);
let rv = TypeRowRV::new_var_use(0, TypeBound::Copyable);
// Can *declare* a function that takes a function-value of unknown #args
FunctionBuilder::new(
"bad_eval",
Expand All @@ -935,23 +935,34 @@ pub(crate) mod test {
Signature::new(
[Type::new_function(FuncValueType::new(
[usize_t()],
[tv.clone()],
rv.clone(),
))],
[],
),
),
)?;

let rv: Term = rv.into();
// But cannot eval it...
let ev = e.instantiate_extension_op("eval", [Term::new_list([usize_t()]), rv.clone()]);
assert_eq!(
ev,
Err(SignatureError::TypeArgMismatch(
TermTypeError::InvalidValue(Box::new(rv.clone()))
))
);

let ev = e.instantiate_extension_op(
"eval",
[vec![usize_t().into()].into(), vec![tv.into()].into()],
[Term::new_list([usize_t()]), Term::new_list([rv.clone()])],
);
assert_eq!(
ev,
Err(SignatureError::RowVarWhereTypeExpected {
var: RowVariable(0, TypeBound::Copyable)
})
Err(SignatureError::TypeArgMismatch(
TermTypeError::TypeMismatch {
term: Box::new(rv),
type_: Box::new(TypeBound::Linear.into())
}
))
);
Ok(())
}
Expand Down
6 changes: 3 additions & 3 deletions hugr-core/src/builder/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ mod test {
use cool_asserts::assert_matches;

use crate::builder::test::dfg_calling_defn_decl;
use crate::builder::{Dataflow, DataflowSubContainer, test::n_identity};
use crate::builder::{Dataflow, DataflowSubContainer};
use crate::extension::prelude::usize_t;
use crate::{hugr::linking::NodeLinkingDirective, ops::OpType, types::Signature};

Expand All @@ -331,7 +331,7 @@ mod test {
Ok(())
}

#[test]
/*#[test]
#[ignore] // https://github.com/Quantinuum/hugr/issues/2828
fn simple_alias() -> Result<(), BuildError> {
let build_result = {
Expand All @@ -352,7 +352,7 @@ mod test {
};
assert_matches!(build_result, Ok(_));
Ok(())
}
}*/

#[test]
fn builder_from_existing() -> Result<(), BuildError> {
Expand Down
95 changes: 42 additions & 53 deletions hugr-core/src/export.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
use crate::Visibility;
use crate::extension::ExtensionRegistry;
use crate::hugr::internal::HugrInternals;
use crate::types::type_param::Term;
use crate::types::{FuncTypeBase, PolyFuncTypeBase, TypeRowLike};
use crate::{
Direction, Hugr, HugrView, IncomingPort, Node, NodeIndex as _, Port,
extension::{ExtensionId, OpDef, SignatureFunc},
Expand All @@ -14,10 +14,8 @@ use crate::{
arithmetic::{float_types::ConstF64, int_types::ConstInt},
collections::array::ArrayValue,
},
types::{
CustomType, EdgeKind, FuncTypeBase, MaybeRV, PolyFuncTypeBase, RowVariable, SumType,
TypeBase, TypeBound, TypeEnum, type_param::TermVar, type_row::TypeRowBase,
},
types::type_param::{Term, TermVar},
types::{CustomType, EdgeKind, SumType, Type, TypeBound, TypeRow},
};

use hugr_model::v0::bumpalo;
Expand Down Expand Up @@ -342,10 +340,12 @@ impl<'a> Context<'a> {
OpType::FuncDefn(func) => self.with_local_scope(node_id, |this| {
let symbol_name = this.export_func_name(node, &mut meta);

let sig = func.signature();
let symbol = this.export_poly_func_type(
symbol_name,
Some(func.visibility().clone().into()),
func.signature(),
sig,
Self::export_type_row,
);
regions = this.bump.alloc_slice_copy(&[this.export_dfg(
node,
Expand All @@ -358,11 +358,12 @@ impl<'a> Context<'a> {

OpType::FuncDecl(func) => self.with_local_scope(node_id, |this| {
let symbol_name = this.export_func_name(node, &mut meta);

let sig = func.signature();
let symbol = this.export_poly_func_type(
symbol_name,
Some(func.visibility().clone().into()),
func.signature(),
sig,
Self::export_type_row,
);
table::Operation::DeclareFunc(symbol)
}),
Expand Down Expand Up @@ -507,7 +508,7 @@ impl<'a> Context<'a> {
Some(signature) => {
let num_inputs = signature.input_types().len();
let num_outputs = signature.output_types().len();
let signature = self.export_func_type(signature);
let signature = self.export_func_type(signature, Self::export_type_row);
(Some(signature), num_inputs, num_outputs)
}
None => (None, 0, 0),
Expand Down Expand Up @@ -559,7 +560,9 @@ impl<'a> Context<'a> {

let symbol = self.with_local_scope(node, |this| {
let name = this.make_qualified_name(opdef.extension_id(), opdef.name());
this.export_poly_func_type(name, None, poly_func_type)
this.export_poly_func_type(name, None, poly_func_type, |this, trv| {
this.export_term(trv, None)
})
});

let meta = {
Expand Down Expand Up @@ -816,11 +819,12 @@ impl<'a> Context<'a> {
}

/// Exports a polymorphic function type.
pub fn export_poly_func_type<RV: MaybeRV>(
pub fn export_poly_func_type<T: TypeRowLike>(
&mut self,
name: &'a str,
visibility: Option<model::Visibility>,
t: &PolyFuncTypeBase<RV>,
t: &PolyFuncTypeBase<T>,
export_io: impl FnMut(&mut Self, &T) -> table::TermId,
) -> &'a table::Symbol<'a> {
let mut params = BumpVec::with_capacity_in(t.params().len(), self.bump);
let scope = self
Expand All @@ -835,7 +839,7 @@ impl<'a> Context<'a> {
}

let constraints = self.bump.alloc_slice_copy(&self.local_constraints);
let body = self.export_func_type(t.body());
let body = self.export_func_type(t.body(), export_io);

self.bump.alloc(table::Symbol {
visibility,
Expand All @@ -846,30 +850,18 @@ impl<'a> Context<'a> {
})
}

pub fn export_type<RV: MaybeRV>(&mut self, t: &TypeBase<RV>) -> table::TermId {
self.export_type_enum(t.as_type_enum())
}

pub fn export_type_enum<RV: MaybeRV>(&mut self, t: &TypeEnum<RV>) -> table::TermId {
match t {
TypeEnum::Extension(ext) => self.export_custom_type(ext),
TypeEnum::Alias(alias) => {
let symbol = self.resolve_symbol(self.bump.alloc_str(alias.name()));
self.make_term(table::Term::Apply(symbol, &[]))
}
TypeEnum::Function(func) => self.export_func_type(func),
TypeEnum::Variable(index, _) => {
let node = self.local_scope.expect("local variable out of scope");
self.make_term(table::Term::Var(table::VarId(node, *index as _)))
}
TypeEnum::RowVar(rv) => self.export_row_var(rv.as_rv()),
TypeEnum::Sum(sum) => self.export_sum_type(sum),
}
pub fn export_type(&mut self, t: &Type) -> table::TermId {
self.export_term(t, None)
}

pub fn export_func_type<RV: MaybeRV>(&mut self, t: &FuncTypeBase<RV>) -> table::TermId {
let inputs = self.export_type_row(t.input());
let outputs = self.export_type_row(t.output());
pub fn export_func_type<T: TypeRowLike>(
&mut self,
t: &FuncTypeBase<T>,
mut export_io: impl FnMut(&mut Self, &T) -> table::TermId,
) -> table::TermId {
let inputs = export_io(self, t.input());
let outputs = export_io(self, t.output());
// To use CORE_FN here, the input/output should each be a core List or ListConcat
self.make_term_apply(model::CORE_FN, &[inputs, outputs])
}

Expand All @@ -888,11 +880,6 @@ impl<'a> Context<'a> {
self.make_term(table::Term::Var(table::VarId(node, var.index() as _)))
}

pub fn export_row_var(&mut self, t: &RowVariable) -> table::TermId {
let node = self.local_scope.expect("local variable out of scope");
self.make_term(table::Term::Var(table::VarId(node, t.0 as _)))
}

pub fn export_sum_variants(&mut self, t: &SumType) -> table::TermId {
match t {
SumType::Unit { size } => {
Expand All @@ -905,7 +892,7 @@ impl<'a> Context<'a> {
SumType::General { rows } => {
let parts = self.bump.alloc_slice_fill_iter(
rows.iter()
.map(|row| table::SeqPart::Item(self.export_type_row(row))),
.map(|row| table::SeqPart::Item(self.export_term(row, None))),
);
self.make_term(table::Term::List(parts))
}
Expand All @@ -918,27 +905,20 @@ impl<'a> Context<'a> {
}

#[inline]
pub fn export_type_row<RV: MaybeRV>(&mut self, row: &TypeRowBase<RV>) -> table::TermId {
pub fn export_type_row(&mut self, row: &TypeRow) -> table::TermId {
self.export_type_row_with_tail(row, None)
}

pub fn export_type_row_with_tail<RV: MaybeRV>(
pub fn export_type_row_with_tail(
Comment thread
acl-cqc marked this conversation as resolved.
&mut self,
row: &TypeRowBase<RV>,
row: &TypeRow,
tail: Option<table::TermId>,
) -> table::TermId {
let mut parts =
BumpVec::with_capacity_in(row.len() + usize::from(tail.is_some()), self.bump);

for t in row.iter() {
match t.as_type_enum() {
TypeEnum::RowVar(var) => {
parts.push(table::SeqPart::Splice(self.export_row_var(var.as_rv())));
}
_ => {
parts.push(table::SeqPart::Item(self.export_type(t)));
}
}
parts.push(table::SeqPart::Item(self.export_type(t)));
}

if let Some(tail) = tail {
Expand Down Expand Up @@ -982,7 +962,16 @@ impl<'a> Context<'a> {
let item_types = self.export_term(item_types, None);
self.make_term_apply(model::CORE_TUPLE_TYPE, &[item_types])
}
Term::Runtime(ty) => self.export_type(ty),
Term::RuntimeExtension(ext) => self.export_custom_type(ext),
/*TypeEnum::Alias(alias) => {
let symbol = self.resolve_symbol(self.bump.alloc_str(alias.name()));
self.make_term(table::Term::Apply(symbol, &[]))
}*/
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/*TypeEnum::Alias(alias) => {
let symbol = self.resolve_symbol(self.bump.alloc_str(alias.name()));
self.make_term(table::Term::Apply(symbol, &[]))
}*/

Term::RuntimeFunction(func) => {
self.export_func_type(func, |this, trv| this.export_term(trv, None))
}
Term::RuntimeSum(sum) => self.export_sum_type(sum),

Term::BoundedNat(value) => self.make_term(model::Literal::Nat(*value).into()),
Term::String(value) => self.make_term(model::Literal::Str(value.into()).into()),
Term::Float(value) => self.make_term(model::Literal::Float(*value).into()),
Expand Down
4 changes: 0 additions & 4 deletions hugr-core/src/extension.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,6 @@ use thiserror::Error;
use crate::hugr::IdentList;
use crate::ops::custom::{ExtensionOp, OpaqueOp};
use crate::ops::{OpName, OpNameRef};
use crate::types::RowVariable;
use crate::types::type_param::{TermTypeError, TypeArg, TypeParam};
use crate::types::{CustomType, TypeBound, TypeName};
use crate::types::{Signature, TypeNameRef};
Expand Down Expand Up @@ -518,9 +517,6 @@ pub enum SignatureError {
/// A type variable that was used has not been declared
#[error("Type variable {idx} was not declared ({num_decls} in scope)")]
FreeTypeVar { idx: usize, num_decls: usize },
/// A row variable was found outside of a variable-length row
#[error("Expected a single type, but found row variable {var}")]
RowVarWhereTypeExpected { var: RowVariable },
/// The result of the type application stored in a [Call]
/// is not what we get by applying the type-args to the polymorphic function
///
Expand Down
4 changes: 2 additions & 2 deletions hugr-core/src/extension/op_def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -614,7 +614,7 @@ pub(super) mod test {
use crate::package::Package;
use crate::std_extensions::collections::list;
use crate::types::type_param::{TermTypeError, TypeParam};
use crate::types::{PolyFuncTypeRV, Signature, Type, TypeArg, TypeBound, TypeRV};
use crate::types::{PolyFuncTypeRV, Signature, Term, Type, TypeArg, TypeBound};
use crate::{Extension, const_extension_ids};

const_extension_ids! {
Expand Down Expand Up @@ -862,7 +862,7 @@ pub(super) mod test {
def.validate_args(&args, &decls).unwrap();
assert_eq!(def.compute_signature(&args), Ok(Signature::new_endo([tv])));
// But not with an external row variable
let arg: TypeArg = TypeRV::new_row_var_use(0, TypeBound::Copyable).into();
let arg: TypeArg = Term::new_row_var_use(0, TypeBound::Copyable);
assert_eq!(
def.compute_signature(std::slice::from_ref(&arg)),
Err(SignatureError::TypeArgMismatch(
Expand Down
Loading
Loading