From 476a59beb754ee8d6b5262e32a52d6396e0ec101 Mon Sep 17 00:00:00 2001 From: Sheehan Olver Date: Fri, 25 Sep 2020 10:07:21 +0100 Subject: [PATCH 01/10] Remove Int call --- base/subarray.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base/subarray.jl b/base/subarray.jl index de99ba48f275d..a9d7e855b9bd8 100644 --- a/base/subarray.jl +++ b/base/subarray.jl @@ -60,7 +60,7 @@ viewindexing(I::Tuple{Vararg{Any}}) = IndexCartesian() viewindexing(I::Tuple{AbstractArray, Vararg{Any}}) = IndexCartesian() # Simple utilities -size(V::SubArray) = (@_inline_meta; map(n->Int(unsafe_length(n)), axes(V))) +size(V::SubArray) = (@_inline_meta; map(unsafe_length, axes(V))) similar(V::SubArray, T::Type, dims::Dims) = similar(V.parent, T, dims) From 1d8f1fb1d3e899952dc0e5342f358472db6e9500 Mon Sep 17 00:00:00 2001 From: Sheehan Olver Date: Sat, 26 Sep 2020 08:30:08 +0100 Subject: [PATCH 02/10] Add tests --- test/subarray.jl | 13 +++++++++++ test/testhelpers/InfiniteArrays.jl | 37 ++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 test/testhelpers/InfiniteArrays.jl diff --git a/test/subarray.jl b/test/subarray.jl index 4fd189e2ae441..a406727ed1d10 100644 --- a/test/subarray.jl +++ b/test/subarray.jl @@ -698,3 +698,16 @@ import InteractiveUtils @test M*v == copy(M)*v @test (InteractiveUtils.@which M*v) == (InteractiveUtils.@which copy(M)*v) end + + +isdefined(Main, :InfiniteArrays) || @eval Main include("testhelpers/InfiniteArrays.jl") +using .Main.InfiniteArrays + +@testset "PR #37741: non-Int sizes" begin + r = BigInt(1):BigInt(100_000_000)^100 + v = SubArray(r, (r,)) + @test size(v) == (last(r),) + + v = SubArray(OneToInf(), (OneToInf(),)) + @test size(v) == (Infinity(),) +end diff --git a/test/testhelpers/InfiniteArrays.jl b/test/testhelpers/InfiniteArrays.jl new file mode 100644 index 0000000000000..b86934e883308 --- /dev/null +++ b/test/testhelpers/InfiniteArrays.jl @@ -0,0 +1,37 @@ +# This file is a part of Julia. License is MIT: https://julialang.org/license + +# InfiniteArrays (arrays with infinite size) + +# This test file is designed to exercise support for generic sizing, +# even though infinite arrays aren't implemented in Base. + +module InfiniteArrays + +export OneToInf, Infinity + +""" + Infinity() + +represents infinite cardinality. Note that `Infinity <: Integer` to support +being treated as an index. +""" +struct Infinity <: Integer end + +""" + OneToInf(n) + +Define an `AbstractInfUnitRange` that behaves like `1:∞`, with the added +distinction that the limits are guaranteed (by the type system) to +be 1 and ∞. +""" +struct OneToInf{T<:Integer} <: AbstractUnitRange{T} end + +OneToInf() = OneToInf{Int}() + +Base.axes(r::OneToInf) = (r,) +Base.unsafe_indices(r::OneToInf) = (r,) +Base.unsafe_length(r::OneToInf) = Infinity() +Base.size(r::OneToInf) = (Infinity(),) +Base.first(r::OneToInf{T}) where {T} = oneunit(T) + +end \ No newline at end of file From 433fb9ea5bb7425dce22fcd35a742880b65e6074 Mon Sep 17 00:00:00 2001 From: Sheehan Olver Date: Sat, 26 Sep 2020 14:54:33 +0100 Subject: [PATCH 03/10] _typed_vcat! --- base/abstractarray.jl | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/base/abstractarray.jl b/base/abstractarray.jl index 478130f4834da..633a92472a345 100644 --- a/base/abstractarray.jl +++ b/base/abstractarray.jl @@ -1437,12 +1437,11 @@ vcat(V::AbstractVector{T}...) where {T} = typed_vcat(T, V...) # but that solution currently fails (see #27188 and #27224) AbstractVecOrTuple{T} = Union{AbstractVector{<:T}, Tuple{Vararg{T}}} -function _typed_vcat(::Type{T}, V::AbstractVecOrTuple{AbstractVector}) where T - n = 0 - for Vk in V - n += Int(length(Vk))::Int - end - a = similar(V[1], T, n) +_typed_vcat_similar(V, T, n) = similar(V[1], T, n) +_typed_vcat(::Type{T}, V::AbstractVecOrTuple{AbstractVector}) where T = + _typed_vcat!(_typed_vcat_similar(V, T, mapreduce(length, +, V)), V) + +function _typed_vcat!(a::AbstractVector{T}, V::AbstractVecOrTuple{AbstractVector}) where T pos = 1 for k=1:Int(length(V))::Int Vk = V[k] From a73d161867a2de853c42675945af2564d0b41d8b Mon Sep 17 00:00:00 2001 From: Sheehan Olver Date: Sat, 26 Sep 2020 15:25:28 +0100 Subject: [PATCH 04/10] Support infinite arrays in printing --- base/arrayshow.jl | 8 ++++---- test/subarray.jl | 3 ++- test/testhelpers/InfiniteArrays.jl | 12 ++++++++++++ 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/base/arrayshow.jl b/base/arrayshow.jl index 1cb002db24f8f..debb4de5288b4 100644 --- a/base/arrayshow.jl +++ b/base/arrayshow.jl @@ -58,9 +58,9 @@ Alignment is reported as a vector of (left,right) tuples, one for each column going across the screen. """ function alignment(io::IO, X::AbstractVecOrMat, - rows::AbstractVector, cols::AbstractVector, - cols_if_complete::Integer, cols_otherwise::Integer, sep::Integer) - a = Tuple{Int, Int}[] + rows::AbstractVector{T}, cols::AbstractVector{V}, + cols_if_complete::Integer, cols_otherwise::Integer, sep::Integer) where {T,V} + a = Tuple{T, V}[] for j in cols # need to go down each column one at a time l = r = 0 for i in rows # plumb down and see what largest element sizes are @@ -178,7 +178,7 @@ function print_matrix(io::IO, X::AbstractVecOrMat, postsp = "" @assert textwidth(hdots) == textwidth(ddots) sepsize = length(sep)::Int - rowsA, colsA = UnitRange{Int}(axes(X,1)), UnitRange{Int}(axes(X,2)) + rowsA, colsA = axes(X,1), axes(X,2) m, n = length(rowsA), length(colsA) # To figure out alignments, only need to look at as many rows as could # fit down screen. If screen has at least as many rows as A, look at A. diff --git a/test/subarray.jl b/test/subarray.jl index a406727ed1d10..0e07fc6f6494e 100644 --- a/test/subarray.jl +++ b/test/subarray.jl @@ -701,7 +701,7 @@ end isdefined(Main, :InfiniteArrays) || @eval Main include("testhelpers/InfiniteArrays.jl") -using .Main.InfiniteArrays +using .Main.InfiniteArrays, Base64 @testset "PR #37741: non-Int sizes" begin r = BigInt(1):BigInt(100_000_000)^100 @@ -710,4 +710,5 @@ using .Main.InfiniteArrays v = SubArray(OneToInf(), (OneToInf(),)) @test size(v) == (Infinity(),) + @test stringmime("text/plain", v; context=(:limit => true)) == "Infinity()-element view(::OneToInf{$Int}, 1:1:Infinity()) with eltype $Int with indices 1:1:Infinity():\n 1\n 2\n 3\n 4\n 5\n 6\n 7\n 8\n 9\n 10\n ⋮" end diff --git a/test/testhelpers/InfiniteArrays.jl b/test/testhelpers/InfiniteArrays.jl index b86934e883308..757bbe81ad507 100644 --- a/test/testhelpers/InfiniteArrays.jl +++ b/test/testhelpers/InfiniteArrays.jl @@ -17,6 +17,16 @@ being treated as an index. """ struct Infinity <: Integer end +Base.:(==)(::Infinity, ::Int) = false +Base.:(==)(::Int, ::Infinity) = false +Base.:(<)(::Int, ::Infinity) = true +Base.:(≤)(::Int, ::Infinity) = true +Base.:(≤)(::Infinity, ::Int) = false +Base.:(≤)(::Infinity, ::Infinity) = true +Base.:(-)(::Infinity, ::Int) = Infinity() +Base.:(+)(::Infinity, ::Int) = Infinity() +Base.:(:)(::Infinity, ::Infinity) = 1:0 + """ OneToInf(n) @@ -33,5 +43,7 @@ Base.unsafe_indices(r::OneToInf) = (r,) Base.unsafe_length(r::OneToInf) = Infinity() Base.size(r::OneToInf) = (Infinity(),) Base.first(r::OneToInf{T}) where {T} = oneunit(T) +Base.length(r::OneToInf{T}) where {T} = Infinity() +Base.last(r::OneToInf{T}) where {T} = Infinity() end \ No newline at end of file From e1159be5dd0c21ab51d8e7a3bdd7ca00b925d864 Mon Sep 17 00:00:00 2001 From: Sheehan Olver Date: Wed, 18 Nov 2020 15:22:56 +0000 Subject: [PATCH 05/10] Revert some of #37080 to fix #37741 --- base/abstractarray.jl | 4 ++-- test/abstractarray.jl | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/base/abstractarray.jl b/base/abstractarray.jl index ec53460edbcc4..9ba08fd9ab4fd 100644 --- a/base/abstractarray.jl +++ b/base/abstractarray.jl @@ -1631,7 +1631,7 @@ _cat(dims, X...) = cat_t(promote_eltypeof(X...), X...; dims=dims) @inline cat_t(::Type{T}, X...; dims) where {T} = _cat_t(dims, T, X...) @inline function _cat_t(dims, ::Type{T}, X...) where {T} catdims = dims2cat(dims) - shape = cat_shape(catdims, map(cat_size, X)::Tuple{Vararg{Union{Int,Dims}}})::Dims + shape = cat_shape(catdims, map(cat_size, X)) A = cat_similar(X[1], T, shape) if count(!iszero, catdims)::Int > 1 fill!(A, zero(T)) @@ -1639,7 +1639,7 @@ _cat(dims, X...) = cat_t(promote_eltypeof(X...), X...; dims=dims) return __cat(A, shape, catdims, X...) end -function __cat(A, shape::NTuple{M,Int}, catdims, X...) where M +function __cat(A, shape::NTuple{M}, catdims, X...) where M N = M::Int offsets = zeros(Int, N) inds = Vector{UnitRange{Int}}(undef, N) diff --git a/test/abstractarray.jl b/test/abstractarray.jl index cec1d5092a76f..502ba78910bb3 100644 --- a/test/abstractarray.jl +++ b/test/abstractarray.jl @@ -1200,3 +1200,8 @@ end _, st = iterate(a) @test Base.rest(a, st) == [3, 2, 4] end + +@testset "issue #37741, non-int cat" begin + @test [1; 1:BigInt(5)] == [1; 1:5] + @test [1:BigInt(5); 1] == [1:5; 1] +end \ No newline at end of file From 0cad296477096dff14d543d112cc6a0f5dc3abb7 Mon Sep 17 00:00:00 2001 From: Sheehan Olver Date: Tue, 1 Dec 2020 12:01:11 +0000 Subject: [PATCH 06/10] Update subarray.jl --- test/subarray.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/subarray.jl b/test/subarray.jl index 0e07fc6f6494e..19fd631d3ab1e 100644 --- a/test/subarray.jl +++ b/test/subarray.jl @@ -710,5 +710,5 @@ using .Main.InfiniteArrays, Base64 v = SubArray(OneToInf(), (OneToInf(),)) @test size(v) == (Infinity(),) - @test stringmime("text/plain", v; context=(:limit => true)) == "Infinity()-element view(::OneToInf{$Int}, 1:1:Infinity()) with eltype $Int with indices 1:1:Infinity():\n 1\n 2\n 3\n 4\n 5\n 6\n 7\n 8\n 9\n 10\n ⋮" + @test stringmime("text/plain", v; context=(:limit => true)) == "Main.InfiniteArrays.Infinity()-element view(::Main.InfiniteArrays.OneToInf{$Int}, 1:1:Main.InfiniteArrays.Infinity()) with eltype $Int with indices 1:1:Main.InfiniteArrays.Infinity():\n 1\n 2\n 3\n 4\n 5\n 6\n 7\n 8\n 9\n 10\n ⋮" end From 54bcf48e4ce6ae5824328139a0731b7738f5613f Mon Sep 17 00:00:00 2001 From: Sheehan Olver Date: Tue, 1 Dec 2020 22:14:11 +0000 Subject: [PATCH 07/10] Add Base.unitrange for converting to UnitRange in a generalisable way --- base/arrayshow.jl | 2 +- base/range.jl | 2 ++ test/subarray.jl | 2 +- test/testhelpers/InfiniteArrays.jl | 1 + 4 files changed, 5 insertions(+), 2 deletions(-) diff --git a/base/arrayshow.jl b/base/arrayshow.jl index 03112ba981efd..7b005d8104b59 100644 --- a/base/arrayshow.jl +++ b/base/arrayshow.jl @@ -178,7 +178,7 @@ function print_matrix(io::IO, @nospecialize(X::AbstractVecOrMat), postsp = "" @assert textwidth(hdots) == textwidth(ddots) sepsize = length(sep)::Int - rowsA, colsA = axes(X,1), axes(X,2) + rowsA, colsA = unitrange(axes(X,1)), unitrange(axes(X,2)) m, n = length(rowsA), length(colsA) # To figure out alignments, only need to look at as many rows as could # fit down screen. If screen has at least as many rows as A, look at A. diff --git a/base/range.jl b/base/range.jl index 2fd5866dc5d6b..ef880ca4d8016 100644 --- a/base/range.jl +++ b/base/range.jl @@ -292,6 +292,8 @@ unitrange_last(start::T, stop::T) where {T} = ifelse(stop >= start, convert(T,start+floor(stop-start)), convert(T,start-oneunit(stop-start))) +unitrange(x) = UnitRange(x) + if isdefined(Main, :Base) # Constant-fold-able indexing into tuples to functionally expose Base.tail and Base.front function getindex(@nospecialize(t::Tuple), r::UnitRange) diff --git a/test/subarray.jl b/test/subarray.jl index 19fd631d3ab1e..985b481438c5b 100644 --- a/test/subarray.jl +++ b/test/subarray.jl @@ -710,5 +710,5 @@ using .Main.InfiniteArrays, Base64 v = SubArray(OneToInf(), (OneToInf(),)) @test size(v) == (Infinity(),) - @test stringmime("text/plain", v; context=(:limit => true)) == "Main.InfiniteArrays.Infinity()-element view(::Main.InfiniteArrays.OneToInf{$Int}, 1:1:Main.InfiniteArrays.Infinity()) with eltype $Int with indices 1:1:Main.InfiniteArrays.Infinity():\n 1\n 2\n 3\n 4\n 5\n 6\n 7\n 8\n 9\n 10\n ⋮" + @test stringmime("text/plain", v; context=(:limit => true)) == "$(Infinity())-element view(::$(OneToInf{Int}), 1:1:$(Infinity())) with eltype $Int with indices 1:1:$(Infinity()):\n 1\n 2\n 3\n 4\n 5\n 6\n 7\n 8\n 9\n 10\n ⋮" end diff --git a/test/testhelpers/InfiniteArrays.jl b/test/testhelpers/InfiniteArrays.jl index 757bbe81ad507..c4d1d7e93f8ee 100644 --- a/test/testhelpers/InfiniteArrays.jl +++ b/test/testhelpers/InfiniteArrays.jl @@ -45,5 +45,6 @@ Base.size(r::OneToInf) = (Infinity(),) Base.first(r::OneToInf{T}) where {T} = oneunit(T) Base.length(r::OneToInf{T}) where {T} = Infinity() Base.last(r::OneToInf{T}) where {T} = Infinity() +Base.unitrange(r::OneToInf) = r end \ No newline at end of file From 859bc47a2e04dc50f5d1f6a4797cbd7a8b9ed940 Mon Sep 17 00:00:00 2001 From: Sheehan Olver Date: Wed, 2 Dec 2020 16:31:41 +0000 Subject: [PATCH 08/10] Add oneto --- base/abstractarray.jl | 8 ++++---- base/range.jl | 1 + base/reshapedarray.jl | 4 ++-- base/subarray.jl | 4 ++-- test/testhelpers/InfiniteArrays.jl | 1 + 5 files changed, 10 insertions(+), 8 deletions(-) diff --git a/base/abstractarray.jl b/base/abstractarray.jl index 6f9d715600226..24c493015684c 100644 --- a/base/abstractarray.jl +++ b/base/abstractarray.jl @@ -86,7 +86,7 @@ julia> axes(A) """ function axes(A) @_inline_meta - map(OneTo, size(A)) + map(oneto, size(A)) end """ @@ -107,10 +107,10 @@ require_one_based_indexing(A...) = !has_offset_axes(A...) || throw(ArgumentError # in other applications. axes1(A::AbstractArray{<:Any,0}) = OneTo(1) axes1(A::AbstractArray) = (@_inline_meta; axes(A)[1]) -axes1(iter) = OneTo(length(iter)) +axes1(iter) = oneto(length(iter)) unsafe_indices(A) = axes(A) -unsafe_indices(r::AbstractRange) = (OneTo(unsafe_length(r)),) # Ranges use checked_sub for size +unsafe_indices(r::AbstractRange) = (oneto(unsafe_length(r)),) # Ranges use checked_sub for size keys(a::AbstractArray) = CartesianIndices(axes(a)) keys(a::AbstractVector) = LinearIndices(a) @@ -308,7 +308,7 @@ function eachindex(A::AbstractArray, B::AbstractArray...) @_inline_meta eachindex(IndexStyle(A,B...), A, B...) end -eachindex(::IndexLinear, A::AbstractArray) = (@_inline_meta; OneTo(length(A))) +eachindex(::IndexLinear, A::AbstractArray) = (@_inline_meta; oneto(length(A))) eachindex(::IndexLinear, A::AbstractVector) = (@_inline_meta; axes1(A)) function eachindex(::IndexLinear, A::AbstractArray, B::AbstractArray...) @_inline_meta diff --git a/base/range.jl b/base/range.jl index ef880ca4d8016..d012537ec40e6 100644 --- a/base/range.jl +++ b/base/range.jl @@ -331,6 +331,7 @@ struct OneTo{T<:Integer} <: AbstractUnitRange{T} end OneTo(stop::T) where {T<:Integer} = OneTo{T}(stop) OneTo(r::AbstractRange{T}) where {T<:Integer} = OneTo{T}(r) +oneto(r) = OneTo(r) ## Step ranges parameterized by length diff --git a/base/reshapedarray.jl b/base/reshapedarray.jl index 3534049a7a10b..d9a9f4eafaa80 100644 --- a/base/reshapedarray.jl +++ b/base/reshapedarray.jl @@ -153,7 +153,7 @@ rdims(out::Tuple{}, inds::NTuple{M,Any}) where {M} = () rdims(out::Tuple{Any}, inds::Tuple{}) = out # N == 1, M == 0 rdims(out::NTuple{N,Any}, inds::Tuple{}) where {N} = out # N > 1, M == 0 rdims(out::Tuple{Any}, inds::Tuple{Any}) = inds # N == 1, M == 1 -rdims(out::Tuple{Any}, inds::NTuple{M,Any}) where {M} = (OneTo(rdims_trailing(inds...)),) # N == 1, M > 1 +rdims(out::Tuple{Any}, inds::NTuple{M,Any}) where {M} = (oneto(rdims_trailing(inds...)),) # N == 1, M > 1 rdims(out::NTuple{N,Any}, inds::NTuple{N,Any}) where {N} = inds # N > 1, M == N rdims(out::NTuple{N,Any}, inds::NTuple{M,Any}) where {N,M} = (first(inds), rdims(tail(out), tail(inds))...) # N > 1, M > 1, M != N @@ -207,7 +207,7 @@ size(A::ReshapedArray) = A.dims similar(A::ReshapedArray, eltype::Type, dims::Dims) = similar(parent(A), eltype, dims) IndexStyle(::Type{<:ReshapedArrayLF}) = IndexLinear() parent(A::ReshapedArray) = A.parent -parentindices(A::ReshapedArray) = map(OneTo, size(parent(A))) +parentindices(A::ReshapedArray) = map(oneto, size(parent(A))) reinterpret(::Type{T}, A::ReshapedArray, dims::Dims) where {T} = reinterpret(T, parent(A), dims) elsize(::Type{<:ReshapedArray{<:Any,<:Any,P}}) where {P} = elsize(P) diff --git a/base/subarray.jl b/base/subarray.jl index 23921efe9f72e..586bccf183dae 100644 --- a/base/subarray.jl +++ b/base/subarray.jl @@ -90,7 +90,7 @@ julia> parentindices(V) (1, Base.Slice(Base.OneTo(2))) ``` """ -parentindices(a::AbstractArray) = map(OneTo, size(a)) +parentindices(a::AbstractArray) = map(oneto, size(a)) ## Aliasing detection dataids(A::SubArray) = (dataids(A.parent)..., _splatmap(dataids, A.indices)...) @@ -107,7 +107,7 @@ function unaliascopy(V::SubArray{T,N,A,I,LD}) where {T,N,A<:Array,I<:Tuple{Varar end # Transform indices to be "dense" _trimmedindex(i::Real) = oftype(i, 1) -_trimmedindex(i::AbstractUnitRange) = oftype(i, OneTo(length(i))) +_trimmedindex(i::AbstractUnitRange) = oftype(i, oneto(length(i))) _trimmedindex(i::AbstractArray) = oftype(i, reshape(eachindex(IndexLinear(), i), axes(i))) ## SubArray creation diff --git a/test/testhelpers/InfiniteArrays.jl b/test/testhelpers/InfiniteArrays.jl index c4d1d7e93f8ee..bc6de1afc5503 100644 --- a/test/testhelpers/InfiniteArrays.jl +++ b/test/testhelpers/InfiniteArrays.jl @@ -46,5 +46,6 @@ Base.first(r::OneToInf{T}) where {T} = oneunit(T) Base.length(r::OneToInf{T}) where {T} = Infinity() Base.last(r::OneToInf{T}) where {T} = Infinity() Base.unitrange(r::OneToInf) = r +Base.oneto(::Infinity) = OneToInf() end \ No newline at end of file From 9df3e87d32558e3295c0d2f5ec2a395b02acc9cc Mon Sep 17 00:00:00 2001 From: Sheehan Olver Date: Wed, 16 Dec 2020 10:34:37 +0000 Subject: [PATCH 09/10] Update arrayshow.jl --- base/arrayshow.jl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/base/arrayshow.jl b/base/arrayshow.jl index 7b005d8104b59..ee99e407d3977 100644 --- a/base/arrayshow.jl +++ b/base/arrayshow.jl @@ -166,6 +166,10 @@ function print_matrix(io::IO, @nospecialize(X::AbstractVecOrMat), vdots::AbstractString = "\u22ee", ddots::AbstractString = " \u22f1 ", hmod::Integer = 5, vmod::Integer = 5) + _print_matrix(io, X, pre, sep, post, hdots, vdots, ddots, hmod, vmod, unitrange(axes(X,1)), unitrange(axes(X,2))) +end + +function _print_matrix(io, @nospecialize(X::AbstractVecOrMat), pre, sep, post, hdots, vdots, ddots, hmod, vmod, rowsA, colsA) hmod, vmod = Int(hmod)::Int, Int(vmod)::Int if !(get(io, :limit, false)::Bool) screenheight = screenwidth = typemax(Int) @@ -178,7 +182,6 @@ function print_matrix(io::IO, @nospecialize(X::AbstractVecOrMat), postsp = "" @assert textwidth(hdots) == textwidth(ddots) sepsize = length(sep)::Int - rowsA, colsA = unitrange(axes(X,1)), unitrange(axes(X,2)) m, n = length(rowsA), length(colsA) # To figure out alignments, only need to look at as many rows as could # fit down screen. If screen has at least as many rows as A, look at A. From 69ba1d7c036f6d594efc3e4ac621911a0f19bf0d Mon Sep 17 00:00:00 2001 From: Sheehan Olver Date: Mon, 28 Dec 2020 11:36:06 +0000 Subject: [PATCH 10/10] Update arrayshow.jl --- base/arrayshow.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/base/arrayshow.jl b/base/arrayshow.jl index ee99e407d3977..37adaf13f669e 100644 --- a/base/arrayshow.jl +++ b/base/arrayshow.jl @@ -166,7 +166,8 @@ function print_matrix(io::IO, @nospecialize(X::AbstractVecOrMat), vdots::AbstractString = "\u22ee", ddots::AbstractString = " \u22f1 ", hmod::Integer = 5, vmod::Integer = 5) - _print_matrix(io, X, pre, sep, post, hdots, vdots, ddots, hmod, vmod, unitrange(axes(X,1)), unitrange(axes(X,2))) + # use invokelatest to avoid backtracing in type invalidation, ref #37741 + invokelatest(_print_matrix, io, X, pre, sep, post, hdots, vdots, ddots, hmod, vmod, unitrange(axes(X,1)), unitrange(axes(X,2))) end function _print_matrix(io, @nospecialize(X::AbstractVecOrMat), pre, sep, post, hdots, vdots, ddots, hmod, vmod, rowsA, colsA)