Skip to content

Commit 731081f

Browse files
authored
feat!: Improved array lowering (#2109)
Feature branch for improved array lowering. * The old `array` type is now called `value_array` and lives in a separate extension * The default `array` is now a linear type with additional `clone` and `discard` operations * To avoid code duplication, array operations and values are now defined generically over a new `ArrayKind` trait that is instantiated with `Array` (the linear one) and `VArray` (the copyable one) to generate the `array` and `value_array` extensions * An `array<n, T>` is now lowered to a fat pointer `{ptr, usize}` where `ptr` is a heap allocated pointer of size at least `n * sizeof(T)` and the `usize` is an offset pointing to the first element (i.e. the first element is at `ptr + offset * sizeof(T)`). The rational behind the additional offset is the `pop_left` operation which bumps the offset instead of mutating the pointer. This way, we can still free the original pointer when the array is discarded after a pop. Tracked PRs: * #2097 (closes #2066) * #2100 * #2101 * #2110 * #2112 (closes #2067) * #2119 * #2125 (closes #2124) BREAKING CHANGE: `std.collections.array` is now a linear type, even if the contained elements are copyable. Use the new `std.collections.value_array` for an array with the previous copyable semantics. BREAKING CHANGE: `std.collections.array.get` now also returns the passed array as an extra output BREAKING CHANGE: `ArrayOpBuilder` was moved from `hugr_core::std_extensions::collections::array::op_builder` to `hugr_core::std_extensions::collections::array`.
1 parent 20081dd commit 731081f

Some content is hidden

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

41 files changed

+6017
-1364
lines changed

Cargo.lock

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

hugr-core/src/ops/constant.rs

+26
Original file line numberDiff line numberDiff line change
@@ -585,6 +585,7 @@ pub(crate) mod test {
585585
use crate::extension::PRELUDE;
586586
use crate::std_extensions::arithmetic::int_types::ConstInt;
587587
use crate::std_extensions::collections::array::{array_type, ArrayValue};
588+
use crate::std_extensions::collections::value_array::{value_array_type, VArrayValue};
588589
use crate::{
589590
builder::{BuildError, DFGBuilder, Dataflow, DataflowHugr},
590591
extension::{
@@ -754,6 +755,11 @@ pub(crate) mod test {
754755
ArrayValue::new(bool_t(), [Value::true_val(), Value::false_val()]).into()
755756
}
756757

758+
#[fixture]
759+
fn const_value_array_bool() -> Value {
760+
VArrayValue::new(bool_t(), [Value::true_val(), Value::false_val()]).into()
761+
}
762+
757763
#[fixture]
758764
fn const_array_options() -> Value {
759765
let some_true = Value::some([Value::true_val()]);
@@ -762,17 +768,35 @@ pub(crate) mod test {
762768
ArrayValue::new(elem_ty.into(), [some_true, none]).into()
763769
}
764770

771+
#[fixture]
772+
fn const_value_array_options() -> Value {
773+
let some_true = Value::some([Value::true_val()]);
774+
let none = Value::none(vec![bool_t()]);
775+
let elem_ty = SumType::new_option(vec![bool_t()]);
776+
VArrayValue::new(elem_ty.into(), [some_true, none]).into()
777+
}
778+
765779
#[rstest]
766780
#[case(Value::unit(), Type::UNIT, "const:seq:{}")]
767781
#[case(const_usize(), usize_t(), "const:custom:ConstUsize(")]
768782
#[case(serialized_float(17.4), float64_type(), "const:custom:json:Object")]
769783
#[case(const_tuple(), Type::new_tuple(vec![usize_t(), bool_t()]), "const:seq:{")]
770784
#[case(const_array_bool(), array_type(2, bool_t()), "const:custom:array")]
785+
#[case(
786+
const_value_array_bool(),
787+
value_array_type(2, bool_t()),
788+
"const:custom:value_array"
789+
)]
771790
#[case(
772791
const_array_options(),
773792
array_type(2, SumType::new_option(vec![bool_t()]).into()),
774793
"const:custom:array"
775794
)]
795+
#[case(
796+
const_value_array_options(),
797+
value_array_type(2, SumType::new_option(vec![bool_t()]).into()),
798+
"const:custom:value_array"
799+
)]
776800
fn const_type(
777801
#[case] const_value: Value,
778802
#[case] expected_type: Type,
@@ -792,7 +816,9 @@ pub(crate) mod test {
792816
#[case(const_serialized_usize(), const_usize())]
793817
#[case(const_tuple_serialized(), const_tuple())]
794818
#[case(const_array_bool(), const_array_bool())]
819+
#[case(const_value_array_bool(), const_value_array_bool())]
795820
#[case(const_array_options(), const_array_options())]
821+
#[case(const_value_array_options(), const_value_array_options())]
796822
// Opaque constants don't get resolved into concrete types when running miri,
797823
// as the `typetag` machinery is not available.
798824
#[cfg_attr(miri, ignore)]

hugr-core/src/std_extensions.rs

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ pub fn std_reg() -> ExtensionRegistry {
2121
collections::array::EXTENSION.to_owned(),
2222
collections::list::EXTENSION.to_owned(),
2323
collections::static_array::EXTENSION.to_owned(),
24+
collections::value_array::EXTENSION.to_owned(),
2425
logic::EXTENSION.to_owned(),
2526
ptr::EXTENSION.to_owned(),
2627
]);

hugr-core/src/std_extensions/collections.rs

+1
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@
33
pub mod array;
44
pub mod list;
55
pub mod static_array;
6+
pub mod value_array;

0 commit comments

Comments
 (0)