From a6d67f7477bfb820b3cec2491da219b99d9ef1a7 Mon Sep 17 00:00:00 2001 From: Catherine Date: Sun, 23 Jul 2023 03:30:38 +0000 Subject: [PATCH] hdl.ir: use additional heuristic for silencing warning. Using `sys.excepthook` to silence the must-use warning has some false negatives: applications may catch the exception and then quit normally, e.g. becaue the error is well known and does not require a traceback to be shown (which would be noisy). The current implementation prints even more noise in that case. In addition to the existing heuristic, silence the warning if *nothing* has been elaborated, which is almost always a reliable sign. It doesn't work if multiple designs are independently created in the application and some of them are dropped without being used, but this is unavoidable as it is not distinguishable from the mistake this warning is attempting to prevent. Fixes #848. --- amaranth/_unused.py | 2 ++ amaranth/hdl/ir.py | 7 ++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/amaranth/_unused.py b/amaranth/_unused.py index e0c67a7..4bd2d3a 100644 --- a/amaranth/_unused.py +++ b/amaranth/_unused.py @@ -28,6 +28,8 @@ class MustUse: def __del__(self): if self._MustUse__silence: return + if getattr(self._MustUse__warning, "_MustUse__silence", False): + return if hasattr(self, "_MustUse__used") and not self._MustUse__used: if get_linter_option(self._MustUse__context["filename"], self._MustUse__warning.__name__, bool, True): diff --git a/amaranth/hdl/ir.py b/amaranth/hdl/ir.py index 45857b8..c26e162 100644 --- a/amaranth/hdl/ir.py +++ b/amaranth/hdl/ir.py @@ -13,7 +13,11 @@ __all__ = ["UnusedElaboratable", "Elaboratable", "DriverConflict", "Fragment", " class UnusedElaboratable(UnusedMustUse): - pass + # The warning is initially silenced. If everything that has been constructed remains unused, + # it means the application likely crashed (with an exception, or in another way that does not + # call `sys.excepthook`), and it's not necessary to show any warnings. + # Once elaboration starts, the warning is enabled. + _MustUse__silence = True class Elaboratable(MustUse, metaclass=ABCMeta): @@ -33,6 +37,7 @@ class Fragment: return obj elif isinstance(obj, Elaboratable): code = obj.elaborate.__code__ + UnusedElaboratable._MustUse__silence = False obj._MustUse__used = True new_obj = obj.elaborate(platform) elif hasattr(obj, "elaborate"):