diff --git a/base/compiler/abstractinterpretation.jl b/base/compiler/abstractinterpretation.jl index 04fa67fa5d304..2abed20886be7 100644 --- a/base/compiler/abstractinterpretation.jl +++ b/base/compiler/abstractinterpretation.jl @@ -97,7 +97,11 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f), const_result = abstract_call_method_with_const_args(interp, result, f, this_arginfo, match, sv) effects = result.edge_effects if const_result !== nothing - (; rt, effects, const_result) = const_result + const_rt = const_result.rt + if const_rt ⊑ rt + rt = const_rt + end + (; effects, const_result) = const_result end tristate_merge!(sv, effects) push!(const_results, const_result) @@ -136,7 +140,12 @@ function abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f), const_result = abstract_call_method_with_const_args(interp, result, f, this_arginfo, match, sv) effects = result.edge_effects if const_result !== nothing - this_rt = const_result.rt + this_const_rt = const_result.rt + # return type of const-prop' inference can be wider than that of non const-prop' inference + # e.g. in cases when there are cycles but cached result is still accurate + if this_const_rt ⊑ this_rt + this_rt = this_const_rt + end (; effects, const_result) = const_result end tristate_merge!(sv, effects) @@ -1485,7 +1494,11 @@ function abstract_invoke(interp::AbstractInterpreter, (; fargs, argtypes)::ArgIn # end const_result = abstract_call_method_with_const_args(interp, result, singleton_type(ft′), arginfo, match, sv) if const_result !== nothing - (;rt, const_result) = const_result + const_rt = const_result.rt + if const_rt ⊑ rt + rt = const_rt + end + const_result = const_result.const_result end return CallMeta(from_interprocedural!(rt, sv, arginfo, sig), InvokeCallInfo(match, const_result)) end @@ -1633,7 +1646,11 @@ function abstract_call_opaque_closure(interp::AbstractInterpreter, closure::Part const_result = abstract_call_method_with_const_args(interp, result, nothing, arginfo, match, sv) if const_result !== nothing - (;rt, const_result) = const_result + const_rt = const_result.rt + if const_rt ⊑ rt + rt = const_rt + end + const_result = const_result.const_result end end info = OpaqueClosureCallInfo(match, const_result)