Revision bc7ba3d5c8b2dab1c0e19537739b67c2da902d11 authored by Keno Fischer on 20 March 2024, 06:35:46 UTC, committed by GitHub on 20 March 2024, 06:35:46 UTC
This passes slightly more information into this function (the full `inst` rather than just the `stmt`) in order to allow external absint to access additional fields (the flags and the info) if necessary to make concrete evaluation decisions. It also splits out the actual concrete evaluation from the part that just maps the `inst` to a CodeInstance.
1 parent e0bb95a
tuple.jl
# This file is a part of Julia. License is MIT: https://julialang.org/license
isdefined(Main, :OffsetArrays) || @eval Main include("testhelpers/OffsetArrays.jl")
using .Main.OffsetArrays
struct BitPerm_19352
p::NTuple{8,UInt8}
function BitPerm(p::NTuple{8,UInt8})
sort(collect(p)) != 0:7 && error("$p is not a permutation of 0:7")
new(p)
end
BitPerm_19352(xs::Vararg{Any,8}) = BitPerm(map(UInt8, xs))
end
@testset "conversion and construction" begin
@test convert(Tuple, ()) === ()
@test convert(Tuple, (1, 2)) === (1, 2)
@test convert(Tuple, (1.0, 2)) === (1.0, 2)
@test convert(NTuple, ()) === ()
@test convert(Tuple{}, ()) === ()
@test convert(Tuple{Vararg{Int}}, ()) === ()
@test convert(Tuple{Vararg{T}} where T<:Integer, ()) === ()
@test convert(NTuple{3, Int}, (1, 2, 3)) === (1, 2, 3)
@test convert(NTuple, (1, 2, 3)) === (1, 2, 3)
@test convert(Tuple{Vararg{Int}}, (1, 2, 3)) === (1, 2, 3)
@test convert(Tuple{Int, Vararg{Int}}, (1, 2, 3)) === (1, 2, 3)
@test convert(Tuple{Vararg{T}} where T<:Integer, (1, 2, 3)) === (1, 2, 3)
@test convert(Tuple{T, Vararg{T}} where T<:Integer, (1, 2, 3)) === (1, 2, 3)
@test convert(Tuple{Int, Int, Float64}, (1, 2, 3)) === (1, 2, 3.0)
@test convert(Tuple{Float64, Int, UInt8}, (1.0, 2, 0x3)) === (1.0, 2, 0x3)
@test convert(Tuple{Vararg{Real}}, (1.0, 2, 0x3)) === (1.0, 2, 0x3)
@test convert(Tuple{Vararg{Integer}}, (1.0, 2, 0x3)) === (1, 2, 0x3)
@test convert(Tuple{Vararg{Int}}, (1.0, 2, 0x3)) === (1, 2, 3)
@test convert(Tuple{Int, Vararg{Int}}, (1.0, 2, 0x3)) === (1, 2, 3)
@test convert(NTuple{3, Int}, (1.0, 2, 0x3)) === (1, 2, 3)
@test convert(Tuple{Int, Int, Float64}, (1.0, 2, 0x3)) === (1, 2, 3.0)
@test convert(Tuple{Vararg{AbstractFloat}}, (2,)) == (2.0,)
@test convert(Tuple{Int, Vararg{AbstractFloat}}, (-9.0+0im, 2,)) == (-9, 2.0,)
let x = @inferred(convert(Tuple{Integer, UInt8, UInt16, UInt32, Int, Vararg{Real}}, (2.0, 3, 5, 6.0, 42, 3.0+0im)))
@test x == (2, 0x03, 0x0005, 0x00000006, 42, 3.0)
end
for x in (Int(2), UInt8(3), UInt16(5), UInt32(6), 42, 5.0, 3.0+0im)
@test (x,) == @inferred Tuple(x)
end
@test_throws MethodError convert(Tuple{Int}, ())
@test_throws MethodError convert(Tuple{Any}, ())
@test_throws MethodError convert(Tuple{Int, Vararg{Int}}, ())
@test_throws MethodError convert(Tuple{}, (1, 2, 3))
@test_throws MethodError convert(Tuple{}, (1.0, 2, 3))
@test_throws MethodError convert(NTuple{3, Int}, ())
@test_throws MethodError convert(NTuple{3, Int}, (1, 2))
@test_throws MethodError convert(NTuple{3, Int}, (1, 2, 3, 4))
@test_throws MethodError convert(Tuple{Int, Int, Float64}, ())
@test_throws MethodError convert(Tuple{Int, Int, Float64}, (1, 2))
@test_throws MethodError convert(Tuple{Int, Int, Float64}, (1, 2, 3, 4))
# #17198
@test_throws MethodError convert(Tuple{Int}, (1.0, 2.0, 3.0))
# #21238
@test_throws MethodError convert(Tuple{Int, Int, Int}, (1, 2))
# issue #26589
@test_throws MethodError convert(NTuple{4}, (1.0,2.0,3.0,4.0,5.0))
# issue #44179
@test_throws TypeError NTuple{3}([1, nothing, nothing])
@test_throws TypeError NTuple{3}([nothing, 1, nothing])
# issue #31824
@test convert(NTuple, (1, 1.0)) === (1, 1.0)
let T = Tuple{Vararg{T}} where T<:Integer, v = (1.0, 2, 0x3)
@test convert(T, v) === (1, 2, 0x3)
end
let T = Tuple{T, Vararg{T}} where T<:Integer, v = (1.0, 2, 0x3)
@test convert(T, v) === (1, 2, 0x3)
end
function f31824(input...)
b::NTuple = input
return b
end
@test f31824(1, 2, 3) === (1, 2, 3)
# PR #15516
@test Tuple{Char,Char}("za") === ('z','a')
@test_throws ArgumentError Tuple{Char,Char}("z")
@test NTuple{20,Int}(Iterators.countfrom(2)) === (2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21)
@test NTuple{20,Float64}(Iterators.countfrom(2)) === (2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.)
@test_throws ArgumentError NTuple{20,Int}([1,2])
@test Tuple{Vararg{Float32}}(Float64[1,2,3]) === (1.0f0, 2.0f0, 3.0f0)
@test Tuple{Int,Vararg{Float32}}(Float64[1,2,3]) === (1, 2.0f0, 3.0f0)
@test Tuple{Int,Vararg{Any}}(Float64[1,2,3]) === (1, 2.0, 3.0)
@test Tuple(fill(1.,5)) === (1.0,1.0,1.0,1.0,1.0)
@test_throws MethodError convert(Tuple, fill(1.,5))
@testset "ambiguity between tuple constructors #20990" begin
Tuple16Int = Tuple{Int,Int,Int,Int,Int,Int,Int,Int,Int,Int,Int,Int,Int,Int,Int,Int}
tuple16int = (1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)
@test Tuple16Int(tuple16int) isa Tuple16Int
end
@testset "side effect in tuple constructor #19352" begin
@test BitPerm_19352(0,2,4,6,1,3,5,7).p[2] == 0x02
end
@testset "n_uninitialized" begin
@test Tuple.name.n_uninitialized == 0
@test Core.Compiler.datatype_min_ninitialized(Tuple{Int,Any}) == 2
@test Core.Compiler.datatype_min_ninitialized(Tuple) == 0
@test Core.Compiler.datatype_min_ninitialized(Tuple{Int,Vararg{Any}}) == 1
@test Core.Compiler.datatype_min_ninitialized(Tuple{Any,Any,Vararg{Any}}) == 2
@test Core.Compiler.datatype_min_ninitialized(Tuple{Any,Any,Vararg{Any,3}}) == 5
end
@test empty((1, 2.0, "c")) === ()
# issue #28915
@test convert(Union{Tuple{}, Tuple{Int}}, (1,)) === (1,)
@testset "one-element containers" begin
r = Ref(3)
@test (3,) === @inferred Tuple(r)
z = Array{Float64,0}(undef); z[] = 3.0
@test (3.0,) === @inferred Tuple(z)
end
end
@testset "size" begin
@test length(()) == 0
@test length((1,)) === 1
@test length((1,2)) === 2
@test_throws ArgumentError Base.front(())
@test_throws ArgumentError Base.tail(())
@test_throws ArgumentError first(())
@test lastindex(()) === 0
@test lastindex((1,)) === 1
@test lastindex((1,2)) === 2
@test size((), 1) === 0
@test size((1,), 1) === 1
@test size((1,2), 1) === 2
# @test_throws ArgumentError size((), 2)
# @test_throws ArgumentError size((1,), 2)
# @test_throws ArgumentError size((1,2), 2)
end
@testset "indexing" begin
@test getindex((1,), 1) === 1
@test getindex((1,2), 2) === 2
@test_throws BoundsError getindex((), 1)
@test_throws BoundsError getindex((1,2), 0)
@test_throws BoundsError getindex((1,2), -1)
@test getindex((5,6,7,8), [1,2,3]) === (5,6,7)
@test_throws BoundsError getindex((1,2), [3,4])
@test getindex((5,6,7,8), [true, false, false, true]) === (5,8)
@test_throws BoundsError getindex((5,6,7,8), [true, false, false, true, true])
@test getindex((5,6,7,8), []) === ()
@test getindex((1,9,9,3),:) === (1,9,9,3)
@test getindex((),:) === ()
@test getindex((1,),:) === (1,)
@testset "boolean arrays" begin
# issue #19719
@test_throws BoundsError (1,2,3)[falses(4)]
@test_throws BoundsError (1,2,3)[[false,false,true,true]]
@test_throws BoundsError (1,2,3)[trues(2)]
@test_throws BoundsError (1,2,3)[falses(2)]
@test_throws BoundsError ()[[false]]
@test_throws BoundsError ()[[true]]
end
@testset "Multidimensional indexing (issue #20453)" begin
@test_throws MethodError (1,)[]
@test_throws MethodError (1,1,1)[1,1]
end
@testset "get() method for Tuple (Issue #40809)" begin
@test get((5, 6, 7), 1, 0) == 5
@test get((), 5, 0) == 0
@test get((1,), 3, 0) == 0
@test get(()->0, (5, 6, 7), 1) == 5
@test get(()->0, (), 4) == 0
@test get(()->0, (1,), 3) == 0
end
end
@testset "fill to length" begin
## filling to specified length
@test @inferred(Base.fill_to_length((1,2,3), -1, Val(5))) == (1,2,3,-1,-1)
@test_throws ArgumentError Base.fill_to_length((1,2,3), -1, Val(2))
end
@testset "iterating" begin
@test iterate(()) === nothing
t = (1,2,3)
y1 = iterate(t)
y2 = iterate(t, y1[2])
y3 = iterate(t, y2[2])
@test y3 !== nothing
@test iterate(t, y3[2]) === nothing
@test eachindex((2,5,"foo")) === Base.OneTo(3)
@test eachindex((2,5,"foo"), (1,2,5,7)) === Base.OneTo(4)
end
@testset "elelement/value/key types" begin
@test eltype((1,2,3)) === Int
@test eltype((1.0,2.0,3.0)) <: AbstractFloat
@test eltype((true, false)) === Bool
@test eltype((1, 2.0, false)) === typejoin(Int, Float64, Bool)
@test eltype(()) === Union{}
@test eltype(Tuple{Int, Float64, Vararg{Bool}}) === typejoin(Int, Float64, Bool)
@test eltype(Tuple{Int, T, Vararg{Bool}} where T <: AbstractFloat) ===
typejoin(Int, AbstractFloat, Bool)
@test eltype(Tuple{Int, Bool, Vararg{T}} where T <: AbstractFloat) ===
typejoin(Int, AbstractFloat, Bool)
@test eltype(Union{Tuple{Int, Float64}, Tuple{Vararg{Bool}}}) ===
typejoin(Int, Float64, Bool)
@test eltype(Tuple{Int, Missing}) === Union{Missing, Int}
@test eltype(Tuple{Int, Nothing}) === Union{Nothing, Int}
@test valtype((1,2,3)) === eltype((1,2,3))
@test valtype(Tuple{Int, Missing}) === eltype(Tuple{Int, Missing})
@test keytype((1,2,3)) === Int
@test keytype(Tuple{Int, Missing}) === Int
end
@testset "map with Nothing and Missing" begin
for T in (Nothing, Missing)
x = [(1, T()), (1, 2)]
y = map(v -> (v[1], v[2]), [(1, T()), (1, 2)])
@test y isa Vector{Tuple{Int, Any}}
@test isequal(x, y)
end
y = map(v -> (v[1], v[1] + v[2]), [(1, missing), (1, 2)])
@test y isa Vector{Tuple{Int, Any}}
@test isequal(y, [(1, missing), (1, 3)])
end
@testset "mapping" begin
foo() = 2
foo(x) = 2x
foo(x, y) = x + y
foo(x, y, z) = x + y + z
longtuple = ntuple(identity, 20)
vlongtuple = ntuple(identity, 33)
@testset "1 argument" begin
@test map(foo, ()) === ()
@test map(foo, (1,)) === (2,)
@test map(foo, (1,2)) === (2,4)
@test map(foo, (1,2,3,4)) === (2,4,6,8)
@test map(foo, longtuple) === ntuple(i->2i,20)
@test map(foo, vlongtuple) === ntuple(i->2i,33)
end
@testset "2 arguments" begin
@test map(foo, (), ()) === ()
@test map(foo, (1,), (1,)) === (2,)
@test map(foo, (1,2), (1,2)) === (2,4)
@test map(foo, (1,2,3,4), (1,2,3,4)) === (2,4,6,8)
@test map(foo, longtuple, longtuple) === ntuple(i->2i,20)
@test map(foo, vlongtuple, vlongtuple) === ntuple(i->2i,33)
@test map(foo, longtuple, vlongtuple) === ntuple(i->2i,20)
@test map(foo, vlongtuple, longtuple) === ntuple(i->2i,20)
@test map(foo, (), (1,)) === ()
@test map(foo, (1,), ()) === ()
end
@testset "n arguments" begin
@test map(foo, (), (), ()) === ()
@test map(foo, (1,), (1,), (1,)) === (3,)
@test map(foo, (1,2), (1,2), (1,2)) === (3,6)
@test map(foo, (1,2,3,4), (1,2,3,4), (1,2,3,4)) === (3,6,9,12)
@test map(foo, longtuple, longtuple, longtuple) === ntuple(i->3i,20)
@test map(foo, vlongtuple, vlongtuple, vlongtuple) === ntuple(i->3i,33)
@test map(foo, vlongtuple, longtuple, longtuple) === ntuple(i->3i,20)
@test map(foo, longtuple, vlongtuple, longtuple) === ntuple(i->3i,20)
@test map(foo, longtuple, vlongtuple, vlongtuple) === ntuple(i->3i,20)
@test map(foo, (), (1,), (1,)) === ()
@test map(foo, (1,), (1,), ()) === ()
end
end
@testset "foreach" begin
longtuple = ntuple(identity, 33)
@testset "1 argument" begin
foo(x) = push!(a, x)
a = []
foreach(foo, ())
@test a == []
a = []
foreach(foo, (1,))
@test a == [1]
a = []
foreach(foo, longtuple)
@test a == [longtuple...]
end
@testset "n arguments" begin
foo(x, y) = push!(a, (x, y))
a = []
foreach(foo, (), ())
@test a == []
a = []
foreach(foo, (1,), (2,))
@test a == [(1, 2)]
a = []
foreach(foo, longtuple, longtuple)
@test a == [(x, x) for x in longtuple]
end
end
@testset "mapfoldl" begin
@test (((1=>2)=>3)=>4) == foldl(=>, (1,2,3,4)) ==
mapfoldl(identity, =>, (1,2,3,4)) == mapfoldl(abs, =>, (-1,-2,-3,-4))
@test mapfoldl(abs, =>, (-1,-2,-3,-4), init=-10) == ((((-10=>1)=>2)=>3)=>4)
@test mapfoldl(abs, =>, (), init=-10) == -10
@test mapfoldl(abs, Pair{Any,Any}, (-30:-1...,)) == mapfoldl(abs, Pair{Any,Any}, [-30:-1...,])
@test_throws "reducing over an empty collection" mapfoldl(abs, =>, ())
end
@testset "filter" begin
@test filter(isodd, (1,2,3)) == (1, 3)
@test filter(isequal(2), (true, 2.0, 3)) === (2.0,)
@test filter(Returns(true), ()) == ()
@test filter(identity, (true,)) === (true,)
longtuple = ntuple(identity, 20)
@test filter(iseven, longtuple) == ntuple(i->2i, 10)
@test filter(x -> x<2, (longtuple..., 1.5)) === (1, 1.5)
end
@testset "comparison and hash" begin
@test isequal((), ())
@test isequal((1,2,3), (1,2,3))
@test !isequal((1,2,3), (1,2,4))
@test !isequal((1,2,3), (1,2))
@test ==((), ())
@test ==((1,2,3), (1,2,3))
@test !==((1,2,3), (1,2,4))
@test !==((1,2,3), (1,2))
@test (1,2) < (1,3)
@test (1,) < (1,2)
@test !((1,2) < (1,2))
@test (2,1) > (1,2)
@test isless((1,2), (1,3))
@test isless((1,), (1,2))
@test !isless((1,2), (1,2))
@test !isless((2,1), (1,2))
@test hash(()) === Base.tuplehash_seed
@test hash((1,)) === hash(1, Base.tuplehash_seed)
@test hash((1,2)) === hash(1, hash(2, Base.tuplehash_seed))
# Test Any32 methods
t = ntuple(identity, 32)
@test isequal((t...,1,2,3), (t...,1,2,3))
@test !isequal((t...,1,2,3), (t...,1,2,4))
@test !isequal((t...,1,2,3), (t...,1,2))
@test ==((t...,1,2,3), (t...,1,2,3))
@test !==((t...,1,2,3), (t...,1,2,4))
@test !==((t...,1,2,3), (t...,1,2))
@test (t...,1,2) < (t...,1,3)
@test (t...,1,) < (t...,1,2)
@test !((t...,1,2) < (t...,1,2))
@test (t...,2,1) > (t...,1,2)
@test isless((t...,1,2), (t...,1,3))
@test isless((t...,1,), (t...,1,2))
@test !isless((t...,1,2), (t...,1,2))
@test !isless((t...,2,1), (t...,1,2))
@test hash(t) === foldr(hash, [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,(),UInt(0)])
end
@testset "functions" begin
@test isempty(())
@test !isempty((1,))
@test reverse(()) === ()
@test reverse((1,2,3)) === (3,2,1)
end
# issue #21697
@test_throws ArgumentError ntuple(identity, -1)
@testset "specialized reduction" begin
@test sum((1,2,3)) === 6
@test prod(()) === 1
@test prod((1,2,3)) === 6
# issue 39182
@test sum((0xe1, 0x1f)) === sum([0xe1, 0x1f])
@test sum((Int8(3),)) === Int(3)
@test sum((UInt8(3),)) === UInt(3)
@test sum((3,)) === Int(3)
@test sum((3.0,)) === 3.0
@test sum(("a",)) == sum(["a"])
@test sum((0xe1, 0x1f), init=0x0) == sum([0xe1, 0x1f], init=0x0)
# issue 39183
@test prod((Int8(100), Int8(100))) === 10000
@test prod((Int8(3),)) === Int(3)
@test prod((UInt8(3),)) === UInt(3)
@test prod((3,)) === Int(3)
@test prod((3.0,)) === 3.0
@test prod(("a",)) == prod(["a"])
@test prod((0xe1, 0x1f), init=0x1) == prod([0xe1, 0x1f], init=0x1)
@testset "all" begin
@test all(()) === true
@test all((false,)) === false
@test all((true,)) === true
@test all((true, true)) === true
@test all((true, false)) === false
@test all((false, false)) === false
@test all((missing, true)) === missing
@test all((true, missing)) === missing
@test all((missing, false)) === false
@test all((false, missing)) === false
@test all((missing, true, false)) === false
@test_throws TypeError all((missing, 3.2, true))
ts = (missing, true, false)
@test @allocated(all(ts)) == 0 # PR #44063
@test (@inferred (()->all((missing, true)))()) === missing
@test (@inferred (()->all((true, missing)))()) === missing
@test (@inferred (()->all((missing, false)))()) === false
@test (@inferred (()->all((false, missing)))()) === false
@test (@inferred (()->all((missing, true, false)))()) === false
end
@testset "any" begin
@test any(()) === false
@test any((true,)) === true
@test any((false,)) === false
@test any((true, true)) === true
@test any((true, false)) === true
@test any((false, false)) === false
@test any((false,false,false)) === false
@test any((true,false,false)) === true
@test any((false,true,false)) === true
@test any((false,false,true)) === true
@test any((true,true,false)) === true
@test any((true,false,true)) === true
@test any((true,true,false)) === true
@test any((true,true,true)) === true
@test any((missing, true)) === true
@test any((true, missing)) === true
@test any((missing, false)) === missing
@test any((false, missing)) === missing
@test any((missing, true, false)) === true
@test any((missing, false, false)) === missing
@test_throws TypeError any((missing, 3.2, true))
ts = (missing, true, false)
@test @allocated(any(ts)) == 0 # PR #44063
@test (@inferred (()->any((missing, true)))()) === true
@test (@inferred (()->any((true, missing)))()) === true
@test (@inferred (()->any((missing, false)))()) === missing
@test (@inferred (()->any((false, missing)))()) === missing
@test (@inferred (()->any((missing, true, false)))()) === true
@test (@inferred (()->any((missing, false, false)))()) === missing
end
end
@testset "accumulate" begin
@test @inferred(cumsum(())) == ()
@test @inferred(cumsum((1, 2, 3))) == (1, 3, 6)
@test @inferred(cumprod((1, 2, 3))) == (1, 2, 6)
@test @inferred(accumulate(+, (1, 2, 3); init=10)) == (11, 13, 16)
op(::Nothing, ::Any) = missing
op(::Missing, ::Any) = nothing
@test @inferred(accumulate(op, (1, 2, 3, 4); init = nothing)) ===
(missing, nothing, missing, nothing)
end
@testset "ntuple" begin
nttest1(x::NTuple{n, Int}) where {n} = n
@test nttest1(()) == 0
@test nttest1((1, 2)) == 2
@test NTuple <: Tuple
@test (NTuple{T, Int32} where T) <: Tuple{Vararg{Int32}}
@test !((NTuple{T, Int32} where T) <: Tuple{Int32, Vararg{Int32}})
@test Tuple{Vararg{Int32}} <: (NTuple{T, Int32} where T)
@test Tuple{Int32, Vararg{Int32}} <: (NTuple{T, Int32} where T)
@test @inferred(ntuple(abs2, Val(0))) == ()
@test @inferred(ntuple(abs2, Val(2))) == (1, 4)
@test @inferred(ntuple(abs2, Val(3))) == (1, 4, 9)
@test @inferred(ntuple(abs2, Val(4))) == (1, 4, 9, 16)
@test @inferred(ntuple(abs2, Val(5))) == (1, 4, 9, 16, 25)
@test @inferred(ntuple(abs2, Val(6))) == (1, 4, 9, 16, 25, 36)
# issue #21697
@test_throws ArgumentError ntuple(abs2, Val(-1))
# issue #12854
@test_throws TypeError ntuple(identity, Val(1:2))
for n = 0:20
t = ntuple(identity, n)
@test length(t) == n
for i = 1:n
@test t[i] == i
end
end
# issue #21697
@test_throws ArgumentError ntuple(identity, -1)
# PR #21446
for n = 0:15
@test ntuple(identity, Val(n)) == ntuple(identity, n)
end
end
struct A_15703{N}
keys::NTuple{N, Int}
end
struct B_15703
x::A_15703
end
@testset "issue #15703" begin
function bug_15703(xs...)
[x for x in xs]
end
function test_15703()
s = (1,)
a = A_15703(s)
ss = B_15703(a).x.keys
@test ss === s
bug_15703(ss...)
end
test_15703()
end
@testset "#21026" begin
# https://github.com/JuliaLang/julia/issues/21026#issuecomment-317113307
VecTuple21026{T} = Tuple{VecElement{T}}
@test convert(VecTuple21026, (1,)) === (VecElement(1),)
@test convert(Tuple{Complex{T}, Complex{T}} where T<:Real, (1, 2)) ===
(Complex(1), Complex(2))
@test convert(Tuple{Complex{T}, Complex{T}} where T<:Real, (1, 2.0)) ===
(Complex(1), Complex(2.0))
@test convert(Tuple{Complex, Complex}, (1, 2)) ===
(Complex(1), Complex(2))
@test convert(Tuple{Complex, Complex}, (1, 2.0)) ===
(Complex(1), Complex(2.0))
end
@testset "issue 24707" begin
@test eltype(Tuple{Vararg{T}} where T<:Integer) >: Integer
end
@testset "find" begin
@test findall(isequal(1), (1, 2)) == [1]
@test findall(isequal(1), (1, 1)) == [1, 2]
@test isempty(findall(isequal(1), ()))
@test isempty(findall(isequal(1), (2, 3)))
@test findfirst(isequal(1), (1, 2)) == 1
@test findlast(isequal(1), (1, 2)) == 1
@test findfirst(isequal(1), (1, 1)) == 1
@test findlast(isequal(1), (1, 1)) == 2
@test findfirst(isequal(1), ()) === nothing
@test findlast(isequal(1), ()) === nothing
@test findfirst(isequal(1), (2, 3)) === nothing
@test findlast(isequal(1), (2, 3)) === nothing
@test findnext(isequal(1), (1, 2), 1) == 1
@test findprev(isequal(1), (1, 2), 2) == 1
@test findnext(isequal(1), (1, 1), 2) == 2
@test findprev(isequal(1), (1, 1), 1) == 1
@test findnext(isequal(1), (2, 3), 1) === nothing
@test findprev(isequal(1), (2, 3), 2) === nothing
@testset "issue 32568" begin
@test findnext(isequal(1), (1, 2), big(1)) isa Int
@test findprev(isequal(1), (1, 2), big(2)) isa Int
@test findnext(isequal(1), (1, 1), UInt(2)) isa Int
@test findprev(isequal(1), (1, 1), UInt(1)) isa Int
end
# recursive implementation should allow constant-folding for small tuples
@test Base.return_types() do
findfirst(==(2), (1.0,2,3f0))
end == Any[Int]
@test Base.return_types() do
findfirst(==(0), (1.0,2,3f0))
end == Any[Nothing]
@test Base.return_types() do
findlast(==(2), (1.0,2,3f0))
end == Any[Int]
@test Base.return_types() do
findlast(==(0), (1.0,2,3f0))
end == Any[Nothing]
@testset "long tuples" begin
longtuple = ntuple(i -> i in (15,17) ? 1 : 0, 40)
@test findfirst(isequal(1), longtuple) == 15
@test findlast(isequal(1), longtuple) == 17
end
end
@testset "properties" begin
ttest = (:a, :b, :c)
@test propertynames(ttest) == (1, 2, 3)
@test getproperty(ttest, 2) === :b
@test map(p->getproperty(ttest, p), propertynames(ttest)) == ttest
@test_throws ErrorException setproperty!(ttest, 1, :d)
end
# tuple_type_tail on non-normalized vararg tuple
@test Base.tuple_type_tail(Tuple{Vararg{T, 3}} where T<:Real) == Tuple{Vararg{T, 2}} where T<:Real
@test Base.tuple_type_tail(Tuple{Vararg{Int}}) == Tuple{Vararg{Int}}
@testset "setindex" begin
@test Base.setindex((1, ), 2, 1) === (2, )
@test Base.setindex((1, 2), 3, 1) === (3, 2)
@test_throws BoundsError Base.setindex((), 1, 1)
@test_throws BoundsError Base.setindex((1, ), 2, 2)
@test_throws BoundsError Base.setindex((1, 2), 2, 0)
@test_throws BoundsError Base.setindex((1, 2, 3), 2, -1)
@test_throws BoundsError Base.setindex((1, 2), 2, 3)
@test_throws BoundsError Base.setindex((1, 2), 2, 4)
@test Base.setindex((1, 2, 4), 4, true) === (4, 2, 4)
@test_throws BoundsError Base.setindex((1, 2), 2, false)
f() = Base.setindex((1:1, 2:2, 3:3), 9, 1)
@test @inferred(f()) == (9, 2:2, 3:3)
end
@testset "inferable range indexing with constant values" begin
whole(t) = t[1:end]
tail(t) = t[2:end]
ttail(t) = t[3:end]
front(t) = t[1:end-1]
ffront(t) = t[1:end-2]
@test @inferred( whole(())) == ()
@test @inferred( tail(())) == ()
@test @inferred( ttail(())) == ()
@test @inferred( front(())) == ()
@test @inferred(ffront(())) == ()
@test @inferred( whole((1,))) == (1,)
@test @inferred( tail((1,))) == ()
@test @inferred( ttail((1,))) == ()
@test @inferred( front((1,))) == ()
@test @inferred(ffront((1,))) == ()
@test @inferred( whole((1,2.0))) == (1,2.0)
@test @inferred( tail((1,2.0))) == (2.0,)
@test @inferred( ttail((1,2.0))) == ()
@test @inferred( front((1,2.0))) == (1.0,)
@test @inferred(ffront((1,2.0))) == ()
@test @inferred( whole((1,2.0,3//1))) == (1,2.0,3//1)
@test @inferred( tail((1,2.0,3//1))) == (2.0,3//1)
@test @inferred( ttail((1,2.0,3//1))) == (3//1,)
@test @inferred( front((1,2.0,3//1))) == (1,2.0)
@test @inferred(ffront((1,2.0,3//1))) == (1,)
@test @inferred( whole((1,2.0,3//1,0x04))) == (1,2.0,3//1,0x04)
@test @inferred( tail((1,2.0,3//1,0x04))) == (2.0,3//1,0x04)
@test @inferred( ttail((1,2.0,3//1,0x04))) == (3//1,0x04)
@test @inferred( front((1,2.0,3//1,0x04))) == (1,2.0,3//1)
@test @inferred(ffront((1,2.0,3//1,0x04))) == (1,2.0)
@test (1,)[0:-1] == ()
@test (1,)[1:0] == ()
@test (1,)[2:1] == ()
@test (1,2.0)[0:-1] == ()
@test (1,2.0)[1:0] == ()
@test (1,2.0)[2:1] == ()
@test (1,2.0)[3:2] == ()
@test_throws BoundsError (1,)[2:2]
@test_throws BoundsError (1,)[1:2]
@test_throws BoundsError (1,)[0:1]
@test_throws BoundsError (1,)[0:0]
@test_throws BoundsError (1,2.0)[3:3]
@test_throws BoundsError (1,2.0)[1:3]
@test_throws BoundsError (1,2.0)[0:2]
@test_throws BoundsError (1,2.0)[0:1]
@test_throws BoundsError (1,2.0)[0:0]
end
@testset "Base.rest" begin
t = (1, 2.0, 0x03, 4f0)
@test Base.rest(t) === t
@test Base.rest(t, 2) === (2.0, 0x03, 4f0)
a = [1 2; 3 4]
@test Base.rest(a) == a[:]
@test pointer(Base.rest(a)) != pointer(a)
@test Base.rest(a, 3) == [2, 4]
itr = (-i for i in a)
@test Base.rest(itr) == itr
_, st = iterate(itr)
r = Base.rest(itr, st)
@test r isa Iterators.Rest
@test collect(r) == -[3, 2, 4]
end
# issue #38837
f38837(xs) = map((F,x)->F(x), (Float32, Float64), xs)
@test @inferred(f38837((1,2))) === (1.0f0, 2.0)
@testset "indexing with UnitRanges" begin
f(t) = t[3:end-2]
@test @inferred(f(Tuple(1:10))) === Tuple(3:8)
@test @inferred(f((true, 2., 3, 4f0, 0x05, 6, 7.))) === (3, 4f0, 0x05)
f2(t) = t[Base.OneTo(5)]
@test @inferred(f2(Tuple(1:10))) === Tuple(1:5)
@test @inferred(f2((true, 2., 3, 4f0, 0x05, 6, 7.))) === (true, 2., 3, 4f0, 0x05)
@test @inferred((t -> t[1:end])(Tuple(1:15))) === Tuple(1:15)
@test @inferred((t -> t[2:end])(Tuple(1:15))) === Tuple(2:15)
@test @inferred((t -> t[3:end])(Tuple(1:15))) === Tuple(3:15)
@test @inferred((t -> t[1:end-1])(Tuple(1:15))) === Tuple(1:14)
@test @inferred((t -> t[1:end-2])(Tuple(1:15))) === Tuple(1:13)
@test @inferred((t -> t[3:2])(Tuple(1:15))) === ()
@test_throws BoundsError (1, 2)[1:4]
@test_throws BoundsError (1, 2)[0:2]
@test_throws ArgumentError (1, 2)[OffsetArrays.IdOffsetRange(1:2, -1)]
end
# https://github.com/JuliaLang/julia/issues/40814
@test Base.return_types(NTuple{3,Int}, (Vector{Int},)) == Any[NTuple{3,Int}]
# issue #42457
f42457(a::NTuple{3,Int}, b::Tuple)::Bool = Base.isequal(a, Base.inferencebarrier(b)::Tuple)
@test f42457((1, 1, 1), (1, 1, 1))
@test !isempty(methods(Base._isequal, (NTuple{3, Int}, Tuple)))
g42457(a, b) = Base.isequal(a, b) ? 1 : 2.0
@test only(Base.return_types(g42457, (NTuple{3, Int}, Tuple))) === Union{Float64, Int}
@test only(Base.return_types(g42457, (NTuple{3, Int}, NTuple))) === Union{Float64, Int}
@test only(Base.return_types(g42457, (NTuple{3, Int}, NTuple{4}))) === Float64
# issue #46049: setindex(::Tuple) regression
@inferred Base.setindex((1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16), 42, 1)
# issue #50562
f50562(r) = in(:i_backward, r[])
r50562 = Ref((:b_back, :foofakgka, :i_backw))
f50562(r50562)
@test @allocated(f50562(r50562)) == 0
# issue #47326
function fun1_47326(args...)
head..., tail = args
head
end
function fun2_47326(args...)
head, tail... = args
tail
end
@test @inferred(fun1_47326(1,2,3)) === (1, 2)
@test @inferred(fun2_47326(1,2,3)) === (2, 3)
f47326(x::Union{Tuple, NamedTuple}) = Base.split_rest(x, 1)
tup = (1, 2, 3)
namedtup = (;a=1, b=2, c=3)
@test only(Base.return_types(f47326, (typeof(tup),))) == Tuple{Tuple{Int, Int}, Tuple{Int}}
@test only(Base.return_types(f47326, (typeof(namedtup),))) ==
Tuple{
NamedTuple{(:a, :b), Tuple{Int, Int}},
NamedTuple{(:c,), Tuple{Int}},
}
# Make sure that tuple iteration is foldable
@test Core.Compiler.is_foldable(Base.infer_effects(iterate, Tuple{NTuple{4, Float64}, Int}))
@test Core.Compiler.is_foldable(Base.infer_effects(eltype, Tuple{Tuple}))
# some basic equivalence handling tests for Union{} appearing in Tuple Vararg parameters
@test Tuple{} <: Tuple{Vararg{Union{}}}
@test Tuple{Int} <: Tuple{Int, Vararg{Union{}}}
@test_throws ErrorException("Tuple field type cannot be Union{}") Tuple{Int, Vararg{Union{},1}}
@test_throws ErrorException("Tuple field type cannot be Union{}") Tuple{Vararg{Union{},1}}
@test Tuple{} <: Tuple{Vararg{Union{},N}} where N
@test !(Tuple{} >: Tuple{Vararg{Union{},N}} where N)
@test Val{Tuple{T,T,T} where T} === Val{Tuple{Vararg{T,3}} where T}
@test Val{Tuple{Vararg{T,4}} where T} === Val{Tuple{T,T,T,T} where T}
@test Val{Tuple{Int64, Vararg{Int32,N}} where N} === Val{Tuple{Int64, Vararg{Int32}}}
@test Val{Tuple{Int32, Vararg{Int64}}} === Val{Tuple{Int32, Vararg{Int64,N}} where N}
@testset "from Pair, issue #52636" begin
pair = (1 => "2")
@test (1, "2") == @inferred Tuple(pair)
@test (1, "2") == @inferred Tuple{Int,String}(pair)
end
@testset "circshift" begin
t1 = (1, 2, 3, 4, 5)
t2 = (1, 'a', -7.0, 3)
t3 = ('a', 'b', 'c', 'd')
@test @inferred(Base.circshift(t1, 2)) == (4, 5, 1, 2, 3)
# The return type of mixed tuples with runtime shift cannot be inferred.
@test Base.circshift(t2, 3) == ('a', -7.0, 3, 1)
@test @inferred(Base.circshift(t3, 7)) == ('b', 'c', 'd', 'a')
@test @inferred(Base.circshift(t3, -1)) == ('b', 'c', 'd', 'a')
@test_throws MethodError circshift(t1, 'a')
end
![swh spinner](/static/img/swh-spinner.gif)
Computing file changes ...