Repository: amaranth-lang/amaranth (python)

Issue:
Wrong shape computed for `range(0, 10, 3)`
```
>>> list(range(0, 10, 3))
[0, 3, 6, 9]
>>> Shape.cast(range(0, 10, 3))
unsigned(3)
>>> Const(9, Shape.cast(range(0, 10, 3)))
(const 3'd1)
```

Pull request:
hdl.ast: fix range handling in `Shape.cast`.
Fixes #803.

Patch:
diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml
index b39619d..c627ad8 100644
--- a/.github/workflows/main.yaml
+++ b/.github/workflows/main.yaml
@@ -1,4 +1,4 @@
-on: [push, pull_request]
+on: [push, pull_request, merge_group]
 name: CI
 jobs:
   test:
diff --git a/amaranth/hdl/ast.py b/amaranth/hdl/ast.py
index cbf2e60..c844627 100644
--- a/amaranth/hdl/ast.py
+++ b/amaranth/hdl/ast.py
@@ -117,9 +117,9 @@ class Shape:
             elif isinstance(obj, range):
                 if len(obj) == 0:
                     return Shape(0, obj.start < 0)
-                signed = obj.start < 0 or (obj.stop - obj.step) < 0
-                width  = max(bits_for(obj.start, signed),
-                             bits_for(obj.stop - obj.step, signed))
+                signed = obj[0] < 0 or obj[-1] < 0
+                width  = max(bits_for(obj[0], signed),
+                             bits_for(obj[-1], signed))
                 return Shape(width, signed)
             elif isinstance(obj, type) and issubclass(obj, Enum):
                 # For compatibility with third party enumerations, handle them as if they were


Test patch:
diff --git a/tests/test_hdl_ast.py b/tests/test_hdl_ast.py
index 65f2404..012f77e 100644
--- a/tests/test_hdl_ast.py
+++ b/tests/test_hdl_ast.py
@@ -117,6 +117,9 @@ class ShapeTestCase(FHDLTestCase):
         s7 = Shape.cast(range(-1, -1))
         self.assertEqual(s7.width, 0)
         self.assertEqual(s7.signed, True)
+        s8 = Shape.cast(range(0, 10, 3))
+        self.assertEqual(s8.width, 4)
+        self.assertEqual(s8.signed, False)
 
     def test_cast_enum(self):
         s1 = Shape.cast(UnsignedEnum)