M
Modular•15mo ago
JIMC

Error:cannot construct 'Array' from 'ListLiteral[Int, Int, Int, Int, Int]' value in 'var' initialize

I'm trying to create a Array[T: AnyType, N: Int] struct but encountered this error when trying to run it:
from memory import stack_allocation

struct Array[T: AnyType, N: Int]:
constrained[N <= 32, "`size` of N cannot be larger than 1024"]()
alias size: Int = N
alias type: AnyType = T

var capacity: Int
var length: Int
var storage: Pointer[T]

fn __init__[*Ts: AnyType](inout self, owned iterable: ListLiteral[Ts]) raises:
if N != len(iterable):
raise Error("`size` of `iterable` is not equal to the `size` of array")
self.capacity = self.size * 2
self.storage = stack_allocation[N*2, T]()
let src: Pointer[T] = Pointer.address_of(iterable).bitcast[T]()
for i in range(len(iterable)):
self.storage.store(i, src.load(i))


fn main():
var myarray: Array[Int, 5] = Array([1, 2, 3, 4, 5])
from memory import stack_allocation

struct Array[T: AnyType, N: Int]:
constrained[N <= 32, "`size` of N cannot be larger than 1024"]()
alias size: Int = N
alias type: AnyType = T

var capacity: Int
var length: Int
var storage: Pointer[T]

fn __init__[*Ts: AnyType](inout self, owned iterable: ListLiteral[Ts]) raises:
if N != len(iterable):
raise Error("`size` of `iterable` is not equal to the `size` of array")
self.capacity = self.size * 2
self.storage = stack_allocation[N*2, T]()
let src: Pointer[T] = Pointer.address_of(iterable).bitcast[T]()
for i in range(len(iterable)):
self.storage.store(i, src.load(i))


fn main():
var myarray: Array[Int, 5] = Array([1, 2, 3, 4, 5])
Please help.
27 Replies
Stole
Stole•15mo ago
I think you want to change that last Array([1, 2, 3, 4, 5]) to Array[Int, 5]([1, 2, 3, 4, 5]), and change fn main(): to fn main() raises:, since your __init__ can raise. Or you can wrap that initialization inside of main in a try block
JIMC
JIMCOP•15mo ago
from memory import stack_allocation

struct Array[T: AnyType, N: Int]:
alias size: Int = N
alias type: AnyType = T

var capacity: Int
var storage: Pointer[T]

@always_inline("nodebug")
fn __init__(inout self, size: Int, value: T) raises:
if N != size:
raise Error("`size` of `iterable` is not equal to the `size` of this array")
self.capacity = self.size * 2
self.storage = stack_allocation[N*2, T]()
for i in range(self.size):
self.storage.store(i, value)

@always_inline("nodebug")
fn __getitem__(self, i: Int) -> T:
return self.storage.load(i)

@always_inline("nodebug")
fn __del__(owned self):
self.storage.free()

fn main() raises:
var myarray = Array[Int, 5](5, 2)
print(myarray[2])
from memory import stack_allocation

struct Array[T: AnyType, N: Int]:
alias size: Int = N
alias type: AnyType = T

var capacity: Int
var storage: Pointer[T]

@always_inline("nodebug")
fn __init__(inout self, size: Int, value: T) raises:
if N != size:
raise Error("`size` of `iterable` is not equal to the `size` of this array")
self.capacity = self.size * 2
self.storage = stack_allocation[N*2, T]()
for i in range(self.size):
self.storage.store(i, value)

@always_inline("nodebug")
fn __getitem__(self, i: Int) -> T:
return self.storage.load(i)

@always_inline("nodebug")
fn __del__(owned self):
self.storage.free()

