From 109a43fd53953c5e28fc055f9ea46d3877356897 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Mon, 15 Aug 2016 22:51:55 -0400 Subject: [PATCH] fix "improved" correctness of fieldtype the getfield_tfunc was missing a test for whether the fields were all equivalent before concluding that the result type was exact fixes the fix #17953 fix #18037 (cherry picked from commit 06a8d891e71c12a7598b2fa818dcfc29437d5c0b) ref #18045 --- base/inference.jl | 9 +++++---- test/inference.jl | 15 +++++++++++++++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/base/inference.jl b/base/inference.jl index 869b30aa0f3e2..95471df20d788 100644 --- a/base/inference.jl +++ b/base/inference.jl @@ -478,7 +478,7 @@ function getfield_tfunc(s0::ANY, name) # in the current type system typ = limit_type_depth(R, 0, true, filter!(x->isa(x,TypeVar), Any[s.parameters...])) - return typ, isleaftype(s) && typeseq(typ, R) + return typ, isleaftype(s) && isa(R, Type) && typeof(R) === typeof(typ) && typeseq(R, typ) end end end @@ -501,14 +501,15 @@ function getfield_tfunc(s0::ANY, name) elseif length(s.types) == 1 && isempty(s.parameters) return s.types[1], true else - R = reduce(tmerge, Bottom, map(unwrapva,s.types)) #=Union{s.types...}=# + R = reduce(tmerge, Bottom, map(unwrapva, s.types)) #=Union{s.types...}=# + alleq = isa(R, Type) && typeof(R) === typeof(s.types[1]) && typeseq(R, s.types[1]) # do the same limiting as the known-symbol case to preserve type-monotonicity if isempty(s.parameters) - return R, typeseq(R, s.types[1]) + return R, alleq else typ = limit_type_depth(R, 0, true, filter!(x->isa(x,TypeVar), Any[s.parameters...])) - return typ, isleaftype(s) && typeseq(typ, R) + return typ, alleq && isleaftype(s) && typeof(R) === typeof(typ) && typeseq(R, typ) end end end diff --git a/test/inference.jl b/test/inference.jl index f1f4fbb9b1457..a324716b2511b 100644 --- a/test/inference.jl +++ b/test/inference.jl @@ -307,6 +307,21 @@ let T = Array{Tuple{Vararg{Float64,TypeVar(:dim)}},1}, end @test f16530a(:d) == Vector +let T1 = Tuple{Int, Float64}, + T2 = Tuple{Int, Float32}, + T = Tuple{T1, T2} + + global f18037 + f18037() = fieldtype(T, 1) + f18037(i) = fieldtype(T, i) + + @test f18037() === T1 + @test f18037(1) === T1 + @test f18037(2) === T2 + + @test Base.return_types(f18037, ()) == Any[Type{T1}] + @test Base.return_types(f18037, (Int,)) == Any[Type{TypeVar(:T, Tuple{Int, AbstractFloat})}] +end # issue #18015 type Triple18015