Skip to content

2/2: Add enumerate() to DSLX stdlib#4022

Merged
copybara-service[bot] merged 7 commits into
google:mainfrom
antmicro:remove-builtin-enumerate
May 21, 2026
Merged

2/2: Add enumerate() to DSLX stdlib#4022
copybara-service[bot] merged 7 commits into
google:mainfrom
antmicro:remove-builtin-enumerate

Conversation

@joannabrozek
Copy link
Copy Markdown
Contributor

The second of two PRs responsible for migrating from the built-in enumerate, which cannot be lowered to IR.

This PR includes: removing the build-in enumerate.

@mikex-oss
Copy link
Copy Markdown
Collaborator

Aside from obvious updates to use std:enumerate, I'm seeing the following error in a bunch of our targets.

Not sure yet how to repro this in a small standalone test.

xls/dslx/stdlib/std.x:20:13-20:19
0018: 
0019: pub fn enumerate<T: type, N: u32>(x: T[N]) -> (u32, T)[N] {
0020:     for (i, result) in 0..N {
~~~~~~~~~~~~~~~~~~^----^ TypeInferenceError: TypeInferenceError: xls/dslx/stdlib/std.x:20:13-20:19 Annotated array size is too small for explicit element count.. The body of function `enumerate` does not actually return the function's declared return type, which is `(u32, u32)[N]`
0021:         update(result, i, (i, x[i]))
0022:     }([(u32:0, zero!<T>()), ...])
Error: INVALID_ARGUMENT: TypeInferenceError: xls/dslx/stdlib/std.x:20:13-20:19 TypeInferenceError: xls/dslx/stdlib/std.x:20:13-20:19 Annotated array size is too small for explicit element count.. The body of function `enumerate` does not actually return the function's declared return type, which is `(u32, u32)[N]`
=== Source Location Trace: === 
xls/dslx/errors.cc:48
xls/dslx/type_system_v2/type_annotation_resolver.cc:325
xls/dslx/type_system_v2/inference_table_converter_impl.cc:1077
xls/dslx/type_system_v2/inference_table_converter_impl.cc:269
xls/dslx/type_system_v2/inference_table_converter_impl.cc:884
xls/dslx/type_system_v2/inference_table_converter_impl.cc:245
xls/dslx/type_system_v2/inference_table_converter_impl.cc:884
xls/dslx/type_system_v2/inference_table_converter_impl.cc:245
xls/dslx/type_system_v2/inference_table_converter_impl.cc:2007
xls/dslx/type_system_v2/inference_table_converter_impl.cc:1750
xls/dslx/type_system_v2/inference_table_converter_impl.cc:1835
xls/dslx/type_system_v2/inference_table_converter_impl.cc:737
xls/dslx/type_system_v2/inference_table_converter_impl.cc:245
xls/dslx/import_routines.cc:247
xls/dslx/type_system_v2/populate_table_visitor.cc:136
xls/dslx/type_system_v2/populate_table_visitor.cc:1939
xls/dslx/type_system_v2/typecheck_module_v2.cc:89
xls/dslx/import_routines.cc:247
xls/dslx/type_system_v2/populate_table_visitor.cc:136
xls/dslx/type_system_v2/populate_table_visitor.cc:1939
xls/dslx/type_system_v2/typecheck_module_v2.cc:89
xls/dslx/import_routines.cc:247
xls/dslx/type_system_v2/populate_table_visitor.cc:136
xls/dslx/type_system_v2/populate_table_visitor.cc:1939
xls/dslx/type_system_v2/typecheck_module_v2.cc:89
xls/dslx/parse_and_typecheck.cc:126
xls/dslx/ir_convert/ir_converter.cc:697
xls/dslx/ir_convert/ir_converter_main.cc:159

@erinzmoore
Copy link
Copy Markdown
Contributor

I believe I was able to reproduce the issue by testing with an empty array, for example:

#[test]
fn emumerate_test() {
    ...

    let empty_array : u32[0] = [];
    let enumerated_empty = enumerate(empty_array);
    assert_eq(enumerated_empty, []);
}

I tried to see if I could fix this with a const if in the enumerate implementation and it also failed, which may be a separate issue:

pub fn enumerate<T: type, N: u32>(x: T[N]) -> (u32, T)[N] {
    const if N == 0 {
      (u32, T)[0]:[]
    } else {
      for (i, result) in 0..N {
          update(result, i, (i, x[i]))
      }((u32, T)[N]:[(u32:0, zero!<T>()), ...])
    }
}

@joannabrozek joannabrozek force-pushed the remove-builtin-enumerate branch 2 times, most recently from 77a0507 to 6c17e74 Compare April 30, 2026 11:24
@joannabrozek
Copy link
Copy Markdown
Contributor Author

@erinzmoore, thank you for the test to reproduce the issue.

I've added more commits to this PR to provide support for empty array enumeration:

Please let me know if this solved the issue on your side as well.

TypecheckSucceeds(HasNodeWithType("X", "sN[16][8]")));
}

TEST(TypecheckV2Test, RangeExprEmptyRange) {
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.

It seems like here and in other test files, we should keep empty range/array tests but change the assertions to expect success, and add a const_assert! in the DSLX that expects it to be empty.

We should also add tests for an empty range with the start being the max of the type, for both signed and unsigned, because there is some logic which normalizes exclusive ranges by converting them into inclusive with end + 1.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I restored RangeExprEmptyRange test and added two more to the same file.

@joannabrozek joannabrozek force-pushed the remove-builtin-enumerate branch from 6c17e74 to b3ba97c Compare May 7, 2026 11:37
@joannabrozek
Copy link
Copy Markdown
Contributor Author

@richmckeever, thank you for the review. I've rebased the code and added the suggested tests. Let me know if there's still something missing.

@proppy
Copy link
Copy Markdown
Member

proppy commented May 21, 2026

do we also need to update documentation and samples?

@copybara-service copybara-service Bot merged commit 6f2ebef into google:main May 21, 2026
6 checks passed
@magancarz
Copy link
Copy Markdown
Contributor

@proppy I've opened a pull request with enumerate docs update in #4326 and also one for removal of obsolete builtin test in #4327.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants