Repository: RustPython/RustPython (language: rust)

Issue:
array._array_reconstructor panics on an empty array with debug stdlib
I wanted to fix this myself, but I think it needs some TLC from @youknowone or similar to find the best fix.

To reproduce:

```
rustup override set nightly
cargo run -Zbuild-std --target=x86_64-unknown-linux-gnu -- -m test -v test_array
```

This uses a debug version of the standard library, which exposes the fact that array._array_reconstructor calls array::frombytes (array.rs line 1561) and array::frombytes calls as_ptr(). Unfortunately, as_ptr() does not give a useful answer when the array is empty, and in fact will provide an unaligned value. This then trips the safety condition in std::slice::from_raw_parts.

```
unsafe precondition(s) violated: slice::from_raw_parts requires the pointer to be aligned and non-null, and the total size of the slice not to exceed `isize::MAX`
```

There are probably many ways to fix this but I'd prefer someone who knows RustPython better than I do to pick the best way!


Discussion / hints:
Nice catch. Because it runs `extend_from_slice` with the given ptr, I think adding length check will fix the problem.
If we skip extend when len==0, everything will be just find. 

Fix patch:
diff --git a/stdlib/src/array.rs b/stdlib/src/array.rs
index cba0eb2fda..5da3da34eb 100644
--- a/stdlib/src/array.rs
+++ b/stdlib/src/array.rs
@@ -213,10 +213,12 @@ mod array {
                         $(ArrayContentType::$n(v) => {
                             // safe because every configuration of bytes for the types we
                             // support are valid
-                            let ptr = b.as_ptr() as *const $t;
-                            let ptr_len = b.len() / std::mem::size_of::<$t>();
-                            let slice = unsafe { std::slice::from_raw_parts(ptr, ptr_len) };
-                            v.extend_from_slice(slice);
+                            if b.len() > 0 {
+                                let ptr = b.as_ptr() as *const $t;
+                                let ptr_len = b.len() / std::mem::size_of::<$t>();
+                                let slice = unsafe { std::slice::from_raw_parts(ptr, ptr_len) };
+                                v.extend_from_slice(slice);
+                            }
                         })*
                     }
                 }


Test patch: