Repository: JuliaLang/julia
File: JuliaLowering/test/functions.jl (Julia)

Code before:
            (a, b)
        end

        f_nospecialize_single_body(1, 2)
    end
    """) == (1, 2)
    @test only(methods(test_mod.f_nospecialize_single_body)).nospecialize == 0b10

    # @nospecialize with zero args in function body (blanket nospecialize)
    @test JuliaLowering.include_string(test_mod, """
    begin
        function f_nospecialize_zero_body(a, b, c)
            @nospecialize
            (a, b, c)
        end

        f_nospecialize_zero_body(1, 2, 3)
    end
    """) == (1, 2, 3)
    # 0-arg @nospecialize sets all bits (-1 == typemax(Int32) for nospecialize)
    @test only(methods(test_mod.f_nospecialize_zero_body)).nospecialize == -1

    # @nospecialize with default value in signature
    @test JuliaLowering.include_string(test_mod, """
    begin
        function f_nospecialize_default(x, @nospecialize(y=1))
            (x, y)
        end

        (f_nospecialize_default(10, 20), f_nospecialize_default(30))
    end
    """) == ((10, 20), (30, 1))
    # The 2-arg method has nospecialize on y (bit 2), the 1-arg forwarding method has no y
    ms = collect(methods(test_mod.f_nospecialize_default))
    @test any(m -> m.nargs == 3 && m.nospecialize == 0b10, ms)
    @test any(m -> m.nargs == 2 && m.nospecialize == 0b00, ms)
end

@testset "Keyword functions" begin
    JuliaLowering.include_string(test_mod, """
    function f_kw_simple(a::Int=1, b::Float64=1.0; x::Char='a', y::Bool=true)
        (a, b, x, y)
    end
    """)

    @test test_mod.f_kw_simple()               === (1, 1.0, 'a', true)
    @test test_mod.f_kw_simple(x='b')          === (1, 1.0, 'b', true)
    @test test_mod.f_kw_simple(y=false)        === (1, 1.0, 'a', false)
    @test test_mod.f_kw_simple(x='b', y=false) === (1, 1.0, 'b', false)

    @test test_mod.f_kw_simple(20)                 === (20, 1.0, 'a', true)

Review comment (bug):
Would be good to add a broken test for the body form (which doesn't work, as noted in https://github.com/JuliaLang/julia/blob/3a3289a17f5a36feddf0898b67788b894a5c7440/JuliaLowering/src/desugaring.jl#L2582).

A `kwargs` example would also be good (and is similarly broken for the body form). Sorry to make you add so many tests, but it seems prudent when we run into loose ends like this.


Code after:
            (a, b)
        end

        f_nospecialize_single_body(1, 2)
    end
    """) == (1, 2)
    @test only(methods(test_mod.f_nospecialize_single_body)).nospecialize == 0b10

    # @nospecialize with zero args in function body (blanket nospecialize)
    @test JuliaLowering.include_string(test_mod, """
    begin
        function f_nospecialize_zero_body(a, b, c)
            @nospecialize
            (a, b, c)
        end

        f_nospecialize_zero_body(1, 2, 3)
    end
    """) == (1, 2, 3)
    # 0-arg @nospecialize sets all bits (-1 == typemax(Int32) for nospecialize)
    @test only(methods(test_mod.f_nospecialize_zero_body)).nospecialize == -1

    # @nospecialize with default value in signature
    @test JuliaLowering.include_string(test_mod, """
    begin
        function f_nospecialize_default(x, @nospecialize(y=1))
            (x, y)
        end

        (f_nospecialize_default(10, 20), f_nospecialize_default(30))
    end
    """) == ((10, 20), (30, 1))
    # The 2-arg method has nospecialize on y (bit 2), the 1-arg forwarding method has no y
    ms = collect(methods(test_mod.f_nospecialize_default))
    @test any(m -> m.nargs == 3 && m.nospecialize == 0b10, ms)
    @test any(m -> m.nargs == 2 && m.nospecialize == 0b00, ms)

    # Body-level @nospecialize with default value in signature
    # See the TODO comment in `optional_positional_defs!`
    @test JuliaLowering.include_string(test_mod, """
    begin
        function f_body_nospecialize_default(x, y=1)
            @nospecialize
            (x, y)
        end
        (f_body_nospecialize_default(10, 20), f_body_nospecialize_default(30))
    end
    """) == ((10, 20), (30, 1))
    # The 2-arg method has nospecialize on y (bit 2), the 1-arg forwarding method has no y
    ms = collect(methods(test_mod.f_body_nospecialize_default))
    @test count(m -> m.nargs == 3 && m.nospecialize == -1, ms) == 1