diff --git a/guppylang/prelude/builtins.py b/guppylang/prelude/builtins.py index 486dda11..57130818 100644 --- a/guppylang/prelude/builtins.py +++ b/guppylang/prelude/builtins.py @@ -569,6 +569,11 @@ class SizedIter: Annotating an iterator with an incorrect size is undefined behaviour. """ + def __class_getitem__(cls, item: Any) -> type: + # Dummy implementation to allow subscripting of the `SizedIter` type in + # positions that are evaluated by the Python interpreter + return cls + @guppy.custom(NoopCompiler()) def __new__(iterator: L @ owned) -> "SizedIter[L, n]": # type: ignore[type-arg] """Casts an iterator into a `SizedIter`.""" diff --git a/tests/integration/test_range.py b/tests/integration/test_range.py index 32d33a61..da9104c4 100644 --- a/tests/integration/test_range.py +++ b/tests/integration/test_range.py @@ -1,5 +1,5 @@ from guppylang.decorator import guppy -from guppylang.prelude.builtins import nat, range +from guppylang.prelude.builtins import nat, range, SizedIter, Range from guppylang.module import GuppyModule from tests.util import compile_guppy @@ -20,7 +20,27 @@ def negative() -> int: total += 100 + x return total + @guppy(module) + def non_static() -> int: + total = 0 + n = 4 + for x in range(n + 1): + total += x + 100 # Make the initial 0 obvious + return total + compiled = module.compile() validate(compiled) run_int_fn(compiled, expected=510) run_int_fn(compiled, expected=0, fn_name="negative") + run_int_fn(compiled, expected=510, fn_name="non_static") + + +def test_static_size(validate): + module = GuppyModule("test") + + @guppy(module) + def negative() -> SizedIter[Range, 10]: + return range(10) + + validate(module.compile()) +