Skip to content

Commit 4c1d0f3

Browse files
wanda-phiwhitequark
authored andcommitted
Implement RFC 39: Warn on Case() and matches() with no patterns.
1 parent 197c234 commit 4c1d0f3

File tree

4 files changed

+30
-7
lines changed

4 files changed

+30
-7
lines changed

amaranth/hdl/ast.py

+2
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,8 @@ def matches(self, *patterns):
541541
continue
542542
matches.append(self == pattern)
543543
if not matches:
544+
warnings.warn("The value of Value.matches() with no patterns will change to Const(0) "
545+
"in Amaranth 0.5", SyntaxWarning, stacklevel=2)
544546
return Const(1)
545547
elif len(matches) == 1:
546548
return matches[0]

amaranth/hdl/dsl.py

+18-1
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,9 @@ def Case(self, *patterns):
307307
src_loc = tracer.get_src_loc(src_loc_at=1)
308308
switch_data = self._get_ctrl("Switch")
309309
new_patterns = ()
310+
if not patterns:
311+
warnings.warn("The behavior of Case() with no patterns will change to never-active "
312+
"in Amaranth 0.5; use Default() instead", SyntaxWarning, stacklevel=3)
310313
# This code should accept exactly the same patterns as `v.matches(...)`.
311314
for pattern in patterns:
312315
if isinstance(pattern, str) and any(bit not in "01- \t" for bit in pattern):
@@ -353,8 +356,22 @@ def Case(self, *patterns):
353356
self._ctrl_context = "Switch"
354357
self._statements = _outer_case
355358

359+
@contextmanager
356360
def Default(self):
357-
return self.Case()
361+
self._check_context("Default", context="Switch")
362+
src_loc = tracer.get_src_loc(src_loc_at=1)
363+
switch_data = self._get_ctrl("Switch")
364+
try:
365+
_outer_case, self._statements = self._statements, []
366+
self._ctrl_context = None
367+
yield
368+
self._flush_ctrl()
369+
if () not in switch_data["cases"]:
370+
switch_data["cases"][()] = self._statements
371+
switch_data["case_src_locs"][()] = src_loc
372+
finally:
373+
self._ctrl_context = "Switch"
374+
self._statements = _outer_case
358375

359376
@contextmanager
360377
def FSM(self, reset=None, domain="sync", name="fsm"):

tests/test_hdl_ast.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -682,7 +682,9 @@ def test_xor_value(self):
682682

683683
def test_matches(self):
684684
s = Signal(4)
685-
self.assertRepr(s.matches(), "(const 1'd1)")
685+
with self.assertWarnsRegex(SyntaxWarning,
686+
r"^The value of Value.matches\(\) with no patterns will change to Const\(0\)"):
687+
self.assertRepr(s.matches(), "(const 1'd1)")
686688
self.assertRepr(s.matches(1), """
687689
(== (sig s) (const 1'd1))
688690
""")

tests/test_hdl_dsl.py

+7-5
Original file line numberDiff line numberDiff line change
@@ -387,11 +387,13 @@ def test_Switch(self):
387387

388388
def test_Switch_default_Case(self):
389389
m = Module()
390-
with m.Switch(self.w1):
391-
with m.Case(3):
392-
m.d.comb += self.c1.eq(1)
393-
with m.Case():
394-
m.d.comb += self.c2.eq(1)
390+
with self.assertWarnsRegex(SyntaxWarning,
391+
r"^The behavior of Case\(\) with no patterns will change to never-active"):
392+
with m.Switch(self.w1):
393+
with m.Case(3):
394+
m.d.comb += self.c1.eq(1)
395+
with m.Case():
396+
m.d.comb += self.c2.eq(1)
395397
m._flush()
396398
self.assertRepr(m._statements, """
397399
(

0 commit comments

Comments
 (0)