diff --git a/base/compiler/abstractinterpretation.jl b/base/compiler/abstractinterpretation.jl index e012273a4b8a2..ff6ac7c99bfa5 100644 --- a/base/compiler/abstractinterpretation.jl +++ b/base/compiler/abstractinterpretation.jl @@ -904,9 +904,28 @@ function abstract_eval(@nospecialize(e), vtypes::VarTable, sv::InferenceState) t = abstract_eval_call(e.args, argtypes, vtypes, sv) elseif e.head === :new t = instanceof_tfunc(abstract_eval(e.args[1], vtypes, sv))[1] - for i = 2:length(e.args) - if abstract_eval(e.args[i], vtypes, sv) === Bottom - rt = Bottom + if isbitstype(t) + args = Vector{Any}(undef, length(e.args)-1) + isconst = true + for i = 2:length(e.args) + at = abstract_eval(e.args[i], vtypes, sv) + if at === Bottom + t = Bottom + isconst = false + break + elseif at isa Const + if !(at.val isa fieldtype(t, i - 1)) + t = Bottom + isconst = false + break + end + args[i-1] = at.val + else + isconst = false + end + end + if isconst + t = Const(ccall(:jl_new_structv, Any, (Any, Ptr{Cvoid}, UInt32), t, args, length(args))) end end elseif e.head === :& diff --git a/test/compiler/compiler.jl b/test/compiler/compiler.jl index b10066956a903..35bf123e1597b 100644 --- a/test/compiler/compiler.jl +++ b/test/compiler/compiler.jl @@ -932,6 +932,13 @@ f21771(::Val{U}) where {U} = Tuple{g21771(U)} @test @inferred(f21771(Val{Union{}}())) === Tuple{Union{}} @test @inferred(f21771(Val{Integer}())) === Tuple{Integer} +# PR #28284, check that constants propagate through calls to new +struct t28284 + x::Int +end +f28284() = Val(t28284(1)) +@inferred f28284() + # missing method should be inferred as Union{}, ref https://github.com/JuliaLang/julia/issues/20033#issuecomment-282228948 @test Base.return_types(f -> f(1), (typeof((x::String) -> x),)) == Any[Union{}]