diff --git a/base/array.jl b/base/array.jl index dfa514cea4981..e7b87cf9739ce 100644 --- a/base/array.jl +++ b/base/array.jl @@ -624,6 +624,20 @@ function _collect_indices(indsA, A) copyto!(B, CartesianIndices(axes(B)), A, CartesianIndices(indsA)) end +# NOTE: this function is not meant to be called, only inferred, for the +# purpose of bounding the types of values generated by an iterator. +function _iterator_upper_bound(itr) + x = iterate(itr) + while x !== nothing + val = getfield(x, 1) + if inferencebarrier(nothing) + return val + end + x = iterate(itr, getfield(x, 2)) + end + throw(nothing) +end + # define this as a macro so that the call to Core.Compiler # gets inlined into the caller before recursion detection # gets a chance to see it, so that recursive calls to the caller @@ -635,7 +649,7 @@ if isdefined(Core, :Compiler) if $I isa Generator && ($I).f isa Type ($I).f else - Core.Compiler.return_type(first, Tuple{typeof($I)}) + Core.Compiler.return_type(_iterator_upper_bound, Tuple{typeof($I)}) end end end diff --git a/test/dict.jl b/test/dict.jl index fd9199faf5589..5b1ac446e3215 100644 --- a/test/dict.jl +++ b/test/dict.jl @@ -159,6 +159,9 @@ end d = Dict(i==1 ? (1=>2) : (2.0=>3.0) for i=1:2) @test isa(d, Dict{Real,Real}) @test d == Dict{Real,Real}(2.0=>3.0, 1=>2) + + # issue #39117 + @test Dict(t[1]=>t[2] for t in zip((1,"2"), (2,"2"))) == Dict{Any,Any}(1=>2, "2"=>"2") end @testset "type of Dict constructed from varargs of Pairs" begin