Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

replace pure annotations in promotion with inline #21771

Merged
merged 4 commits into from
May 29, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 9 additions & 6 deletions base/inference.jl
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,8 @@ mutable struct InferenceState
if isa(atyp, DataType) && isdefined(atyp, :instance)
# replace singleton types with their equivalent Const object
atyp = Const(atyp.instance)
elseif isconstType(atyp)
atype = Const(atyp.parameters[1])
else
atyp = rewrap_unionall(atyp, linfo.specTypes)
end
Expand Down Expand Up @@ -999,7 +1001,7 @@ function apply_type_tfunc(headtypetype::ANY, args::ANY...)
ai = args[i]
if isType(ai)
aip1 = ai.parameters[1]
canconst &= isleaftype(aip1)
canconst &= !has_free_typevars(aip1)
push!(tparams, aip1)
elseif isa(ai, Const) && (isa(ai.val, Type) || isa(ai.val, TypeVar) || valid_tparam(ai.val))
push!(tparams, ai.val)
Expand Down Expand Up @@ -1782,6 +1784,10 @@ function abstract_call(f::ANY, fargs::Union{Tuple{},Vector{Any}}, argtypes::Vect
else
return Any
end
if !isa(body, Type) && !isa(body, TypeVar)
return Any
end
has_free_typevars(body) || return body
if isa(argtypes[2], Const)
tv = argtypes[2].val
elseif isa(argtypes[2], PartialTypeVar)
Expand All @@ -1792,9 +1798,6 @@ function abstract_call(f::ANY, fargs::Union{Tuple{},Vector{Any}}, argtypes::Vect
return Any
end
!isa(tv, TypeVar) && return Any
if !isa(body, Type) && !isa(body, TypeVar)
return Any
end
theunion = UnionAll(tv, body)
ret = canconst ? abstract_eval_constant(theunion) : Type{theunion}
return ret
Expand Down Expand Up @@ -1862,8 +1865,8 @@ function abstract_call(f::ANY, fargs::Union{Tuple{},Vector{Any}}, argtypes::Vect
t = pure_eval_call(f, argtypes, atype, sv)
t !== false && return t

if istopfunction(tm, f, :promote_type) || istopfunction(tm, f, :typejoin)
return Type
if istopfunction(tm, f, :typejoin) || f === return_type
return Type # don't try to infer these function edges directly -- it won't actually come up with anything useful
elseif length(argtypes) == 2 && istopfunction(tm, f, :typename)
return typename_static(argtypes[2])
end
Expand Down
4 changes: 2 additions & 2 deletions base/linalg/uniformscaling.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# This file is a part of Julia. License is MIT: https://julialang.org/license

import Base: copy, ctranspose, getindex, show, transpose, one, zero, inv,
@_pure_meta, hcat, vcat, hvcat
hcat, vcat, hvcat
import Base.LinAlg: SingularException

struct UniformScaling{T<:Number}
Expand Down Expand Up @@ -201,7 +201,7 @@ promote_to_arrays(n,k, ::Type{T}, A, B, C) where {T} =
(promote_to_arrays_(n[k], T, A), promote_to_arrays_(n[k+1], T, B), promote_to_arrays_(n[k+2], T, C))
promote_to_arrays(n,k, ::Type{T}, A, B, Cs...) where {T} =
(promote_to_arrays_(n[k], T, A), promote_to_arrays_(n[k+1], T, B), promote_to_arrays(n,k+2, T, Cs...)...)
promote_to_array_type(A::Tuple{Vararg{Union{AbstractVecOrMat,UniformScaling}}}) = (@_pure_meta; Matrix)
promote_to_array_type(A::Tuple{Vararg{Union{AbstractVecOrMat,UniformScaling}}}) = Matrix

for (f,dim,name) in ((:hcat,1,"rows"), (:vcat,2,"cols"))
@eval begin
Expand Down
41 changes: 22 additions & 19 deletions base/promotion.jl
Original file line number Diff line number Diff line change
Expand Up @@ -122,14 +122,14 @@ end

## promotion mechanism ##

promote_type() = (@_pure_meta; Bottom)
promote_type(T) = (@_pure_meta; T)
promote_type(T, S, U, V...) = (@_pure_meta; promote_type(T, promote_type(S, U, V...)))
promote_type() = Bottom
promote_type(T) = T
promote_type(T, S, U, V...) = (@_inline_meta; promote_type(T, promote_type(S, U, V...)))

promote_type(::Type{Bottom}, ::Type{Bottom}) = (@_pure_meta; Bottom)
promote_type(::Type{T}, ::Type{T}) where {T} = (@_pure_meta; T)
promote_type(::Type{T}, ::Type{Bottom}) where {T} = (@_pure_meta; T)
promote_type(::Type{Bottom}, ::Type{T}) where {T} = (@_pure_meta; T)
promote_type(::Type{Bottom}, ::Type{Bottom}) = Bottom
promote_type(::Type{T}, ::Type{T}) where {T} = T
promote_type(::Type{T}, ::Type{Bottom}) where {T} = T
promote_type(::Type{Bottom}, ::Type{T}) where {T} = T

"""
promote_type(type1, type2)
Expand All @@ -152,7 +152,7 @@ BigFloat
```
"""
function promote_type(::Type{T}, ::Type{S}) where {T,S}
@_pure_meta
@_inline_meta
# Try promote_rule in both orders. Typically only one is defined,
# and there is a fallback returning Bottom below, so the common case is
# promote_type(T, S) =>
Expand All @@ -161,26 +161,29 @@ function promote_type(::Type{T}, ::Type{S}) where {T,S}
promote_result(T, S, promote_rule(T,S), promote_rule(S,T))
end

promote_rule(T, S) = (@_pure_meta; Bottom)
promote_rule(::Type{<:Any}, ::Type{<:Any}) = Bottom

promote_result(t,s,T,S) = (@_pure_meta; promote_type(T,S))
promote_result(::Type{<:Any},::Type{<:Any},::Type{T},::Type{S}) where {T,S} = (@_inline_meta; promote_type(T,S))
# If no promote_rule is defined, both directions give Bottom. In that
# case use typejoin on the original types instead.
promote_result(::Type{T},::Type{S},::Type{Bottom},::Type{Bottom}) where {T,S} = (@_pure_meta; typejoin(T, S))
promote_result(::Type{T},::Type{S},::Type{Bottom},::Type{Bottom}) where {T,S} = (@_inline_meta; typejoin(T, S))

promote() = ()
promote(x) = (x,)
function promote(x::T, y::S) where {T,S}
@_inline_meta
(convert(promote_type(T,S),x), convert(promote_type(T,S),y))
end
promote_typeof(x) = (@_pure_meta; typeof(x))
promote_typeof(x, xs...) = (@_pure_meta; promote_type(typeof(x), promote_typeof(xs...)))
promote_typeof(x) = typeof(x)
promote_typeof(x, xs...) = (@_inline_meta; promote_type(typeof(x), promote_typeof(xs...)))
function promote(x, y, z)
@_inline_meta
(convert(promote_typeof(x,y,z), x),
convert(promote_typeof(x,y,z), y),
convert(promote_typeof(x,y,z), z))
end
function promote(x, y, zs...)
@_inline_meta
(convert(promote_typeof(x,y,zs...), x),
convert(promote_typeof(x,y,zs...), y),
convert(Tuple{Vararg{promote_typeof(x,y,zs...)}}, zs)...)
Expand All @@ -195,16 +198,16 @@ end
# happens, and +(promote(x,y)...) is called again, causing a stack
# overflow.
function promote_result(::Type{T},::Type{S},::Type{Bottom},::Type{Bottom}) where {T<:Number,S<:Number}
@_pure_meta
@_inline_meta
promote_to_supertype(T, S, typejoin(T,S))
end

# promote numeric types T and S to typejoin(T,S) if T<:S or S<:T
# for example this makes promote_type(Integer,Real) == Real without
# promoting arbitrary pairs of numeric types to Number.
promote_to_supertype(::Type{T}, ::Type{T}, ::Type{T}) where {T<:Number} = (@_pure_meta; T)
promote_to_supertype(::Type{T}, ::Type{S}, ::Type{T}) where {T<:Number,S<:Number} = (@_pure_meta; T)
promote_to_supertype(::Type{T}, ::Type{S}, ::Type{S}) where {T<:Number,S<:Number} = (@_pure_meta; S)
promote_to_supertype(::Type{T}, ::Type{T}, ::Type{T}) where {T<:Number} = (@_inline_meta; T)
promote_to_supertype(::Type{T}, ::Type{S}, ::Type{T}) where {T<:Number,S<:Number} = (@_inline_meta; T)
promote_to_supertype(::Type{T}, ::Type{S}, ::Type{S}) where {T<:Number,S<:Number} = (@_inline_meta; S)
promote_to_supertype(::Type{T}, ::Type{S}, ::Type) where {T<:Number,S<:Number} =
error("no promotion exists for ", T, " and ", S)

Expand Down Expand Up @@ -304,15 +307,15 @@ minmax(x::Real, y::Real) = minmax(promote(x, y)...)
# "Promotion" that takes a function into account and tries to preserve
# non-concrete types. These are meant to be used mainly by elementwise
# operations, so it is advised against overriding them
_default_type(T::Type) = (@_pure_meta; T)
_default_type(T::Type) = (@_inline_meta; T)

if isdefined(Core, :Inference)
const _return_type = Core.Inference.return_type
else
_return_type(f::ANY, t::ANY) = Any
end

promote_op(::Any...) = (@_pure_meta; Any)
promote_op(::Any...) = (@_inline_meta; Any)
function promote_op{S}(f, ::Type{S})
@_inline_meta
T = _return_type(f, Tuple{_default_type(S)})
Expand Down
4 changes: 2 additions & 2 deletions base/show.jl
Original file line number Diff line number Diff line change
Expand Up @@ -518,7 +518,7 @@ typeemphasize(io::IO) = get(io, :TYPEEMPHASIZE, false) === true

const indent_width = 4

function show_expr_type(io::IO, ty, emph)
function show_expr_type(io::IO, ty::ANY, emph::Bool)
if ty === Function
print(io, "::F")
elseif ty === Core.IntrinsicFunction
Expand Down Expand Up @@ -627,7 +627,7 @@ function show_unquoted(io::IO, ex::Slot, ::Int, ::Int)
if isa(slottypes, Array) && slotid <= length(slottypes::Array)
slottype = slottypes[slotid]
# The Slot in assignment can somehow have an Any type
if slottype <: typ
if isa(slottype, Type) && isa(typ, Type) && slottype <: typ
typ = slottype
end
end
Expand Down
2 changes: 1 addition & 1 deletion base/sparse/abstractsparse.jl
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@ issparse(S::LinAlg.UnitLowerTriangular{<:Any,<:AbstractSparseMatrix}) = true
issparse(S::UpperTriangular{<:Any,<:AbstractSparseMatrix}) = true
issparse(S::LinAlg.UnitUpperTriangular{<:Any,<:AbstractSparseMatrix}) = true

indtype(S::AbstractSparseArray{<:Any,Ti}) where {Ti} = (Base.@_pure_meta; Ti)
indtype(S::AbstractSparseArray{<:Any,Ti}) where {Ti} = Ti
6 changes: 3 additions & 3 deletions base/sparse/sparsevector.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

### Common definitions

import Base: scalarmax, scalarmin, sort, find, findnz, @_pure_meta
import Base: scalarmax, scalarmin, sort, find, findnz
import Base.LinAlg: promote_to_array_type, promote_to_arrays_

### The SparseVector
Expand Down Expand Up @@ -962,8 +962,8 @@ function hvcat(rows::Tuple{Vararg{Int}}, X::_SparseConcatGroup...)
end

# make sure UniformScaling objects are converted to sparse matrices for concatenation
promote_to_array_type(A::Tuple{Vararg{Union{_SparseConcatGroup,UniformScaling}}}) = (@_pure_meta; SparseMatrixCSC)
promote_to_array_type(A::Tuple{Vararg{Union{_DenseConcatGroup,UniformScaling}}}) = (@_pure_meta; Matrix)
promote_to_array_type(A::Tuple{Vararg{Union{_SparseConcatGroup,UniformScaling}}}) = SparseMatrixCSC
promote_to_array_type(A::Tuple{Vararg{Union{_DenseConcatGroup,UniformScaling}}}) = Matrix
promote_to_arrays_(n::Int, ::Type{SparseMatrixCSC}, J::UniformScaling) = sparse(J, n, n)

# Concatenations strictly involving un/annotated dense matrices/vectors should yield dense arrays
Expand Down
7 changes: 7 additions & 0 deletions test/inference.jl
Original file line number Diff line number Diff line change
Expand Up @@ -828,3 +828,10 @@ end
end
@test length(code_typed(test_20902, (), optimize = false)) == 1
@test length(code_typed(test_20902, (), optimize = false)) == 1

# normalization of arguments with constant Types as parameters
g21771(T) = T
f21771(::Val{U}) where {U} = Tuple{g21771(U)}
@test @inferred(f21771(Val{Int}())) === Tuple{Int}
@test @inferred(f21771(Val{Union{}}())) === Tuple{Union{}}
@test @inferred(f21771(Val{Integer}())) === Tuple{Integer}