JuliaLang / julia

The Julia Programming Language
https://julialang.org/
MIT License
45.85k stars 5.49k forks source link

Better purity checks for `@generated` functions #55332

Open MilesCranmer opened 3 months ago

MilesCranmer commented 3 months ago

According to @aviatesk in https://github.com/JuliaLang/julia/issues/55147, the following code:

g() = [i for i in 1:0]
@generated function foo()
    if g() isa Vector{Int}
        return :(1)
    else
        return :(2)
    end
end

violates assumptions in @generated due to the implicit use of Core.Compiler.return_type in the list comprehension and thus might lead to Illegal instruction errors and segfaults.

However, Julia seems happy to compile it, and it seems to work without error most of the time.

If this is accurate, it is a major footgun, and I think Julia needs to be able to detect such behavior before compiling. This is similar to how Julia can detect the use of closures in generated functions and refuse to compile them.

nsajko commented 3 months ago

FWIW the metaprogramming docs say this about @generated:

Note that the set of operations that should not be attempted in a generated function is unbounded, and the runtime system can currently only detect a subset of the invalid operations. There are many other operations that will simply corrupt the runtime system without notification, usually in subtle ways not obviously connected to the bad definition. Because the function generator is run during inference, it must respect all of the limitations of that code.

MilesCranmer commented 3 months ago

Thanks.

I guess it could also be worth it if we specifically mention list comprehensions and map there? Even reading those docs now, I find it surprising that standard Julia utilities like map could cause this type of corruption when used with @generated. x-ref https://github.com/JuliaLang/julia/issues/55147#issuecomment-2262581006