fn main() raises:
var myarray = Array[Int, 5](5, 2)
print(myarray[2])
now i tried this
root@DESKTOP-N84UN90:~/mojo_projs/marray# [6725:6726:20230911,012436.045090:ERROR http_transport_libcurl.cc:483] HTTP status 404
mojo array.mojo
munmap_chunk(): invalid pointer
[6849:6849:20230911,012533.599369:ERROR file_io_posix.cc:144] open /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq: No such file or directory (2)
[6849:6849:20230911,012533.599465:ERROR file_io_posix.cc:144] open /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq: No such file or directory (2)
Please submit a bug report to https://github.com/modularml/mojo/issues and include the crash backtrace along with all the relevant source codes.
Stack dump:
0. Program arguments: mojo array.mojo
Stack dump without symbol names (ensure you have llvm-symbolizer in your PATH or set the environment var `LLVM_SYMBOLIZER_PATH` to point to it):
0 mojo 0x00005622408e3957
1 mojo 0x00005622408e152e
2 mojo 0x00005622408e402f
3 libc.so.6 0x00007f84e78b7520
4 libc.so.6 0x00007f84e790ba7c pthread_kill + 300
5 libc.so.6 0x00007f84e78b7476 raise + 22
6 libc.so.6 0x00007f84e789d7f3 abort + 211
7 libc.so.6 0x00007f84e78fe6f6
8 libc.so.6 0x00007f84e7915d7c
9 libc.so.6 0x00007f84e791605c
10 libc.so.6 0x00007f84e791a51a free + 186
11 libc.so.6 0x00007f847400106a free + 18446744071770631178
Aborted
root@DESKTOP-N84UN90:~/mojo_projs/marray# [6725:6726:20230911,012436.045090:ERROR http_transport_libcurl.cc:483] HTTP status 404
mojo array.mojo
munmap_chunk(): invalid pointer
[6849:6849:20230911,012533.599369:ERROR file_io_posix.cc:144] open /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq: No such file or directory (2)
[6849:6849:20230911,012533.599465:ERROR file_io_posix.cc:144] open /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq: No such file or directory (2)
Please submit a bug report to https://github.com/modularml/mojo/issues and include the crash backtrace along with all the relevant source codes.
Stack dump:
0. Program arguments: mojo array.mojo
Stack dump without symbol names (ensure you have llvm-symbolizer in your PATH or set the environment var `LLVM_SYMBOLIZER_PATH` to point to it):
0 mojo 0x00005622408e3957
1 mojo 0x00005622408e152e
2 mojo 0x00005622408e402f
3 libc.so.6 0x00007f84e78b7520
4 libc.so.6 0x00007f84e790ba7c pthread_kill + 300
5 libc.so.6 0x00007f84e78b7476 raise + 22
6 libc.so.6 0x00007f84e789d7f3 abort + 211
7 libc.so.6 0x00007f84e78fe6f6
8 libc.so.6 0x00007f84e7915d7c
9 libc.so.6 0x00007f84e791605c
10 libc.so.6 0x00007f84e791a51a free + 186
11 libc.so.6 0x00007f847400106a free + 18446744071770631178
Aborted
i get a mad error
Stole
Stole•15mo ago
Oops. I forgot that the ListLiteral passed is destroyed immediately.
TeamPuzel
TeamPuzel•15mo ago
You can also omit the constructor and write
var array: Array[Int, 5] = [1, 2, 3, 4, 5]
var array: Array[Int, 5] = [1, 2, 3, 4, 5]
It's a bit easier to both type and read
Stole
Stole•15mo ago
Wait, this is quite different.
JIMC
JIMCOP•15mo ago
this works but...
from memory import stack_allocation

struct Array[T: AnyType, N: Int]:
alias size: Int = N
alias type: AnyType = T

var capacity: Int
var storage: Pointer[T]

fn __init__[*Ts: AnyType](inout self, owned iterable: ListLiteral[Ts]) raises:
if N != len(iterable):
raise Error("`size` of `iterable` is not equal to the `size` of array")
self.capacity = self.size * 2
self.storage = stack_allocation[N*2, T]()
let src: Pointer[T] = Pointer.address_of(iterable).bitcast[T]()
for i in range(len(iterable)):
self.storage.store(i, src.load(i))

fn __getitem__(self, idx: Int) -> T:
return self.storage[idx]


