From cfd039b9478c6a22df0b161c4ba43ed4b691b0c5 Mon Sep 17 00:00:00 2001 From: Martin Holters Date: Mon, 24 Jul 2017 17:48:58 +0200 Subject: [PATCH 1/2] Widen unions less agressively during inference Use `typejoin` for unions growing too large instead of just returning `Any`. --- base/inference.jl | 9 ++++++--- test/inference.jl | 3 +++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/base/inference.jl b/base/inference.jl index b70485c24339f..a637eb47606ca 100644 --- a/base/inference.jl +++ b/base/inference.jl @@ -2810,9 +2810,12 @@ function tmerge(@nospecialize(typea), @nospecialize(typeb)) end end u = Union{typea, typeb} - if unionlen(u) > MAX_TYPEUNION_LEN || type_too_complex(u, MAX_TYPE_DEPTH) - # don't let type unions get too big - # TODO: something smarter, like a common supertype + if unionlen(u) > MAX_TYPEUNION_LEN + u = typejoin(typea, typeb) + end + if type_too_complex(u, MAX_TYPE_DEPTH) + # helps convergence speed (large types that are changing value become very slow to + # work with very quickly) return Any end return u diff --git a/test/inference.jl b/test/inference.jl index c04c6b8c6dcda..50faf55a48602 100644 --- a/test/inference.jl +++ b/test/inference.jl @@ -1291,3 +1291,6 @@ let T1 = Array{Float64}, T2 = Array{_1,2} where _1 rt = Base.return_types(g, (Union{Ref{Array{Float64}}, Ref{Array{Float32}}},))[1] @test rt >: Union{Type{Array{Float64}}, Type{Array{Float32}}} end + +f_23077(x) = (Int8(0), Int16(0), Int32(0), Int64(0))[x] +@test Base.return_types(f_23077, Tuple{Int})[1] <: Signed From 7a26e18115b5ad1994c6d1d309fef06b5fd02d4b Mon Sep 17 00:00:00 2001 From: Martin Holters Date: Thu, 27 Jul 2017 12:52:04 +0200 Subject: [PATCH 2/2] Remove special treatment of Tuples from tmerge --- base/inference.jl | 11 ----------- test/inference.jl | 2 ++ 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/base/inference.jl b/base/inference.jl index a637eb47606ca..713c7b1b810c8 100644 --- a/base/inference.jl +++ b/base/inference.jl @@ -2798,17 +2798,6 @@ function tmerge(@nospecialize(typea), @nospecialize(typeb)) if !(isa(typea,Type) || isa(typea,TypeVar)) || !(isa(typeb,Type) || isa(typeb,TypeVar)) return Any end - if (typea <: Tuple) && (typeb <: Tuple) - if isa(typea, DataType) && isa(typeb, DataType) && length(typea.parameters) == length(typeb.parameters) && !isvatuple(typea) && !isvatuple(typeb) - return typejoin(typea, typeb) - end - if isa(typea, Union) || isa(typeb, Union) || (isa(typea,DataType) && length(typea.parameters)>3) || - (isa(typeb,DataType) && length(typeb.parameters)>3) - # widen tuples faster (see #6704), but not too much, to make sure we can infer - # e.g. (t::Union{Tuple{Bool},Tuple{Bool,Int}})[1] - return Tuple - end - end u = Union{typea, typeb} if unionlen(u) > MAX_TYPEUNION_LEN u = typejoin(typea, typeb) diff --git a/test/inference.jl b/test/inference.jl index 50faf55a48602..aa43d03da8e2f 100644 --- a/test/inference.jl +++ b/test/inference.jl @@ -1294,3 +1294,5 @@ end f_23077(x) = (Int8(0), Int16(0), Int32(0), Int64(0))[x] @test Base.return_types(f_23077, Tuple{Int})[1] <: Signed +g_23077(x,y,z) = x ? y ? z ? (1,) : (1,1.0) : (1,1) : (1,1.0,1) +@test Base.return_types(g_23077, Tuple{Bool,Bool,Bool})[1] <: Tuple{Int,Vararg{Real}}