Skip to content

Commit 7e44cc0

Browse files
committed
deprecate convert-to-construct fallback
1 parent f965a87 commit 7e44cc0

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+414
-405
lines changed

NEWS.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ Language changes
4141
* The syntax for parametric methods, `function f{T}(x::T)`, has been
4242
changed to `function f(x::T) where {T}` ([#11310]).
4343

44+
* The fallback constructor that calls `convert` is deprecated. Instead, new types should
45+
prefer to define constructors, and add `convert` methods that call those constructors
46+
only as necessary ([#15120]).
47+
4448
* The syntax `1.+2` is deprecated, since it is ambiguous: it could mean either
4549
`1 .+ 2` (the current meaning) or `1. + 2` ([#19089]).
4650

@@ -1721,4 +1725,4 @@ Command-line option changes
17211725
[#24413]: https://github.com/JuliaLang/julia/issues/24413
17221726
[#24653]: https://github.com/JuliaLang/julia/issues/24653
17231727
[#24869]: https://github.com/JuliaLang/julia/issues/24869
1724-
[#25021]: https://github.com/JuliaLang/julia/issues/25021
1728+
[#25021]: https://github.com/JuliaLang/julia/issues/25021

base/abstractarray.jl

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,17 @@ Supertype for `N`-dimensional arrays (or array-like types) with elements of type
1111
"""
1212
AbstractArray
1313

14+
convert(::Type{T}, a::T) where {T<:AbstractArray} = a
15+
convert(::Type{T}, a::AbstractArray) where {T<:AbstractArray} = T(a)
16+
17+
if module_name(@__MODULE__) === :Base # avoid method overwrite
18+
# catch undefined constructors before the deprecation kicks in
19+
# TODO: remove when deprecation is removed
20+
function (::Type{T})(arg) where {T<:AbstractArray}
21+
throw(MethodError(T, (arg,)))
22+
end
23+
end
24+
1425
"""
1526
size(A::AbstractArray, [dim...])
1627
@@ -856,14 +867,6 @@ isempty(a::AbstractArray) = (_length(a) == 0)
856867
# keys with an IndexStyle
857868
keys(s::IndexStyle, A::AbstractArray, B::AbstractArray...) = eachindex(s, A, B...)
858869

859-
## Conversions ##
860-
861-
convert(::Type{AbstractArray{T,N}}, A::AbstractArray{T,N}) where {T,N } = A
862-
convert(::Type{AbstractArray{T,N}}, A::AbstractArray{S,N}) where {T,S,N} = copy!(similar(A,T), A)
863-
convert(::Type{AbstractArray{T}}, A::AbstractArray{S,N}) where {T,S,N} = convert(AbstractArray{T,N}, A)
864-
865-
convert(::Type{Array}, A::AbstractArray{T,N}) where {T,N} = convert(Array{T,N}, A)
866-
867870
"""
868871
of_indices(x, y)
869872

base/array.jl

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -396,21 +396,14 @@ oneunit(x::AbstractMatrix{T}) where {T} = _one(oneunit(T), x)
396396
# arises in similar(dest, Pair{Union{},Union{}}) where dest::Dict:
397397
convert(::Type{Vector{Union{}}}, a::Vector{Union{}}) = a
398398

399-
convert(::Type{Vector}, x::AbstractVector{T}) where {T} = convert(Vector{T}, x)
400-
convert(::Type{Matrix}, x::AbstractMatrix{T}) where {T} = convert(Matrix{T}, x)
401-
402-
convert(::Type{Array{T}}, x::Array{T,n}) where {T,n} = x
403-
convert(::Type{Array{T,n}}, x::Array{T,n}) where {T,n} = x
404-
405-
convert(::Type{Array{T}}, x::AbstractArray{S,n}) where {T,n,S} = convert(Array{T,n}, x)
406-
convert(::Type{Array{T,n}}, x::AbstractArray{S,n}) where {T,n,S} = copy!(Array{T,n}(uninitialized, size(x)), x)
407-
408399
promote_rule(a::Type{Array{T,n}}, b::Type{Array{S,n}}) where {T,n,S} = el_same(promote_type(T,S), a, b)
409400

410-
# constructors should make copies
401+
## Constructors ##
411402

412403
if module_name(@__MODULE__) === :Base # avoid method overwrite
413-
(::Type{T})(x::T) where {T<:Array} = copy(x)
404+
# constructors should make copies
405+
Array{T,N}(x::AbstractArray{S,N}) where {T,N,S} = copy!(Array{T,N}(uninitialized, size(x)), x)
406+
AbstractArray{T,N}(A::AbstractArray{S,N}) where {T,N,S} = copy!(similar(A,T), A)
414407
end
415408

416409
## copying iterators to containers
@@ -498,14 +491,26 @@ end
498491
# gets a chance to see it, so that recursive calls to the caller
499492
# don't trigger the inference limiter
500493
if isdefined(Core, :Inference)
501-
macro default_eltype(itrt)
494+
macro default_eltype(itr)
495+
I = esc(itr)
502496
return quote
503-
Core.Inference.return_type(first, Tuple{$(esc(itrt))})
497+
if $I isa Generator && ($I).f isa Type
498+
($I).f
499+
else
500+
Core.Inference.return_type(first, Tuple{typeof($I)})
501+
end
504502
end
505503
end
506504
else
507-
macro default_eltype(itrt)
508-
return :(Any)
505+
macro default_eltype(itr)
506+
I = esc(itr)
507+
return quote
508+
if $I isa Generator && ($I).f isa Type
509+
($I).f
510+
else
511+
Any
512+
end
513+
end
509514
end
510515
end
511516

@@ -514,7 +519,7 @@ _array_for(::Type{T}, itr, ::HasShape) where {T} = similar(Array{T}, indices(itr
514519

515520
function collect(itr::Generator)
516521
isz = iteratorsize(itr.iter)
517-
et = @default_eltype(typeof(itr))
522+
et = @default_eltype(itr)
518523
if isa(isz, SizeUnknown)
519524
return grow_to!(Vector{et}(), itr)
520525
else
@@ -528,12 +533,12 @@ function collect(itr::Generator)
528533
end
529534

530535
_collect(c, itr, ::EltypeUnknown, isz::SizeUnknown) =
531-
grow_to!(_similar_for(c, @default_eltype(typeof(itr)), itr, isz), itr)
536+
grow_to!(_similar_for(c, @default_eltype(itr), itr, isz), itr)
532537

533538
function _collect(c, itr, ::EltypeUnknown, isz::Union{HasLength,HasShape})
534539
st = start(itr)
535540
if done(itr,st)
536-
return _similar_for(c, @default_eltype(typeof(itr)), itr, isz)
541+
return _similar_for(c, @default_eltype(itr), itr, isz)
537542
end
538543
v1, st = next(itr, st)
539544
collect_to_with_first!(_similar_for(c, typeof(v1), itr, isz), v1, itr, st)

base/bitarray.jl

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -463,21 +463,19 @@ function _bitreshape(B::BitArray, dims::NTuple{N,Int}) where N
463463
return Br
464464
end
465465

466-
## Conversions ##
466+
## Constructors ##
467467

468-
convert(::Type{Array{T}}, B::BitArray{N}) where {T,N} = convert(Array{T,N}, B)
469-
convert(::Type{Array{T,N}}, B::BitArray{N}) where {T,N} = _convert(Array{T,N}, B) # see #15801
470-
function _convert(::Type{Array{T,N}}, B::BitArray{N}) where {T,N}
471-
A = Array{T}(uninitialized, size(B))
468+
function Array{T,N}(B::BitArray{N}) where {T,N}
469+
A = Array{T,N}(uninitialized, size(B))
472470
Bc = B.chunks
473471
@inbounds for i = 1:length(A)
474472
A[i] = unsafe_bitgetindex(Bc, i)
475473
end
476474
return A
477475
end
478476

479-
convert(::Type{BitArray}, A::AbstractArray{T,N}) where {T,N} = convert(BitArray{N}, A)
480-
function convert(::Type{BitArray{N}}, A::AbstractArray{T,N}) where N where T
477+
BitArray(A::AbstractArray{<:Any,N}) where {N} = BitArray{N}(A)
478+
function BitArray{N}(A::AbstractArray{T,N}) where N where T
481479
B = BitArray(uninitialized, size(A))
482480
Bc = B.chunks
483481
l = length(B)
@@ -502,7 +500,7 @@ function convert(::Type{BitArray{N}}, A::AbstractArray{T,N}) where N where T
502500
return B
503501
end
504502

505-
function convert(::Type{BitArray{N}}, A::Array{Bool,N}) where N
503+
function BitArray{N}(A::Array{Bool,N}) where N
506504
B = BitArray(uninitialized, size(A))
507505
Bc = B.chunks
508506
l = length(B)
@@ -511,16 +509,9 @@ function convert(::Type{BitArray{N}}, A::Array{Bool,N}) where N
511509
return B
512510
end
513511

514-
convert(::Type{BitArray{N}}, B::BitArray{N}) where {N} = B
515-
convert(::Type{AbstractArray{T,N}}, B::BitArray{N}) where {T,N} = convert(Array{T,N}, B)
516-
517512
reinterpret(::Type{Bool}, B::BitArray, dims::NTuple{N,Int}) where {N} = reinterpret(B, dims)
518513
reinterpret(B::BitArray, dims::NTuple{N,Int}) where {N} = reshape(B, dims)
519514

520-
## Constructors from generic iterables ##
521-
522-
BitArray(A::AbstractArray{<:Any,N}) where {N} = convert(BitArray{N}, A)
523-
524515
if module_name(@__MODULE__) === :Base # avoid method overwrite
525516
(::Type{T})(x::T) where {T<:BitArray} = copy(x)
526517
end

base/boot.jl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,13 @@ Array{T}(::Uninitialized, d::NTuple{N,Int}) where {T,N} = Array{T,N}(uninitializ
376376
Array{T,1}() where {T} = Array{T,1}(uninitialized, 0)
377377

378378

379+
(::Type{Array{T,N} where T})(x::AbstractArray{S,N}) where {S,N} = Array{S,N}(x)
380+
381+
Array(A::AbstractArray{T,N}) where {T,N} = Array{T,N}(A)
382+
Array{T}(A::AbstractArray{S,N}) where {T,N,S} = Array{T,N}(A)
383+
384+
AbstractArray{T}(A::AbstractArray{S,N}) where {T,S,N} = AbstractArray{T,N}(A)
385+
379386
# primitive Symbol constructors
380387
function Symbol(s::String)
381388
return ccall(:jl_symbol_n, Ref{Symbol}, (Ptr{UInt8}, Int),
@@ -667,6 +674,7 @@ UInt128(x::BuiltinInts) = toUInt128(x)::UInt128
667674
UInt32(x::Char) = bitcast(UInt32, x)
668675
Char(x::UInt32) = bitcast(Char, x)
669676
Char(x::Number) = Char(UInt32(x))
677+
Char(x::Char) = x
670678
(::Type{T})(x::Char) where {T<:Number} = T(UInt32(x))
671679

672680
(::Type{T})(x::T) where {T<:Number} = x

base/deprecated.jl

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1520,6 +1520,22 @@ export hex2num
15201520

15211521
@deprecate convert(dt::Type{<:Integer}, ip::IPAddr) dt(ip)
15221522

1523+
function (::Type{T})(arg) where {T}
1524+
if applicable(convert, T, arg)
1525+
sig = which(convert, (Type{T}, typeof(arg))).sig
1526+
if sig == (Tuple{typeof(convert),Type{S},Number} where S<:Number) ||
1527+
sig == (Tuple{typeof(convert),Type{S},AbstractArray} where S<:AbstractArray)
1528+
# matches a catch-all converter; will stack overflow
1529+
throw(MethodError(T, (arg,)))
1530+
end
1531+
# if `convert` call would not work, just let the method error happen
1532+
depwarn("Constructors no longer fall back to `convert`. A constructor `$T(::$(typeof(arg)))` should be defined instead.", :Type)
1533+
end
1534+
convert(T, arg)::T
1535+
end
1536+
# related items to remove in: abstractarray.jl, dates/periods.jl, inference.jl
1537+
# also remove all uses of is_default_method
1538+
15231539
# Issue #19923
15241540
@deprecate ror circshift
15251541
@deprecate ror! circshift!

base/dict.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,9 +157,9 @@ associative_with_eltype(DT_apply, kv, ::TP{K,V}) where {K,V} = DT_apply(K, V)(kv
157157
associative_with_eltype(DT_apply, kv::Generator, ::TP{K,V}) where {K,V} = DT_apply(K, V)(kv)
158158
associative_with_eltype(DT_apply, ::Type{Pair{K,V}}) where {K,V} = DT_apply(K, V)()
159159
associative_with_eltype(DT_apply, ::Type) = DT_apply(Any, Any)()
160-
associative_with_eltype(DT_apply::F, kv, t) where {F} = grow_to!(associative_with_eltype(DT_apply, @default_eltype(typeof(kv))), kv)
160+
associative_with_eltype(DT_apply::F, kv, t) where {F} = grow_to!(associative_with_eltype(DT_apply, @default_eltype(kv)), kv)
161161
function associative_with_eltype(DT_apply::F, kv::Generator, t) where F
162-
T = @default_eltype(typeof(kv))
162+
T = @default_eltype(kv)
163163
if T <: Union{Pair, Tuple{Any, Any}} && _isleaftype(T)
164164
return associative_with_eltype(DT_apply, kv, T)
165165
end

base/inference.jl

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1912,7 +1912,7 @@ function abstract_call_gf_by_type(@nospecialize(f), argtypes::Vector{Any}, @nosp
19121912
end
19131913
# many types have many matching constructors; try harder to infer simple type ctors
19141914
if !has_free_typevars(tname)
1915-
max_methods = max(max_methods, 15)
1915+
#max_methods = max(max_methods, 15)
19161916
end
19171917
end
19181918
min_valid = UInt[typemin(UInt)]
@@ -2088,7 +2088,13 @@ function abstract_call_method_with_const_args(argtypes::Vector{Any}, match::Simp
20882088
return result
20892089
end
20902090

2091+
const deprecated_sym = Symbol("deprecated.jl")
2092+
20912093
function abstract_call_method(method::Method, @nospecialize(sig), sparams::SimpleVector, sv::InferenceState)
2094+
# TODO: remove with 0.7 deprecations
2095+
if method.file === deprecated_sym && method.sig == (Tuple{Type{T},Any} where T)
2096+
return Any, false
2097+
end
20922098
topmost = nothing
20932099
# Limit argument type tuple growth of functions:
20942100
# look through the parents list to see if there's a call to the same method
@@ -2183,7 +2189,7 @@ function abstract_call_method(method::Method, @nospecialize(sig), sparams::Simpl
21832189
recomputed = ccall(:jl_type_intersection_with_env, Any, (Any, Any), sig, method.sig)::SimpleVector
21842190
sig = recomputed[1]
21852191
if !isa(unwrap_unionall(sig), DataType) # probably Union{}
2186-
return Any
2192+
return Any, false
21872193
end
21882194
sparams = recomputed[2]::SimpleVector
21892195
end

base/libgit2/types.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ struct GitHash <: AbstractGitHash
2020
GitHash(val::NTuple{OID_RAWSZ, UInt8}) = new(val)
2121
end
2222
GitHash() = GitHash(ntuple(i->zero(UInt8), OID_RAWSZ))
23+
GitHash(h::GitHash) = h
2324

2425
"""
2526
GitShortHash(hash::GitHash, len::Integer)

base/linalg/bidiag.jl

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ function Bidiagonal(A::AbstractMatrix, uplo::Symbol)
9393
Bidiagonal(diag(A, 0), diag(A, uplo == :U ? 1 : -1), uplo)
9494
end
9595

96+
Bidiagonal(A::Bidiagonal) = A
97+
9698
function getindex(A::Bidiagonal{T}, i::Integer, j::Integer) where T
9799
if !((1 <= i <= size(A,2)) && (1 <= j <= size(A,2)))
98100
throw(BoundsError(A,(i,j)))
@@ -131,7 +133,7 @@ function Base.replace_in_print_matrix(A::Bidiagonal,i::Integer,j::Integer,s::Abs
131133
end
132134

133135
#Converting from Bidiagonal to dense Matrix
134-
function convert(::Type{Matrix{T}}, A::Bidiagonal) where T
136+
function Matrix{T}(A::Bidiagonal) where T
135137
n = size(A, 1)
136138
B = zeros(T, n, n)
137139
for i = 1:n - 1
@@ -145,15 +147,14 @@ function convert(::Type{Matrix{T}}, A::Bidiagonal) where T
145147
B[n,n] = A.dv[n]
146148
return B
147149
end
148-
convert(::Type{Matrix}, A::Bidiagonal{T}) where {T} = convert(Matrix{T}, A)
149-
convert(::Type{Array}, A::Bidiagonal) = convert(Matrix, A)
150+
Matrix(A::Bidiagonal{T}) where {T} = Matrix{T}(A)
151+
Array(A::Bidiagonal) = Matrix(A)
150152
promote_rule(::Type{Matrix{T}}, ::Type{<:Bidiagonal{S}}) where {T,S} =
151153
@isdefined(T) && @isdefined(S) ? Matrix{promote_type(T,S)} : Matrix
152154
promote_rule(::Type{Matrix}, ::Type{<:Bidiagonal}) = Matrix
153155

154156
#Converting from Bidiagonal to Tridiagonal
155-
Tridiagonal(M::Bidiagonal{T}) where {T} = convert(Tridiagonal{T}, M)
156-
function convert(::Type{Tridiagonal{T}}, A::Bidiagonal) where T
157+
function Tridiagonal{T}(A::Bidiagonal) where T
157158
dv = convert(AbstractVector{T}, A.dv)
158159
ev = convert(AbstractVector{T}, A.ev)
159160
z = fill!(similar(ev), zero(T))
@@ -164,12 +165,12 @@ promote_rule(::Type{<:Tridiagonal{T}}, ::Type{<:Bidiagonal{S}}) where {T,S} =
164165
promote_rule(::Type{<:Tridiagonal}, ::Type{<:Bidiagonal}) = Tridiagonal
165166

166167
# No-op for trivial conversion Bidiagonal{T} -> Bidiagonal{T}
167-
convert(::Type{Bidiagonal{T}}, A::Bidiagonal{T}) where {T} = A
168+
Bidiagonal{T}(A::Bidiagonal{T}) where {T} = A
168169
# Convert Bidiagonal to Bidiagonal{T} by constructing a new instance with converted elements
169-
convert(::Type{Bidiagonal{T}}, A::Bidiagonal) where {T} =
170+
Bidiagonal{T}(A::Bidiagonal) where {T} =
170171
Bidiagonal(convert(AbstractVector{T}, A.dv), convert(AbstractVector{T}, A.ev), A.uplo)
171172
# When asked to convert Bidiagonal to AbstractMatrix{T}, preserve structure by converting to Bidiagonal{T} <: AbstractMatrix{T}
172-
convert(::Type{AbstractMatrix{T}}, A::Bidiagonal) where {T} = convert(Bidiagonal{T}, A)
173+
AbstractMatrix{T}(A::Bidiagonal) where {T} = convert(Bidiagonal{T}, A)
173174

174175
broadcast(::typeof(big), B::Bidiagonal) = Bidiagonal(big.(B.dv), big.(B.ev), B.uplo)
175176

0 commit comments

Comments
 (0)