fn main() raises:
var myarray: Array[Int, 5] = [1, 2, 3, 4]
print(myarray[2])
from memory import stack_allocation

struct Array[T: AnyType, N: Int]:
alias size: Int = N
alias type: AnyType = T

var capacity: Int
var storage: Pointer[T]

fn __init__[*Ts: AnyType](inout self, owned iterable: ListLiteral[Ts]) raises:
if N != len(iterable):
raise Error("`size` of `iterable` is not equal to the `size` of array")
self.capacity = self.size * 2
self.storage = stack_allocation[N*2, T]()
let src: Pointer[T] = Pointer.address_of(iterable).bitcast[T]()
for i in range(len(iterable)):
self.storage.store(i, src.load(i))

fn __getitem__(self, idx: Int) -> T:
return self.storage[idx]


fn main() raises:
var myarray: Array[Int, 5] = [1, 2, 3, 4]
print(myarray[2])
this doesn't raise a compile time error lol
Stole
Stole•15mo ago
You'd probably want to change [1, 2, 3, 4] to [1, 2, 3, 4, 5] So it actually has 5 elements
JIMC
JIMCOP•15mo ago
LOL sir you are very confused it is done on purpose with 4 elements, I want it to give me a compile time error
TeamPuzel
TeamPuzel•15mo ago
huh
JIMC
JIMCOP•15mo ago
Using constrained
from memory import stack_allocation

struct Array[T: AnyType, N: Int]:
alias size: Int = N
alias type: AnyType = T

var capacity: Int
var storage: Pointer[T]

fn __init__[*Ts: AnyType](inout self, owned iterable: ListLiteral[Ts]) raises:
constrained(N != len(iterable), "`size` of `iterable` is not equal to the `size` of array")
self.capacity = self.size * 2
self.storage = stack_allocation[N*2, T]()
let src: Pointer[T] = Pointer.address_of(iterable).bitcast[T]()
for i in range(len(iterable)):
self.storage.store(i, src.load(i))

fn __getitem__(self, idx: Int) -> T:
return self.storage[idx]


fn main() raises:
var myarray: Array[Int, 5] = [1, 2, 3, 4]
print(myarray[2])
from memory import stack_allocation

struct Array[T: AnyType, N: Int]:
alias size: Int = N
alias type: AnyType = T

var capacity: Int
var storage: Pointer[T]

fn __init__[*Ts: AnyType](inout self, owned iterable: ListLiteral[Ts]) raises:
constrained(N != len(iterable), "`size` of `iterable` is not equal to the `size` of array")
self.capacity = self.size * 2
self.storage = stack_allocation[N*2, T]()
let src: Pointer[T] = Pointer.address_of(iterable).bitcast[T]()
for i in range(len(iterable)):
self.storage.store(i, src.load(i))

fn __getitem__(self, idx: Int) -> T:
return self.storage[idx]


fn main() raises:
var myarray: Array[Int, 5] = [1, 2, 3, 4]
print(myarray[2])
Moosems / Three chickens
You have to fill up the array with default values then.
JIMC
JIMCOP•15mo ago
Hi sir, can you elaborate?
Moosems / Three chickens
See the array implementation that some of the devs and I made: https://discord.com/channels/1087530497313357884/1146821935112667288/1148339799808299038 Custom types are necessary until traits get implemented.
Stole
Stole•15mo ago
Sorry about that. I don't think you can in this case, fetching the length of that ListLiteral isn't done at compile time in this case
JIMC
JIMCOP•15mo ago
Guess you made sense 🙂
ModularBot
ModularBot•15mo ago
Congrats @JIMC, you just advanced to level 1!
JIMC
JIMCOP•15mo ago
That's your impl? Cool
Moosems / Three chickens
That’s what me and the devs arrived at, yes. I believe it should accomplish the behavior you’re looking for.
JIMC
JIMCOP•15mo ago
I don't think it does, because I want a compile time check e.g. var my_array: Array[Int, 5] = [1, 2, 3] will have a compile time error that's what i want
Stole
Stole•15mo ago
And I don't think you can pass it as a parameter either, because trying to do something like fn __init__[*Ts: AnyType, iterable: ListLiteral[Ts]](inout self) raises: has a parameter pack plus normal parameters, and the error states keyword args aren't supported yet
Moosems / Three chickens
You could modify it to receive compile time values.
JIMC
JIMCOP•15mo ago
How do you do try, except in Mojo?
TeamPuzel
TeamPuzel•15mo ago
try except finally it works the same way as in python but you raise Error not exception
JIMC
JIMCOP•15mo ago
yeah but you cannot capture the error message right? @Three chickens in the green bag Anyway, array is not growable so i think your impl is a vector and usually a compile time construct
Moosems / Three chickens
Yes, it is a DynamicVector.
JIMC
JIMCOP•15mo ago
from memory import stack_allocation

