Repository: numba/numba

Issue:
Record not recognized as a data type
The Record.make_c_struct throws error in some special cases in the new releases of numba:

```
import numba
import numpy as np
from numba.types import Record, NestedArray, float64

print(numba.__version__)
print(np.__version__)

cell_shape_poly = np.array([[0,0],[1,1], [1,1],[1,0], [1,1]])

args_dtype = Record.make_c_struct([('cell_shape_poly', NestedArray(dtype=float64, shape=cell_shape_poly.shape)),])
print(args_dtype)
args=np.array((cell_shape_poly,), dtype=args_dtype)
```

The error:
```
0.55.2
1.22.4
Record(cell_shape_poly[type=nestedarray(float64, (5, 2));offset=0;alignment=8];72;True)
Traceback (most recent call last):
  File "D:\Projects\Python\tessellation\TorchSpatial\test.py", line 12, in <module>
    args=np.array((cell_shape_poly,), dtype=args_dtype)
TypeError: Cannot interpret 'Record(cell_shape_poly[type=nestedarray(float64, (5, 2));offset=0;alignment=8];72;True)' as a data type
```

Surprisingly the following code works correctly:
```
import numba
import numpy as np
from numba.types import Record, NestedArray, float64

print(numba.__version__)
print(np.__version__)

cell_shape_poly = np.array([[0,0],[1,1], [1,1],[1,0]])

args_dtype = Record.make_c_struct([('cell_shape_poly', NestedArray(dtype=float64, shape=cell_shape_poly.shape)),])
print(args_dtype)
args=np.array((cell_shape_poly,), dtype=args_dtype)
```

```
0.55.2
1.22.4
Record(cell_shape_poly[type=nestedarray(float64, (4, 2));offset=0;alignment=8];72;True)
```

All of the above codes work perfectly on numba 0.51.2 and numpy 1.21.6, however numba 0.51.2 is not compatible with python 3.10.4 that I'm currently using.


Discussion:
Thanks for the bug report. I can confirm it.
git bisect is pointing to https://github.com/numba/numba/commit/71118545391ad74f6e3fb90a3607610a85615262 as the first bad commit. 
This is a regression in 0.55

Resolving patch:
diff --git a/numba/core/datamodel/models.py b/numba/core/datamodel/models.py
--- a/numba/core/datamodel/models.py
+++ b/numba/core/datamodel/models.py
@@ -899,6 +899,13 @@ def __init__(self, dmm, fe_type):
         self._be_type = dmm.lookup(fe_type.dtype).get_data_type()
         super(NestedArrayModel, self).__init__(dmm, fe_type)
 
+    def as_storage_type(self):
+        """Return the LLVM type representation for the storage of
+        the nestedarray.
+        """
+        ret = ir.ArrayType(self._be_type, self._fe_type.nitems)
+        return ret
+
 
 @register_default(types.Optional)
 class OptionalModel(StructModel):
diff --git a/numba/core/types/npytypes.py b/numba/core/types/npytypes.py
--- a/numba/core/types/npytypes.py
+++ b/numba/core/types/npytypes.py
@@ -94,7 +94,10 @@ def make_c_struct(cls, name_types):
             if not isinstance(ty, (Number, NestedArray)):
                 msg = "Only Number and NestedArray types are supported, found: {}. "
                 raise TypeError(msg.format(ty))
-            datatype = ctx.get_data_type(ty)
+            if isinstance(ty, NestedArray):
+                datatype = ctx.data_model_manager[ty].as_storage_type()
+            else:
+                datatype = ctx.get_data_type(ty)
             lltypes.append(datatype)
             size = ctx.get_abi_sizeof(datatype)
             align = ctx.get_abi_alignment(datatype)


Test patch:
diff --git a/numba/tests/test_record_dtype.py b/numba/tests/test_record_dtype.py
--- a/numba/tests/test_record_dtype.py
+++ b/numba/tests/test_record_dtype.py
@@ -539,6 +539,22 @@ class Ref(ctypes.Structure):
                 str(raises.exception),
             )
 
+    def test_nestedarray_issue_8132(self):
+        # issue#8132 is caused by misrepresenting the NestedArray. Instead of
+        # using the storage layout for the contained data, it is represented
+        # as an array object structure.
+
+        # Make an array that is longer than the array object structure.
+        data = np.arange(27 * 2, dtype=np.float64).reshape(27, 2)
+        recty = types.Record.make_c_struct([
+            ('data', types.NestedArray(dtype=types.float64, shape=data.shape)),
+        ])
+        arr = np.array((data,), dtype=recty.dtype)
+        # unpack the nestedarray as a normal array
+        [extracted_array] = arr.tolist()
+        # check that is matches the original values
+        np.testing.assert_array_equal(extracted_array, data)
+
 
 class TestRecordDtype(unittest.TestCase):