diff --git a/amaranth/lib/data.py b/amaranth/lib/data.py index 24bbde4..1013863 100644 --- a/amaranth/lib/data.py +++ b/amaranth/lib/data.py @@ -662,6 +662,10 @@ class View(ValueCastable): If ``ShapeCastable.__call__`` does not return a value or a value-castable object. """ if isinstance(self.__layout, ArrayLayout): + if not isinstance(key, (int, Value, ValueCastable)): + raise TypeError("Views with array layout may only be indexed with an integer " + "or a value, not {!r}" + .format(key)) shape = self.__layout.elem_shape value = self.__target.word_select(key, Shape.cast(self.__layout.elem_shape).width) else: @@ -697,6 +701,9 @@ class View(ValueCastable): If the layout does not define a field called ``name``, or if ``name`` starts with an underscore. """ + if isinstance(self.__layout, ArrayLayout): + raise AttributeError("View of {!r} with an array layout does not have fields" + .format(self.__target)) try: item = self[name] except KeyError: diff --git a/tests/test_lib_data.py b/tests/test_lib_data.py index 5ce1120..e368095 100644 --- a/tests/test_lib_data.py +++ b/tests/test_lib_data.py @@ -611,6 +611,17 @@ class ViewTestCase(FHDLTestCase): r"and may only be accessed by indexing$"): Signal(StructLayout({"_c": signed(1)}))._c + def test_bug_837_array_layout_getitem_str(self): + with self.assertRaisesRegex(TypeError, + r"^Views with array layout may only be indexed with an integer or a value, " + r"not 'reset'$"): + Signal(ArrayLayout(unsigned(1), 1), reset=[0])["reset"] + + def test_bug_837_array_layout_getattr(self): + with self.assertRaisesRegex(AttributeError, + r"^View of \(sig \$signal\) with an array layout does not have fields$"): + Signal(ArrayLayout(unsigned(1), 1), reset=[0]).reset + class StructTestCase(FHDLTestCase): def test_construct(self):