Read a creator's IList return level in build

This commit is contained in:
Dennis Kobert
2026-08-14 08:11:59 +00:00
parent 849d6a17be
commit 3e183fbd28

View File

@@ -78,12 +78,12 @@ fn subject(index: usize, field: &ParsedField, carrier_subject: bool, routing: Op
}
fn output(parsed: &ParsedNodeFn, generics: &[Ident]) -> Output {
let value = slot_value_type(&parsed.output_type);
let (element, writes, removes) = match record_writes(&value) {
// Strip the `IList` rank markers first so the write set is read from the row.
let (row, depth) = strip_ilist(&slot_value_type(&parsed.output_type));
let (element, writes, removes) = match record_writes(&row) {
Some(RecordWrites { element, markers, removes }) => (element, markers, removes),
None => (value, Vec::new(), Vec::new()),
None => (row, Vec::new(), Vec::new()),
};
let (element, depth) = strip_ilist(&element);
Output {
shape: ItemShape {
element: element_of(&element, generics),
@@ -736,6 +736,24 @@ mod tests {
);
}
#[test]
fn creator_ilist_return_pushes_a_level() {
let mut parsed = parse_node_fn(
quote!(category(""), extent(repeat_extent)),
quote!(fn repeat<T>(_: impl Ctx, (element, transform): (T, Attr<Transform>), count: u32) -> IList<(T, Attr<Transform>)> { emit(element, Attr(count as f64)) }),
)
.unwrap();
parsed.replace_impl_trait_in_input();
let node = build(&parsed);
// The `IList` return pushes one rank level, with the element and the
// written attribute read from the stripped row.
assert_eq!(node.output.shape.depth, 1);
assert!(matches!(node.output.shape.element, Element::Generic(_)));
assert_eq!(markers(node.output.shape.attrs.iter().map(|attr| &attr.marker)), vec!["Transform".to_string()]);
let subject_depth = node.inputs.iter().find(|input| input.subject).map_or(0, |input| input.shape.depth);
assert_eq!(node.output.shape.depth as i8 - subject_depth as i8, 1, "creator level_delta is +1");
}
#[test]
fn monomorphizations_key_by_generic() {
let node = assert_bridge(