Skip to content

Commit c4bbcc6

Browse files
wanda-phiwhitequark
authored andcommitted
hdl._ast: enforce the ShapeCastable.const contract in Const().
1 parent 5577f4e commit c4bbcc6

File tree

5 files changed

+18
-11
lines changed

5 files changed

+18
-11
lines changed

amaranth/hdl/_ast.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1503,7 +1503,13 @@ def __new__(cls, *args, **kwargs):
15031503
class _ConstMeta(ABCMeta):
15041504
def __call__(cls, value, shape=None, src_loc_at=0, **kwargs):
15051505
if isinstance(shape, ShapeCastable):
1506-
return shape.const(value)
1506+
value = shape.const(value)
1507+
cast_shape = Shape.cast(shape)
1508+
cast_value = Const.cast(value)
1509+
if cast_value.shape() != cast_shape:
1510+
raise ValueError(f"Constant returned by {shape!r}.const() must have the shape that "
1511+
f"it casts to, {cast_shape!r}, and not {cast_value.shape()!r}")
1512+
return value
15071513
return super().__call__(value, shape, **kwargs, src_loc_at=src_loc_at + 1)
15081514

15091515

amaranth/lib/data.py

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -223,12 +223,7 @@ def const(self, init):
223223
field = self[key]
224224
cast_field_shape = Shape.cast(field.shape)
225225
if isinstance(field.shape, ShapeCastable):
226-
key_value = hdl.Const.cast(field.shape.const(key_value))
227-
if key_value.shape() != cast_field_shape:
228-
raise ValueError("Constant returned by {!r}.const() must have the shape that "
229-
"it casts to, {!r}, and not {!r}"
230-
.format(field.shape, cast_field_shape,
231-
key_value.shape()))
226+
key_value = hdl.Const.cast(hdl.Const(key_value, field.shape))
232227
elif not isinstance(key_value, hdl.Const):
233228
key_value = hdl.Const(key_value, cast_field_shape)
234229
mask = ((1 << cast_field_shape.width) - 1) << field.offset

amaranth/lib/memory.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ def __init__(self, elems, *, shape, depth):
8383

8484
if isinstance(shape, ShapeCastable):
8585
self._elems = [None] * depth
86-
self._raw = [Const.cast(shape.const(None)).value] * depth
86+
self._raw = [Const.cast(Const(None, shape)).value] * depth
8787
else:
8888
self._elems = [0] * depth
8989
self._raw = self._elems # intentionally mutably aliased
@@ -113,7 +113,7 @@ def __setitem__(self, index, value):
113113
self[actual_index] = actual_value
114114
else:
115115
if isinstance(self._shape, ShapeCastable):
116-
self._raw[index] = Const.cast(self._shape.const(value)).value
116+
self._raw[index] = Const.cast(Const(value, self._shape)).value
117117
else:
118118
value = operator.index(value)
119119
# self._raw[index] assigned by the following line

amaranth/lib/wiring.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ def __init__(self, flow, description, *, init=None, reset=None, _dimensions=(),
139139
# TODO: We need a simpler way to check for "is this a valid constant initializer"
140140
if issubclass(type(self._description), ShapeCastable):
141141
try:
142-
self._init_as_const = Const.cast(self._description.const(self._init))
142+
self._init_as_const = Const.cast(Const(self._init, self._description))
143143
except Exception as e:
144144
raise TypeError(f"Port member initial value {self._init!r} is not a valid "
145145
f"constant initializer for {self._description}") from e

tests/test_hdl_ast.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -522,10 +522,16 @@ def test_hash(self):
522522
hash(Const(0))
523523

524524
def test_shape_castable(self):
525-
class MockConstValue:
525+
class MockConstValue(ValueCastable):
526526
def __init__(self, value):
527527
self.value = value
528528

529+
def shape(self):
530+
return MockConstShape()
531+
532+
def as_value(self):
533+
return Const(self.value, 8)
534+
529535
class MockConstShape(ShapeCastable):
530536
def as_shape(self):
531537
return unsigned(8)

0 commit comments

Comments
 (0)