diff --git a/base/abstractarray.jl b/base/abstractarray.jl index 5ec677a2db340..3313666ef5724 100644 --- a/base/abstractarray.jl +++ b/base/abstractarray.jl @@ -1009,20 +1009,18 @@ replace_in_print_matrix(A::AbstractMatrix,i::Integer,j::Integer,s::AbstractStrin replace_in_print_matrix(A::AbstractVector,i::Integer,j::Integer,s::AbstractString) = s ## Concatenation ## -eltypeof(x) = typeof(x) -eltypeof(x::AbstractArray) = eltype(x) - -promote_eltypeof() = Bottom -promote_eltypeof(v1, vs...) = promote_type(eltypeof(v1), promote_eltypeof(vs...)) - promote_eltype() = Bottom promote_eltype(v1, vs...) = promote_type(eltype(v1), promote_eltype(vs...)) +eltyped_vcat{T}(::Type{T}, args...) = typed_vcat(Array{T}, args...) +eltyped_hcat{T}(::Type{T}, args...) = typed_hcat(Array{T}, args...) +eltyped_hvcat{T}(::Type{T}, args...) = typed_hvcat(Array{T}, args...) + #TODO: ERROR CHECK cat(catdim::Integer) = Array{Any,1}(0) -typed_vcat{T}(::Type{T}) = Array{T,1}(0) -typed_hcat{T}(::Type{T}) = Array{T,1}(0) +typed_vcat{T}(::Type{T}) = similar(T, 0) +typed_hcat{T}(::Type{T}) = similar(T, 0) ## cat: special cases vcat{T}(X::T...) = T[ X[i] for i=1:length(X) ] @@ -1032,18 +1030,17 @@ hcat{T<:Number}(X::T...) = T[ X[j] for i=1:1, j=1:length(X) ] vcat(X::Number...) = hvcat_fill(Array{promote_typeof(X...)}(length(X)), X) hcat(X::Number...) = hvcat_fill(Array{promote_typeof(X...)}(1,length(X)), X) -typed_vcat{T}(::Type{T}, X::Number...) = hvcat_fill(Array{T,1}(length(X)), X) -typed_hcat{T}(::Type{T}, X::Number...) = hvcat_fill(Array{T,2}(1,length(X)), X) +typed_vcat{T}(::Type{T}, X::Number...) = hvcat_fill(similar(T, length(X)), X) +typed_hcat{T}(::Type{T}, X::Number...) = hvcat_fill(similar(T, 1, length(X)), X) -vcat(V::AbstractVector...) = typed_vcat(promote_eltype(V...), V...) -vcat{T}(V::AbstractVector{T}...) = typed_vcat(T, V...) +vcat(V::AbstractVector...) = typed_vcat(promote_typeof_cat(V...), V...) function typed_vcat{T}(::Type{T}, V::AbstractVector...) n::Int = 0 for Vk in V n += length(Vk) end - a = similar(V[1], T, n) + a = similar(T, n) pos = 1 for k=1:length(V) Vk = V[k] @@ -1054,8 +1051,7 @@ function typed_vcat{T}(::Type{T}, V::AbstractVector...) a end -hcat(A::AbstractVecOrMat...) = typed_hcat(promote_eltype(A...), A...) -hcat{T}(A::AbstractVecOrMat{T}...) = typed_hcat(T, A...) +hcat(A::AbstractVecOrMat...) = typed_hcat(promote_typeof_cat(A...), A...) function typed_hcat{T}(::Type{T}, A::AbstractVecOrMat...) nargs = length(A) @@ -1071,7 +1067,7 @@ function typed_hcat{T}(::Type{T}, A::AbstractVecOrMat...) nd = ndims(Aj) ncols += (nd==2 ? size(Aj,2) : 1) end - B = similar(A[1], T, nrows, ncols) + B = similar(T, nrows, ncols) pos = 1 if dense for k=1:nargs @@ -1091,8 +1087,7 @@ function typed_hcat{T}(::Type{T}, A::AbstractVecOrMat...) return B end -vcat(A::AbstractMatrix...) = typed_vcat(promote_eltype(A...), A...) -vcat{T}(A::AbstractMatrix{T}...) = typed_vcat(T, A...) +vcat(A::AbstractMatrix...) = typed_vcat(promote_typeof_cat(A...), A...) function typed_vcat{T}(::Type{T}, A::AbstractMatrix...) nargs = length(A) @@ -1103,7 +1098,7 @@ function typed_vcat{T}(::Type{T}, A::AbstractMatrix...) throw(ArgumentError("number of columns of each array must match (got $(map(x->size(x,2), A)))")) end end - B = similar(A[1], T, nrows, ncols) + B = similar(T, nrows, ncols) pos = 1 for k=1:nargs Ak = A[k] @@ -1125,9 +1120,6 @@ cat_size(A::AbstractArray, d) = size(A, d) cat_indices(A, d) = OneTo(1) cat_indices(A::AbstractArray, d) = indices(A, d) -cat_similar(A, T, shape) = Array{T}(shape) -cat_similar(A::AbstractArray, T, shape) = similar(A, T, shape) - cat_shape(dims, shape::Tuple) = shape @inline cat_shape(dims, shape::Tuple, nshape::Tuple, shapes::Tuple...) = cat_shape(dims, _cshp(dims, (), shape, nshape), shapes...) @@ -1157,14 +1149,24 @@ _cs(d, concat, a, b) = concat ? (a + b) : (a == b ? a : throw(DimensionMismatch( dims2cat{n}(::Type{Val{n}}) = ntuple(i -> (i == n), Val{n}) dims2cat(dims) = ntuple(i -> (i in dims), maximum(dims)) -cat(dims, X...) = cat_t(dims, promote_eltypeof(X...), X...) +promote_type_cat(::Type{S}, ::Type{T}) where {S<:AbstractArray, T<:AbstractArray} = + Array{promote_type(eltype(S), eltype(T))} +promote_type_cat(::Type{T}, ::Type{Union{}}) where {T<:AbstractArray} = + Array{eltype(T)} + +promote_typeof_cat{T<:AbstractArray}(v1::T) = T +promote_typeof_cat{T}(v1::T) = Array{T} +promote_typeof_cat{T<:AbstractArray}(v1::T, vs...) = promote_type_cat(T, promote_typeof_cat(vs...)) +promote_typeof_cat{T}(v1::T, vs...) = promote_type_cat(Array{T}, promote_typeof_cat(vs...)) + +cat(dims, X...) = cat_t(dims, promote_typeof_cat(X...), X...) function cat_t(dims, T::Type, X...) catdims = dims2cat(dims) shape = cat_shape(catdims, (), map(cat_size, X)...) - A = cat_similar(X[1], T, shape) - if T <: Number && countnz(catdims) > 1 - fill!(A, zero(T)) + A = similar(T, shape) + if eltype(T) <: Number && countnz(catdims) > 1 + fill!(A, zero(eltype(T))) end return _cat(A, shape, catdims, X...) end @@ -1264,8 +1266,6 @@ hcat(X...) = cat(Val{2}, X...) typed_vcat(T::Type, X...) = cat_t(Val{1}, T, X...) typed_hcat(T::Type, X...) = cat_t(Val{2}, T, X...) -cat{T}(catdims, A::AbstractArray{T}...) = cat_t(catdims, T, A...) - # The specializations for 1 and 2 inputs are important # especially when running with --inline=no, see #11158 vcat(A::AbstractArray) = cat(Val{1}, A) @@ -1330,8 +1330,7 @@ julia> hvcat((2,2,2), a,b,c,d,e,f) If the first argument is a single integer `n`, then all block rows are assumed to have `n` block columns. """ -hvcat(rows::Tuple{Vararg{Int}}, xs::AbstractVecOrMat...) = typed_hvcat(promote_eltype(xs...), rows, xs...) -hvcat{T}(rows::Tuple{Vararg{Int}}, xs::AbstractVecOrMat{T}...) = typed_hvcat(T, rows, xs...) +hvcat(rows::Tuple{Vararg{Int}}, xs::AbstractVecOrMat...) = typed_hvcat(promote_typeof_cat(xs...), rows, xs...) function typed_hvcat{T}(::Type{T}, rows::Tuple{Vararg{Int}}, as::AbstractVecOrMat...) nbr = length(rows) # number of block rows @@ -1348,7 +1347,7 @@ function typed_hvcat{T}(::Type{T}, rows::Tuple{Vararg{Int}}, as::AbstractVecOrMa a += rows[i] end - out = similar(as[1], T, nr, nc) + out = similar(T, nr, nc) a = 1 r = 1 @@ -1377,7 +1376,7 @@ function typed_hvcat{T}(::Type{T}, rows::Tuple{Vararg{Int}}, as::AbstractVecOrMa end hvcat(rows::Tuple{Vararg{Int}}) = [] -typed_hvcat{T}(::Type{T}, rows::Tuple{Vararg{Int}}) = Array{T,1}(0) +typed_hvcat{T}(::Type{T}, rows::Tuple{Vararg{Int}}) = similar(T, 0) function hvcat{T<:Number}(rows::Tuple{Vararg{Int}}, xs::T...) nr = length(rows) @@ -1412,7 +1411,7 @@ function hvcat_fill(a::Array, xs::Tuple) a end -hvcat(rows::Tuple{Vararg{Int}}, xs::Number...) = typed_hvcat(promote_typeof(xs...), rows, xs...) +hvcat(rows::Tuple{Vararg{Int}}, xs::Number...) = typed_hvcat(Matrix{promote_typeof(xs...)}, rows, xs...) function typed_hvcat{T}(::Type{T}, rows::Tuple{Vararg{Int}}, xs::Number...) nr = length(rows) @@ -1426,7 +1425,7 @@ function typed_hvcat{T}(::Type{T}, rows::Tuple{Vararg{Int}}, xs::Number...) if nr*nc != len throw(ArgumentError("argument count $(len) does not match specified shape $((nr,nc))")) end - hvcat_fill(Array{T,2}(nr, nc), xs) + hvcat_fill(similar(T, nr, nc), xs) end # fallback definition of hvcat in terms of hcat and vcat @@ -1449,7 +1448,7 @@ function typed_hvcat{T}(::Type{T}, rows::Tuple{Vararg{Int}}, as...) rs[i] = typed_hcat(T, as[a:a-1+rows[i]]...) a += rows[i] end - T[rs...;] + eltype(T)[rs...;] end ## Reductions and accumulates ## diff --git a/base/array.jl b/base/array.jl index 153f7cbf942c8..031fcbf0d6b02 100644 --- a/base/array.jl +++ b/base/array.jl @@ -181,6 +181,8 @@ similar{T}(a::Array{T}, m::Int) = Array{T,1}(m) similar{N}(a::Array, T::Type, dims::Dims{N}) = Array{T,N}(dims) similar{T,N}(a::Array{T}, dims::Dims{N}) = Array{T,N}(dims) +similar{T,A<:Array{T},N}(::Type{A}, dims::Dims{N}) = Array{T, N}(dims) + # T[x...] constructs Array{T,1} function getindex{T}(::Type{T}, vals...) a = Array{T,1}(length(vals)) diff --git a/base/sparse/sparse.jl b/base/sparse/sparse.jl index 8f97fcecb57de..125ec3fc38252 100644 --- a/base/sparse/sparse.jl +++ b/base/sparse/sparse.jl @@ -22,9 +22,9 @@ import Base: @get!, acos, acosd, acot, acotd, acsch, asech, asin, asind, asinh, broadcast, ceil, complex, cond, conj, convert, copy, copy!, ctranspose, diagm, exp, expm1, factorize, find, findmax, findmin, findnz, float, full, getindex, vcat, hcat, hvcat, cat, imag, indmax, ishermitian, kron, length, log, log1p, max, min, - maximum, minimum, norm, one, promote_eltype, real, reinterpret, reshape, rot180, - rotl90, rotr90, round, scale!, setindex!, similar, size, transpose, tril, - triu, vec, permute!, map, map! + maximum, minimum, norm, one, promote_eltype, promote_type_cat, promote_typeof_cat, real, + reinterpret, reshape, rot180, rotl90, rotr90, round, scale!, setindex!, similar, size, + transpose, tril, triu, vec, permute!, map, map! import Base.Broadcast: broadcast_indices diff --git a/base/sparse/sparsematrix.jl b/base/sparse/sparsematrix.jl index d5600a5aebea7..04d5b8e7d43aa 100644 --- a/base/sparse/sparsematrix.jl +++ b/base/sparse/sparsematrix.jl @@ -300,6 +300,7 @@ function similar{Tv,Ti}(S::SparseMatrixCSC, ::Type{Tv}, ::Type{Ti}) SparseMatrixCSC(S.m, S.n, new_colptr, new_rowval, new_nzval) end @inline similar{Tv}(S::SparseMatrixCSC, ::Type{Tv}, d::Dims) = spzeros(Tv, d...) +@inline similar{Tv}(::Type{SparseMatrixCSC{Tv}}, d::Dims) = spzeros(Tv, d...) # convert'ing between SparseMatrixCSC types convert{Tv}(::Type{AbstractMatrix{Tv}}, A::SparseMatrixCSC{Tv}) = A @@ -2938,7 +2939,6 @@ end end end - function hcat(X::SparseMatrixCSC...) num = length(X) mX = Int[ size(x, 1) for x in X ] diff --git a/base/sparse/sparsevector.jl b/base/sparse/sparsevector.jl index a4f7bac6b244a..82d4e71687c81 100644 --- a/base/sparse/sparsevector.jl +++ b/base/sparse/sparsevector.jl @@ -928,16 +928,25 @@ const _Symmetric_DenseArrays{T,A<:Matrix} = Symmetric{T,A} const _Hermitian_DenseArrays{T,A<:Matrix} = Hermitian{T,A} const _Triangular_DenseArrays{T,A<:Matrix} = Base.LinAlg.AbstractTriangular{T,A} const _Annotated_DenseArrays = Union{_Triangular_DenseArrays, _Symmetric_DenseArrays, _Hermitian_DenseArrays} -const _Annotated_Typed_DenseArrays{T} = Union{_Triangular_DenseArrays{T}, _Symmetric_DenseArrays{T}, _Hermitian_DenseArrays{T}} const _SparseConcatGroup = Union{Vector, Matrix, _SparseConcatArrays, _Annotated_SparseConcatArrays, _Annotated_DenseArrays} const _DenseConcatGroup = Union{Vector, Matrix, _Annotated_DenseArrays} -const _TypedDenseConcatGroup{T} = Union{Vector{T}, Matrix{T}, _Annotated_Typed_DenseArrays{T}} + +promote_type_cat(::Type{S}, ::Type{T}) where {S<:AbstractArray, + T<:Union{_SparseConcatArrays,_Annotated_SparseConcatArrays}} = + SparseMatrixCSC{promote_type(eltype(S), eltype(T))} +promote_type_cat(::Type{S}, ::Type{T}) where {S<:Union{_SparseConcatArrays,_Annotated_SparseConcatArrays}, + T<:AbstractArray} = + SparseMatrixCSC{promote_type(eltype(S), eltype(T))} +promote_type_cat(::Type{S}, ::Type{T}) where {S<:Union{_SparseConcatArrays,_Annotated_SparseConcatArrays}, + T<:Union{_SparseConcatArrays,_Annotated_SparseConcatArrays}} = + SparseMatrixCSC{promote_type(eltype(S), eltype(T))} # Concatenations involving un/annotated sparse/special matrices/vectors should yield sparse arrays function cat(catdims, Xin::_SparseConcatGroup...) + # FIXME: still needed? (same below) X = map(x -> SparseMatrixCSC(issparse(x) ? x : sparse(x)), Xin) - T = promote_eltype(Xin...) + T = promote_typeof_cat(Xin...) Base.cat_t(catdims, T, X...) end function hcat(Xin::_SparseConcatGroup...) @@ -965,18 +974,14 @@ promote_to_array_type(A::Tuple{Vararg{Union{_SparseConcatGroup,UniformScaling}}} promote_to_array_type(A::Tuple{Vararg{Union{_DenseConcatGroup,UniformScaling}}}) = (@_pure_meta; Matrix) promote_to_arrays_(n::Int, ::Type{SparseMatrixCSC}, J::UniformScaling) = sparse(J, n, n) +# FIXME: these should be unnecessary now, and _DenseConcatGroup too # Concatenations strictly involving un/annotated dense matrices/vectors should yield dense arrays -cat(catdims, xs::_DenseConcatGroup...) = Base.cat_t(catdims, promote_eltype(xs...), xs...) -vcat(A::Vector...) = Base.typed_vcat(promote_eltype(A...), A...) -vcat(A::_DenseConcatGroup...) = Base.typed_vcat(promote_eltype(A...), A...) -hcat(A::Vector...) = Base.typed_hcat(promote_eltype(A...), A...) -hcat(A::_DenseConcatGroup...) = Base.typed_hcat(promote_eltype(A...), A...) -hvcat(rows::Tuple{Vararg{Int}}, xs::_DenseConcatGroup...) = Base.typed_hvcat(promote_eltype(xs...), rows, xs...) -# For performance, specially handle the case where the matrices/vectors have homogeneous eltype -cat{T}(catdims, xs::_TypedDenseConcatGroup{T}...) = Base.cat_t(catdims, T, xs...) -vcat{T}(A::_TypedDenseConcatGroup{T}...) = Base.typed_vcat(T, A...) -hcat{T}(A::_TypedDenseConcatGroup{T}...) = Base.typed_hcat(T, A...) -hvcat{T}(rows::Tuple{Vararg{Int}}, xs::_TypedDenseConcatGroup{T}...) = Base.typed_hvcat(T, rows, xs...) +cat(catdims, xs::_DenseConcatGroup...) = Base.cat_t(catdims, promote_typeof_cat(xs...), xs...) +vcat(A::Vector...) = Base.typed_vcat(promote_typeof_cat(A...), A...) +vcat(A::_DenseConcatGroup...) = Base.typed_vcat(promote_typeof_cat(A...), A...) +hcat(A::Vector...) = Base.typed_hcat(promote_typeof_cat(A...), A...) +hcat(A::_DenseConcatGroup...) = Base.typed_hcat(promote_typeof_cat(A...), A...) +hvcat(rows::Tuple{Vararg{Int}}, xs::_DenseConcatGroup...) = Base.typed_hvcat(promote_typeof_cat(xs...), rows, xs...) ### math functions diff --git a/doc/src/devdocs/ast.md b/doc/src/devdocs/ast.md index bacb91e1bd0e3..2f3241554e5c2 100644 --- a/doc/src/devdocs/ast.md +++ b/doc/src/devdocs/ast.md @@ -390,9 +390,9 @@ call. Finally, chains of comparisons have their own special expression structure | Input | AST | |:------------------------ |:------------------------------------ | | `a[i]` | `(ref a i)` | -| `t[i;j]` | `(typed_vcat t i j)` | -| `t[i j]` | `(typed_hcat t i j)` | -| `t[a b; c d]` | `(typed_vcat t (row a b) (row c d))` | +| `t[i;j]` | `(eltyped_vcat t i j)` | +| `t[i j]` | `(eltyped_hcat t i j)` | +| `t[a b; c d]` | `(eltyped_vcat t (row a b) (row c d))` | | `a{b}` | `(curly a b)` | | `a{b;c}` | `(curly a (parameters c) b)` | | `[x]` | `(vect x)` | diff --git a/src/julia-parser.scm b/src/julia-parser.scm index 0a0633a3fbcb3..12ff823ba938e 100644 --- a/src/julia-parser.scm +++ b/src/julia-parser.scm @@ -1052,9 +1052,9 @@ (loop (list 'ref ex)) (case (car al) ((vect) (loop (list* 'ref ex (cdr al)))) - ((hcat) (loop (list* 'typed_hcat ex (cdr al)))) + ((hcat) (loop (list* 'eltyped_hcat ex (cdr al)))) ((vcat) - (loop (list* 'typed_vcat ex (cdr al)))) + (loop (list* 'eltyped_vcat ex (cdr al)))) ((comprehension) (loop (list* 'typed_comprehension ex (cdr al)))) (else (error "unknown parse-cat result (internal error)")))))) diff --git a/src/julia-syntax.scm b/src/julia-syntax.scm index b8caa322685bb..98802c5fcdc05 100644 --- a/src/julia-syntax.scm +++ b/src/julia-syntax.scm @@ -1518,7 +1518,7 @@ ,(expand-update-operator op op= (car e) rhs T)))) (else (if (and (pair? lhs) - (not (memq (car lhs) '(|.| tuple vcat typed_hcat typed_vcat)))) + (not (memq (car lhs) '(|.| tuple vcat eltyped_hcat eltyped_vcat)))) (error (string "invalid assignment location \"" (deparse lhs) "\""))) (expand-update-operator- op op= lhs rhs declT)))) @@ -1914,9 +1914,9 @@ (iota (length lhss)) lhss) (unnecessary ,xx)))))) - ((typed_hcat) + ((eltyped_hcat) (error "invalid spacing in left side of indexed assignment")) - ((typed_vcat) + ((eltyped_vcat) (error "unexpected \";\" in left side of indexed assignment")) ((ref) ;; (= (ref a . idxs) rhs) @@ -2210,10 +2210,10 @@ ,.(apply append rows))) `(call vcat ,@a)))))) - 'typed_hcat - (lambda (e) `(call (top typed_hcat) ,(expand-forms (cadr e)) ,.(map expand-forms (cddr e)))) + 'eltyped_hcat + (lambda (e) `(call (top eltyped_hcat) ,(expand-forms (cadr e)) ,.(map expand-forms (cddr e)))) - 'typed_vcat + 'eltyped_vcat (lambda (e) (let ((t (cadr e)) (a (cddr e))) @@ -2227,10 +2227,10 @@ (cdr x) (list x))) a))) - `(call (top typed_hvcat) ,t + `(call (top eltyped_hvcat) ,t (tuple ,.(map length rows)) ,.(apply append rows))) - `(call (top typed_vcat) ,t ,@a))))) + `(call (top eltyped_vcat) ,t ,@a))))) '|'| (lambda (e) `(call ctranspose ,(expand-forms (cadr e)))) '|.'| (lambda (e) `(call transpose ,(expand-forms (cadr e)))) diff --git a/test/abstractarray.jl b/test/abstractarray.jl index b97c51066b798..22e7df437959c 100644 --- a/test/abstractarray.jl +++ b/test/abstractarray.jl @@ -231,8 +231,16 @@ Base.convert{T,N }(::Type{TSlow{T,N}}, X::AbstractArray ) = begin A end +Base.promote_type_cat(::Type{S}, ::Type{T}) where {S<:TSlow, T<:AbstractArray} = + TSlow{promote_type(eltype(S), eltype(T))} +Base.promote_type_cat(::Type{S}, ::Type{T}) where {S<:AbstractArray, T<:TSlow} = + TSlow{promote_type(eltype(S), eltype(T))} +Base.promote_type_cat(::Type{S}, ::Type{T}) where {S<:TSlow, T<:TSlow} = + TSlow{promote_type(eltype(S), eltype(T))} + Base.size(A::TSlow) = A.dims Base.similar{T}(A::TSlow, ::Type{T}, dims::Dims) = TSlow(T, dims) +Base.similar{T, A<:TSlow{T}}(::Type{A}, dims::Dims) = TSlow(T, dims) import Base: IndexCartesian Base.IndexStyle{A<:TSlow}(::Type{A}) = IndexCartesian() # Until #11242 is merged, we need to define each dimension independently @@ -560,9 +568,9 @@ function test_cat(::Type{TestAbstractArray}) @test vcat(B) == B @test hcat(B) == B - @test Base.typed_hcat(Float64, B) == TSlow(b_float) - @test Base.typed_hcat(Float64, B, B) == TSlow(b2hcat) - @test Base.typed_hcat(Float64, B, B, B) == TSlow(b3hcat) + @test Base.eltyped_hcat(Float64, B) == TSlow(b_float) + @test Base.eltyped_hcat(Float64, B, B) == TSlow(b2hcat) + @test Base.eltyped_hcat(Float64, B, B, B) == TSlow(b3hcat) @test vcat(B1, B2) == TSlow(vcat([1:24...], [1:25...])) @test hcat(C1, C2) == TSlow([1 2 1 2 3; 3 4 4 5 6]) @@ -584,10 +592,10 @@ function test_cat(::Type{TestAbstractArray}) # check for shape mismatch @test_throws ArgumentError hvcat((2, 2), 1, 2, 3, 4, 5) - @test_throws ArgumentError Base.typed_hvcat(Int, (2, 2), 1, 2, 3, 4, 5) + @test_throws ArgumentError Base.eltyped_hvcat(Int, (2, 2), 1, 2, 3, 4, 5) # check for # of columns mismatch b/w rows @test_throws ArgumentError hvcat((3, 2), 1, 2, 3, 4, 5, 6) - @test_throws ArgumentError Base.typed_hvcat(Int, (3, 2), 1, 2, 3, 4, 5, 6) + @test_throws ArgumentError Base.eltyped_hvcat(Int, (3, 2), 1, 2, 3, 4, 5, 6) # 18395 @test isa(Any["a" 5; 2//3 1.0][2,1], Rational{Int})