diff --git a/README.md b/README.md index 679ab15f4..cbea8303a 100644 --- a/README.md +++ b/README.md @@ -49,37 +49,11 @@ Please check the list below for the specific syntax you need. Currently, the `@compat` macro supports the following syntaxes: -* `@compat (a::B{T}){T}(c) = d` — the Julia 0.5-style call overload - -* `@compat(get(io, s, false))`, with `s` equal to `:limit`, `:compact` or `:multiline`, to detect the corresponding print settings (performs useful work only on Julia 0.5, defaults to `false` otherwise) - -* `@compat Nullable(value, hasvalue)` to handle the switch from the `Nullable` `:isnull` field to `:hasvalue` field ([#18510]) - -* `@compat x .= y` converts to an in-place assignment to `x` (via `broadcast!`) ([#17510]). - However, beware that `.=` in Julia 0.4 has the precedence of `==`, not of assignment `=`, so if the right-hand-side `y` - includes expressions with lower precedence than `==` you should enclose it in parentheses `x .= (y)` to ensure the - correct order of evaluation. Also, `x .+= y` converts to `x .= (x .+ y)`, and similarly for the other updating - assignment operators (`.*=` and so on). - -* `@compat Array{<:Real}`, `@compat Array{>:Int}`, and similar uses of `<:T` (resp. `>:T`) to define a set of "covariant" (resp. "contravariant") parameterized types ([#20414]). - In 0.5, this only works for non-nested usages (e.g. you can't define `Array{<:Array{<:Real}}`). - -* `@compat abstract type T end` and `@compat primitive type T 8 end` - to declare abstract and primitive types. [#20418] - This only works when `@compat` is applied directly on the declaration. - -* `@compat A{T} = B{T}` or `@compat const A{T} = B{T}` to declare type alias with free - parameters. [#20500]. Use `const A = B{T}` or `const A = B` for type alias without free parameters (i.e. no type parameter on the left hand side). - -* `@compat Base.IndexStyle(::Type{<:MyArray}) = IndexLinear()` and `@compat Base.IndexStyle(::Type{<:MyArray}) = IndexCartesian()` to define traits for abstract arrays, replacing the former `Base.linearindexing{T<:MyArray}(::Type{T}) = Base.LinearFast()` and `Base.linearindexing{T<:MyArray}(::Type{T}) = Base.LinearSlow()`, respectively. - -* `Compat.collect(A)` returns an `Array`, no matter what indices the array `A` has. [#21257] - * `@compat foo(::CartesianRange{N})` to replace the former `foo(::CartesianRange{CartesianIndex{N}})` ([#20974]). Note that `CartesianRange` now has two type parameters, so using them as fields in other `struct`s requires manual intervention. - + * Required keyword arguments ([#25830]). For example, `@compat foo(; x, y)` makes `x` and `y` required keyword arguments: when calling `foo`, an error is thrown if `x` or `y` is not explicitly provided. ## Module Aliases @@ -527,12 +501,10 @@ includes this fix. Find the minimum version from there. [#16986]: https://github.com/JuliaLang/julia/issues/16986 [#17302]: https://github.com/JuliaLang/julia/issues/17302 [#17323]: https://github.com/JuliaLang/julia/issues/17323 -[#17510]: https://github.com/JuliaLang/julia/issues/17510 [#17623]: https://github.com/JuliaLang/julia/issues/17623 [#18082]: https://github.com/JuliaLang/julia/issues/18082 [#18380]: https://github.com/JuliaLang/julia/issues/18380 [#18484]: https://github.com/JuliaLang/julia/issues/18484 -[#18510]: https://github.com/JuliaLang/julia/issues/18510 [#18629]: https://github.com/JuliaLang/julia/issues/18629 [#18727]: https://github.com/JuliaLang/julia/issues/18727 [#18977]: https://github.com/JuliaLang/julia/issues/18977 @@ -548,12 +520,8 @@ includes this fix. Find the minimum version from there. [#20164]: https://github.com/JuliaLang/julia/issues/20164 [#20321]: https://github.com/JuliaLang/julia/issues/20321 [#20407]: https://github.com/JuliaLang/julia/issues/20407 -[#20414]: https://github.com/JuliaLang/julia/issues/20414 -[#20418]: https://github.com/JuliaLang/julia/issues/20418 -[#20500]: https://github.com/JuliaLang/julia/issues/20500 [#20974]: https://github.com/JuliaLang/julia/issues/20974 [#21197]: https://github.com/JuliaLang/julia/issues/21197 -[#21257]: https://github.com/JuliaLang/julia/issues/21257 [#21346]: https://github.com/JuliaLang/julia/issues/21346 [#21709]: https://github.com/JuliaLang/julia/issues/21709 [#22064]: https://github.com/JuliaLang/julia/issues/22064 diff --git a/src/Compat.jl b/src/Compat.jl index c47ecc051..0eda7c595 100644 --- a/src/Compat.jl +++ b/src/Compat.jl @@ -169,13 +169,6 @@ end Base.Broadcast.broadcast{N}(f, t::NTuple{N}, ts::Vararg{NTuple{N}}) = map(f, t, ts...) end -# julia#18510 -if VERSION < v"0.6.0-dev.826" - _Nullable_field2(x) = !x -else - _Nullable_field2(x) = x -end - # julia#18484 @static if VERSION < v"0.6.0-dev.848" unsafe_get(x::Nullable) = x.value @@ -257,15 +250,6 @@ include("arraymacros.jl") # julia #18839 import Base.Iterators # TODO deprecate, remove -@static if VERSION < v"0.6.0-dev.2840" - export IndexStyle, IndexLinear, IndexCartesian - eval(Expr(:typealias, :IndexStyle, :(Base.LinearIndexing))) - eval(Expr(:typealias, :IndexLinear, :(Base.LinearFast))) - eval(Expr(:typealias, :IndexCartesian, :(Base.LinearSlow))) - IndexStyle{T}(::Type{T}) = Base.linearindexing(T) - IndexStyle(args...) = Base.linearindexing(args...) -end - if VERSION < v"0.6.0-dev.1653" for (fname, felt) in ((:zeros,:zero), (:ones,:one)) @eval begin @@ -342,20 +326,6 @@ else end end -# https://github.com/JuliaLang/julia/pull/21257 -@static if VERSION < v"0.6.0-pre.beta.28" - collect(A) = collect_indices(indices(A), A) - collect_indices(::Tuple{}, A) = copy!(Array{eltype(A)}(), A) - collect_indices(indsA::Tuple{Vararg{Base.OneTo}}, A) = - copy!(Array{eltype(A)}(map(length, indsA)), A) - function collect_indices(indsA, A) - B = Array{eltype(A)}(map(length, indsA)) - copy!(B, CartesianRange(indices(B)), A, CartesianRange(indsA)) - end -else - const collect = Base.collect -end - # https://github.com/JuliaLang/julia/pull/21197 if VERSION < v"0.7.0-DEV.257" # allow the elements of the Cmd to be accessed as an array or iterator diff --git a/src/compatmacro.jl b/src/compatmacro.jl index 28a57ba9b..09234c613 100644 --- a/src/compatmacro.jl +++ b/src/compatmacro.jl @@ -4,27 +4,6 @@ using Base.Meta export @compat -"""Get just the function part of a function declaration.""" -withincurly(ex) = isexpr(ex, :curly) ? ex.args[1] : ex - -is_index_style(ex::Expr) = ex == :(Compat.IndexStyle) || ex == :(Base.IndexStyle) || - (ex.head == :(.) && (ex.args[1] == :Compat || ex.args[1] == :Base) && - ex.args[2] == Expr(:quote, :IndexStyle)) - -is_index_style(arg) = false - -istopsymbol(ex, mod, sym) = ex in (sym, Expr(:(.), mod, Expr(:quote, sym))) - -if VERSION < v"0.6.0-dev.2782" - function new_style_typealias(ex::ANY) - isexpr(ex, :(=)) || return false - ex = ex::Expr - return length(ex.args) == 2 && isexpr(ex.args[1], :curly) - end -else - new_style_typealias(ex) = false -end - if !isdefined(Base, :UndefKeywordError) struct UndefKeywordError <: Exception kw @@ -42,43 +21,13 @@ symbol2kw(arg) = arg function _compat(ex::Expr) if ex.head === :call f = ex.args[1] - if VERSION < v"0.6.0-dev.826" && length(ex.args) == 3 && # julia#18510 - istopsymbol(withincurly(ex.args[1]), :Base, :Nullable) - ex = Expr(:call, f, ex.args[2], Expr(:call, :(Compat._Nullable_field2), ex.args[3])) - end if !isdefined(Base, :UndefKeywordError) && length(ex.args) > 1 && isexpr(ex.args[2], :parameters) params = ex.args[2] params.args = map(symbol2kw, params.args) end - elseif ex.head === :curly - f = ex.args[1] - if VERSION < v"0.6.0-dev.2575" #20414 - ex = Expr(:curly, map(a -> isexpr(a, :call, 2) && a.args[1] == :(<:) ? - :($TypeVar($(QuoteNode(gensym(:T))), $(a.args[2]), false)) : - isexpr(a, :call, 2) && a.args[1] == :(>:) ? - :($TypeVar($(QuoteNode(gensym(:T))), $(a.args[2]), $Any, false)) : a, - ex.args)...) - end elseif ex.head === :quote && isa(ex.args[1], Symbol) # Passthrough return ex - elseif new_style_typealias(ex) - ex.head = :typealias - elseif ex.head === :const && length(ex.args) == 1 && new_style_typealias(ex.args[1]) - ex = ex.args[1]::Expr - ex.head = :typealias - end - if VERSION < v"0.6.0-dev.2840" - if ex.head == :(=) && isa(ex.args[1], Expr) && ex.args[1].head == :call - a = ex.args[1].args[1] - if is_index_style(a) - ex.args[1].args[1] = :(Base.linearindexing) - elseif isa(a, Expr) && a.head == :curly - if is_index_style(a.args[1]) - ex.args[1].args[1].args[1] = :(Base.linearindexing) - end - end - end end if VERSION < v"0.7.0-DEV.880" if ex.head == :curly && ex.args[1] == :CartesianRange && length(ex.args) >= 2 @@ -98,51 +47,6 @@ end _compat(ex) = ex -function _get_typebody(ex::Expr) - args = ex.args - if ex.head !== :type || length(args) != 3 || args[1] !== true - throw(ArgumentError("Invalid usage of @compat: $ex")) - end - name = args[2] - if !isexpr(args[3], :block) - throw(ArgumentError("Invalid type declaration: $ex")) - end - body = (args[3]::Expr).args - filter!(body) do e - if isa(e, LineNumberNode) || isexpr(e, :line) - return false - end - return true - end - return name, body -end - -function _compat_primitive(typedecl) - name, body = _get_typebody(typedecl) - if length(body) != 1 - throw(ArgumentError("Invalid primitive type declaration: $typedecl")) - end - return Expr(:bitstype, body[1], name) -end - -function _compat_abstract(typedecl) - name, body = _get_typebody(typedecl) - if length(body) != 0 - throw(ArgumentError("Invalid abstract type declaration: $typedecl")) - end - return Expr(:abstract, name) -end - -macro compat(ex...) - if VERSION < v"0.6.0-dev.2746" && length(ex) == 2 && ex[1] === :primitive - return esc(_compat_primitive(ex[2])) - elseif length(ex) != 1 - throw(ArgumentError("@compat called with wrong number of arguments: $ex")) - elseif (VERSION < v"0.6.0-dev.2746" && isexpr(ex[1], :abstract) && - length(ex[1].args) == 1 && isexpr(ex[1].args[1], :type)) - # This can in principle be handled in nested case but we do not - # do that to be consistent with primitive types. - return esc(_compat_abstract(ex[1].args[1])) - end - esc(_compat(ex[1])) +macro compat(ex) + esc(_compat(ex)) end diff --git a/test/runtests.jl b/test/runtests.jl index 7680c91fb..b82eb6123 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -192,41 +192,12 @@ if VERSION < v"0.7.0-DEV.3017" UInt8, ] for T in types - # julia#18510, Nullable constructors - x = @compat Nullable(one(T), true) - @test isnull(x) === false - @test isa(x.value, T) - @test eltype(x) === T - - x = @compat Nullable{T}(one(T), true) - y = @compat Nullable{Any}(one(T), true) - @test isnull(x) === false - @test isnull(y) === false - @test isa(x.value, T) - @test eltype(x) === T - @test eltype(y) === Any - - x = @compat Nullable{T}(one(T), false) - y = @compat Nullable{Any}(one(T), false) - @test isnull(x) === true - @test isnull(y) === true - @test eltype(x) === T - @test eltype(y) === Any - - x = @compat Nullable(one(T), false) - @test isnull(x) === true - @test eltype(x) === T - - x = @compat Nullable{T}() - @test isnull(x) === true - @test eltype(x) === T - # julia#18484, generic isnull, unsafe_get a = one(T) - x = @compat Nullable(a, true) + x = Nullable(a, true) @test isequal(unsafe_get(x), a) - x = @compat Nullable{Array{T}}() + x = Nullable{Array{T}}() @test_throws UndefRefError unsafe_get(x) end end @@ -234,19 +205,6 @@ end @test xor(1,5) == 4 @test 1 ⊻ 5 == 4 -# julia#20414 -@compat let T = Array{<:Real}, f(x::AbstractVector{<:Real}) = 1 - @test isa([3,4],T) - @test !isa([3,4im],T) - @test f(1:3) == f([1,2]) == 1 -end -@compat let T = Array{>:Integer}, f(x::AbstractVector{>:Integer}) = 1 - @test isa(Integer[1,2],T) - @test !isa([3,4],T) - @test !isa([3.0,4.0],T) - @test f(Integer[1,2]) == f([1,'a',:sym]) == 1 -end - # supertype operator @test !(Int >: Integer) @test Integer >: Int @@ -263,16 +221,6 @@ let io = IOBuffer() @test String(take!(io)) == "bbb" end -# julia#17510 -let x = [1,2,3] - @compat x .= [3,4,5] - @test x == [3,4,5] - @compat x .= x .== 4 - @test x == [0,1,0] - @compat x .= 7 - @test x == [7,7,7] -end - let s = "Koala test: 🐨" @test transcode(UInt16, s) == UInt16[75,111,97,108,97,32,116,101,115,116,58,32,55357,56360] @test transcode(UInt32, s) == UInt32[75,111,97,108,97,32,116,101,115,116,58,32,128040] @@ -326,7 +274,7 @@ for x in (3.1, -17, 3//4, big(111.1), Inf) end # julia#20006 -@compat abstract type AbstractFoo20006 end +abstract type AbstractFoo20006 end eval(Expr( struct_sym, false, Expr(:(<:), :(ConcreteFoo20006{T<:Int}), :AbstractFoo20006), @@ -468,47 +416,6 @@ let x = [1,2,3] @test f(x) == [1,4,9] end -# PR #20418 -@compat abstract type Abstract20418{T} <: Ref{T} end -@test Compat.TypeUtils.isabstract(Abstract20418) -@compat primitive type Primitive20418{T} <: Ref{T} 16 end -@test !Compat.TypeUtils.isabstract(Primitive20418) -@test isbitstype(Primitive20418{Int}) -@test sizeof(Primitive20418{Int}) == 2 - -# PR #20500 -@compat A20500{T<:Integer} = Array{T,20500} -@compat const A20500_2{T<:Union{Int,Float32}} = Pair{T,T} -f20500() = A20500 -f20500_2() = A20500_2 -@inferred f20500() -@inferred f20500_2() - -module CompatArray - using Compat - const struct_sym = VERSION < v"0.7.0-DEV.1263" ? :type : :struct - eval(Expr( - struct_sym, false, - Expr(:(<:), :(CartesianArray{T,N}), :(AbstractArray{T,N})), - quote - parent::Array{T,N} - end)) - eval(Expr( - struct_sym, false, - Expr(:(<:), :(LinearArray{T,N}), :(AbstractArray{T,N})), - quote - parent::Array{T,N} - end)) - @compat Base.IndexStyle(::Type{<:LinearArray}) = IndexLinear() -end -@test IndexStyle(Array{Float32,2}) === IndexLinear() -@test IndexStyle(CompatArray.CartesianArray{Float32,2}) === IndexCartesian() -@test IndexStyle(CompatArray.LinearArray{Float32,2}) === IndexLinear() -let a = CompatArray.CartesianArray(rand(2,3)), b = CompatArray.LinearArray(rand(2,3)) - @test IndexStyle(a) === IndexCartesian() - @test IndexStyle(b) === IndexLinear() -end - if VERSION < v"0.6.0-dev.1653" for (A,val) in ((zeros(1:5, Float32, 3, 2), 0), (ones(1:5, Float32, 3, 2), 1), @@ -601,18 +508,6 @@ using Compat: StringVector @test length(StringVector(5)) == 5 @test String(fill!(StringVector(5), 0x61)) == "aaaaa" -# collect -if VERSION < v"0.7.0-" - # Note: This is disabled on 0.7, since the Compat.collect functionality is only - # applicable on 0.5, and OffsetArrays currently has some incompatibilities with - # 0.7. This can be reenabled later if needed. - using OffsetArrays - a = OffsetArray(1:3, -1:1) - b = Compat.collect(a) - @test indices(b) === (Base.OneTo(3),) - @test b == [1,2,3] -end - # PR 22064 module Test22064 using Compat