hdl.ir: warn if .elaborate() returns None.
authorwhitequark <cz@m-labs.hk>
Sat, 3 Aug 2019 12:30:39 +0000 (12:30 +0000)
committerwhitequark <cz@m-labs.hk>
Sat, 3 Aug 2019 12:30:39 +0000 (12:30 +0000)
Fixes #164.

nmigen/hdl/ir.py
nmigen/test/test_hdl_ir.py

index 773bb8eac13bef48c272028f948d7d8aeca8273a..bb2cd0ec936465064624127ac712312c46d9f88b 100644 (file)
@@ -52,10 +52,12 @@ class DriverConflict(UserWarning):
 class Fragment:
     @staticmethod
     def get(obj, platform):
+        code = None
         while True:
             if isinstance(obj, Fragment):
                 return obj
             elif isinstance(obj, Elaboratable):
+                code = obj.elaborate.__code__
                 obj._Elaboratable__used = True
                 obj = obj.elaborate(platform)
             elif hasattr(obj, "elaborate"):
@@ -65,9 +67,16 @@ class Fragment:
                             .format(type(obj)),
                     category=RuntimeWarning,
                     stacklevel=2)
+                code = obj.elaborate.__code__
                 obj = obj.elaborate(platform)
             else:
                 raise AttributeError("Object '{!r}' cannot be elaborated".format(obj))
+            if obj is None and code is not None:
+                warnings.warn_explicit(
+                    message=".elaborate() returned None; missing return statement?",
+                    category=UserWarning,
+                    filename=code.co_filename,
+                    lineno=code.co_firstlineno)
 
     def __init__(self):
         self.ports = SignalDict()
index b30238f70095e559362ac980ca362b0ee1c79229..2ad5eb24579a38f74c4a5ef9c559e333ad4b8714 100644 (file)
@@ -7,12 +7,21 @@ from ..hdl.mem import *
 from .tools import *
 
 
+class BadElaboratable(Elaboratable):
+    def elaborate(self, platform):
+        return
+
+
 class FragmentGetTestCase(FHDLTestCase):
     def test_get_wrong(self):
         with self.assertRaises(AttributeError,
                 msg="Object 'None' cannot be elaborated"):
             Fragment.get(None, platform=None)
 
+        with self.assertRaises(AttributeError,
+                msg="Object 'None' cannot be elaborated"):
+            Fragment.get(BadElaboratable(), platform=None)
+
 
 class FragmentGeneratedTestCase(FHDLTestCase):
     def test_find_subfragment(self):