Here is a pretty innocent program that takes a really long time to compile if you use --release:
# big.cr — a def that returns a ~163KB struct by value
struct Big
getter a : StaticArray(UInt64, 20410) # 20410 * 8 = ~163KB
def initialize
@a = StaticArray(UInt64, 20410).new(0_u64)
end
end
def make : Big
big = Big.new
big.a[0] = 1_u64
big # returned by value
end
x = make
y = make
puts x.a[0] + y.a[0]
Depending on the size of the struct it returns, the compile time shoots to pretty much infinite, and may even use all your RAM.
Less noticeable is that the a’s in all those .a[0] calls already return the instance variable by reference, not by value, despite it being a StaticArray, because the compiler has special rules for method calls inside a call chain when the method body is exactly an instance variable. Otherwise the build times would have been even longer (and the program wouldn’t work as intended).
Is there a way to detect this at compile time and emit a warning, perhaps with a link to the known issue? I’m not sure what the right threshold would be, but if the compiler sees a StaticArray with a large second parameter, it might be nice to say “don’t do this”.
FWIW, I reckon huge static arrays are rarely ever a good idea.
Regardless of whether the compiler can handle them efficiently or not: Passing huge amounts of memory by value is super inefficient at runtime as well.
So yeah, perhaps a compiler warning would be good in general.
Or a linter rule in ameba?