From 49f6f7c7938c67f2285cb84ce43e09466160046c Mon Sep 17 00:00:00 2001 From: Jeff Bezanson Date: Mon, 5 Mar 2018 17:31:29 -0500 Subject: [PATCH] narrow array conversions. fixes #26294, fixes #26178. Not all array types can convert from any AbstractArray via a 1-argument constructor call. --- base/abstractarray.jl | 1 - base/array.jl | 7 +++++-- base/bitarray.jl | 3 +++ base/range.jl | 3 +++ stdlib/LinearAlgebra/test/diagonal.jl | 2 ++ 5 files changed, 13 insertions(+), 3 deletions(-) diff --git a/base/abstractarray.jl b/base/abstractarray.jl index 5721ec77bfe49..665f5c966147f 100644 --- a/base/abstractarray.jl +++ b/base/abstractarray.jl @@ -12,7 +12,6 @@ Supertype for `N`-dimensional arrays (or array-like types) with elements of type AbstractArray convert(::Type{T}, a::T) where {T<:AbstractArray} = a -convert(::Type{T}, a::AbstractArray) where {T<:AbstractArray} = T(a) if nameof(@__MODULE__) === :Base # avoid method overwrite # catch undefined constructors before the deprecation kicks in diff --git a/base/array.jl b/base/array.jl index 16c23f862ecfb..26ecc9188cd1e 100644 --- a/base/array.jl +++ b/base/array.jl @@ -413,8 +413,11 @@ oneunit(x::AbstractMatrix{T}) where {T} = _one(oneunit(T), x) ## Conversions ## -# arises in similar(dest, Pair{Union{},Union{}}) where dest::Dict: -convert(::Type{Vector{Union{}}}, a::Vector{Union{}}) = a +convert(::Type{T}, a::T) where {T<:Array} = a +convert(::Type{T}, a::AbstractArray) where {T<:Array} = T(a) + +convert(::Type{AbstractArray{T}}, a::AbstractArray) where {T} = AbstractArray{T}(a) +convert(::Type{AbstractArray{T,N}}, a::AbstractArray{<:Any,N}) where {T,N} = AbstractArray{T,N}(a) promote_rule(a::Type{Array{T,n}}, b::Type{Array{S,n}}) where {T,n,S} = el_same(promote_type(T,S), a, b) diff --git a/base/bitarray.jl b/base/bitarray.jl index 9e6d65b76f908..4cad8efb4b0f4 100644 --- a/base/bitarray.jl +++ b/base/bitarray.jl @@ -532,6 +532,9 @@ julia> BitArray(x+y == 3 for x = 1:2 for y = 1:3) """ BitArray(itr) = gen_bitarray(IteratorSize(itr), itr) +convert(::Type{BitArray}, a::AbstractArray) = BitArray(a) +convert(::Type{BitArray{N}}, a::AbstractArray{<:Any,N}) where {N} = BitArray{N}(a) + # generic constructor from an iterable without compile-time info # (we pass start(itr) explicitly to avoid a type-instability with filters) gen_bitarray(isz::IteratorSize, itr) = gen_bitarray_from_itr(itr, start(itr)) diff --git a/base/range.jl b/base/range.jl index cbe79060be684..af0026d32b44a 100644 --- a/base/range.jl +++ b/base/range.jl @@ -97,6 +97,9 @@ abstract type AbstractRange{T} <: AbstractArray{T,1} end RangeStepStyle(::Type{<:AbstractRange}) = RangeStepIrregular() RangeStepStyle(::Type{<:AbstractRange{<:Integer}}) = RangeStepRegular() +convert(::Type{T}, r::T) where {T<:AbstractRange} = r +convert(::Type{T}, r::AbstractRange) where {T<:AbstractRange} = T(r) + ## ordinal ranges abstract type OrdinalRange{T,S} <: AbstractRange{T} end diff --git a/stdlib/LinearAlgebra/test/diagonal.jl b/stdlib/LinearAlgebra/test/diagonal.jl index 2d3cb70a42f98..e8c3abb0d3749 100644 --- a/stdlib/LinearAlgebra/test/diagonal.jl +++ b/stdlib/LinearAlgebra/test/diagonal.jl @@ -27,6 +27,8 @@ srand(1) @test Diagonal{elty}(x)::Diagonal{elty,typeof(x)} == DM @test Diagonal{elty}(x).diag === x end + # issue #26178 + @test_throws MethodError convert(Diagonal, [1, 2, 3, 4]) end @testset "Basic properties" begin