diff --git a/README.md b/README.md index 3404cafa6..79df773e8 100644 --- a/README.md +++ b/README.md @@ -78,6 +78,8 @@ Currently, the `@compat` macro supports the following syntaxes: * `@compat A{T} = B{T}` or `@compat const A{T} = B{T}` to declare type alias with free parameters. [#20500]. Use `const A = B` for type alias without free parameters. +* `@compat Compat.IndexStyle(::Type{<:MyArray}) = IndexLinear()` and `@compat Compat.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. + ## Module Aliases * In 0.6, some 0.5 iterator functions have been moved to the `Base.Iterators` diff --git a/src/Compat.jl b/src/Compat.jl index 9a512ace4..d251542e7 100644 --- a/src/Compat.jl +++ b/src/Compat.jl @@ -147,6 +147,11 @@ function is_quote_symbol(ex::ANY, val::Symbol) return false end +is_index_style(ex::Expr) = ex == :(Compat.IndexStyle) || + (ex.head == :(.) && ex.args[1] == :Compat && ex.args[2] == Expr(:quote, :IndexStyle)) + +is_index_style(arg) = false + # rewrites accesses to IOContext dicts function rewrite_iocontext!(expr::Expr) args = expr.args @@ -463,6 +468,18 @@ function _compat(ex::Expr) return _compat(Expr(:comparison, ex.args[1], :.=, Expr(:call, Symbol(shead[1:end-1]), ex.args...))) end 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 return Expr(ex.head, map(_compat, ex.args)...) end function _compat(ex::Symbol) @@ -1384,6 +1401,15 @@ else using Base: Iterators end +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 + include("to-be-deprecated.jl") end # module Compat diff --git a/test/runtests.jl b/test/runtests.jl index 0f6015794..b98d8e846 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1745,4 +1745,22 @@ f20500_2() = A20500_2 @inferred f20500() @inferred f20500_2() +module CompatArray +using Compat +immutable CartesianArray{T,N} <: AbstractArray{T,N} + parent::Array{T,N} +end +immutable LinearArray{T,N} <: AbstractArray{T,N} + parent::Array{T,N} +end +@compat Compat.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 + include("to-be-deprecated.jl")