From: whitequark Date: Sat, 11 Dec 2021 08:18:33 +0000 (+0000) Subject: hdl.ast: warn on bare integer value used in Cat()/Repl(). X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=09d100779f74c3bf3b0fb4bf47b70e3098ff1c35;p=nmigen.git hdl.ast: warn on bare integer value used in Cat()/Repl(). Fixes #639. --- diff --git a/nmigen/hdl/ast.py b/nmigen/hdl/ast.py index ae010a0..0049c04 100644 --- a/nmigen/hdl/ast.py +++ b/nmigen/hdl/ast.py @@ -831,7 +831,14 @@ class Cat(Value): """ def __init__(self, *args, src_loc_at=0): super().__init__(src_loc_at=src_loc_at) - self.parts = [Value.cast(v) for v in flatten(args)] + self.parts = [] + for index, arg in enumerate(flatten(args)): + if isinstance(arg, int) and arg not in [0, 1]: + warnings.warn("Argument #{} of Cat() is a bare integer {} used in bit vector " + "context; consider specifying explicit width using C({}, {}) instead" + .format(index + 1, arg, arg, bits_for(arg)), + SyntaxWarning, stacklevel=2 + src_loc_at) + self.parts.append(Value.cast(arg)) def shape(self): return Shape(sum(len(part) for part in self.parts)) @@ -880,6 +887,11 @@ class Repl(Value): .format(count)) super().__init__(src_loc_at=src_loc_at) + if isinstance(value, int) and value not in [0, 1]: + warnings.warn("Value argument of Repl() is a bare integer {} used in bit vector " + "context; consider specifying explicit width using C({}, {}) instead" + .format(value, value, bits_for(value)), + SyntaxWarning, stacklevel=2 + src_loc_at) self.value = Value.cast(value) self.count = count diff --git a/tests/test_hdl_ast.py b/tests/test_hdl_ast.py index fb25f39..83f6071 100644 --- a/tests/test_hdl_ast.py +++ b/tests/test_hdl_ast.py @@ -746,6 +746,17 @@ class CatTestCase(FHDLTestCase): r"^Object 'foo' cannot be converted to an nMigen value$"): Cat("foo") + def test_int_01(self): + with warnings.catch_warnings(): + warnings.filterwarnings(action="error", category=SyntaxWarning) + Cat(0, 1, 1, 0) + + def test_int_wrong(self): + with self.assertWarnsRegex(SyntaxWarning, + r"^Argument #1 of Cat\(\) is a bare integer 2 used in bit vector context; " + r"consider specifying explicit width using C\(2, 2\) instead$"): + Cat(2) + class ReplTestCase(FHDLTestCase): def test_shape(self): @@ -769,6 +780,18 @@ class ReplTestCase(FHDLTestCase): r = Repl(0, 3) self.assertEqual(repr(r), "(repl (const 1'd0) 3)") + def test_int_01(self): + with warnings.catch_warnings(): + warnings.filterwarnings(action="error", category=SyntaxWarning) + Repl(0, 3) + Repl(1, 3) + + def test_int_wrong(self): + with self.assertWarnsRegex(SyntaxWarning, + r"^Value argument of Repl\(\) is a bare integer 2 used in bit vector context; " + r"consider specifying explicit width using C\(2, 2\) instead$"): + Repl(2, 3) + class ArrayTestCase(FHDLTestCase): def test_acts_like_array(self):