struct IntType[num: Int]:
alias value: Int = num

fn comptime_add[NumOne: Int, NumTwo: Int]() -> Int:
return NumOne + NumTwo

struct Array[T: AnyType, N: Int]:
alias size: Int = N

var capacity: Int
var storage: Pointer[T]

@staticmethod
fn check_size[Size: Int]() raises -> Int:
print("Size is ", Size)
@parameter
if Size <= N:
return Size
else:
raise Error("`{Size}`")

fn __init__[*Ts: AnyType](inout self, owned iterable: ListLiteral[Ts]) raises:
constrained[N <= 32, "`size` of array must be less than 32"]()
# if N != len(iterable):
# raise Error("`size` of `iterable` is not equal to the `size` of array")
self.capacity = self.size * 2
self.storage = stack_allocation[N*2, T]()
let src: Pointer[T] = Pointer.address_of(iterable).bitcast[T]()
alias Counter: Int = 0
for i in range(len(iterable)):
alias JustAnotherCounter = Counter
alias Counter = comptime_add[JustAnotherCounter, 1]()
self.check_size[Counter]()
self.storage.store(i, src.load(i))

fn __getitem__(self, idx: Int) raises -> T :
if idx > self.size:
raise Error("Out of bounds")
return self.storage[idx]

fn __setitem__(self, idx: Int, value: T) raises:
if idx > self.size:
raise Error("Out of bounds")
self.storage.store(idx, value)

fn __del__(owned self):
if self.storage:
self.storage.free()
from memory import stack_allocation

struct IntType[num: Int]:
alias value: Int = num

fn comptime_add[NumOne: Int, NumTwo: Int]() -> Int:
return NumOne + NumTwo

struct Array[T: AnyType, N: Int]:
alias size: Int = N

var capacity: Int
var storage: Pointer[T]

@staticmethod
fn check_size[Size: Int]() raises -> Int:
print("Size is ", Size)
@parameter
if Size <= N:
return Size
else:
raise Error("`{Size}`")

fn __init__[*Ts: AnyType](inout self, owned iterable: ListLiteral[Ts]) raises:
constrained[N <= 32, "`size` of array must be less than 32"]()
# if N != len(iterable):
# raise Error("`size` of `iterable` is not equal to the `size` of array")
self.capacity = self.size * 2
self.storage = stack_allocation[N*2, T]()
let src: Pointer[T] = Pointer.address_of(iterable).bitcast[T]()
alias Counter: Int = 0
for i in range(len(iterable)):
alias JustAnotherCounter = Counter
alias Counter = comptime_add[JustAnotherCounter, 1]()
self.check_size[Counter]()
self.storage.store(i, src.load(i))

fn __getitem__(self, idx: Int) raises -> T :
if idx > self.size:
raise Error("Out of bounds")
return self.storage[idx]

fn __setitem__(self, idx: Int, value: T) raises:
if idx > self.size:
raise Error("Out of bounds")
self.storage.store(idx, value)

fn __del__(owned self):
if self.storage:
self.storage.free()
Looks like its difficult to do compile time checking of array length lol, even though obviously at compile time the array is defined as [1, 2, 3, 4, 5, 7] with length of 6.
Want results from more Discord servers?
Add your server