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.
This commit is contained in:
Catherine 2023-07-23 03:30:38 +00:00
parent f6c38061ff
commit a6d67f7477
2 changed files with 8 additions and 1 deletions

View file

@ -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):

View file

@ -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"):