diff --git a/base/inference.jl b/base/inference.jl index 45c030af11efb..99507b270f197 100644 --- a/base/inference.jl +++ b/base/inference.jl @@ -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 @@ -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) @@ -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) @@ -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 @@ -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 diff --git a/base/linalg/uniformscaling.jl b/base/linalg/uniformscaling.jl index 92f1c81434d58..81a3ee1e6b29c 100644 --- a/base/linalg/uniformscaling.jl +++ b/base/linalg/uniformscaling.jl @@ -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} @@ -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 diff --git a/base/promotion.jl b/base/promotion.jl index 5c55b3d1e34d3..2972a7da99cce 100644 --- a/base/promotion.jl +++ b/base/promotion.jl @@ -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) @@ -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) => @@ -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)...) @@ -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) @@ -304,7 +307,7 @@ 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 @@ -312,7 +315,7 @@ 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)}) diff --git a/base/show.jl b/base/show.jl index cdf7450f5713f..5cfa8acdd032d 100644 --- a/base/show.jl +++ b/base/show.jl @@ -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 @@ -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 diff --git a/base/sparse/abstractsparse.jl b/base/sparse/abstractsparse.jl index 6de3403b5d6de..e17d3be97dbcb 100644 --- a/base/sparse/abstractsparse.jl +++ b/base/sparse/abstractsparse.jl @@ -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 diff --git a/base/sparse/sparsevector.jl b/base/sparse/sparsevector.jl index dd9e19d9bc729..d4f43de229667 100644 --- a/base/sparse/sparsevector.jl +++ b/base/sparse/sparsevector.jl @@ -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 @@ -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 diff --git a/test/inference.jl b/test/inference.jl index c03636fb26198..76917a3a4fef7 100644 --- a/test/inference.jl +++ b/test/inference.jl @@ -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}