diff --git a/base/compiler/inferencestate.jl b/base/compiler/inferencestate.jl index 0e0409f755a0b..8aff8910f457f 100644 --- a/base/compiler/inferencestate.jl +++ b/base/compiler/inferencestate.jl @@ -854,7 +854,11 @@ function should_infer_this_call(interp::AbstractInterpreter, sv::InferenceState) end function should_infer_for_effects(sv::InferenceState) effects = sv.ipo_effects - return is_terminates(effects) && is_effect_free(effects) + effects.consistent === ALWAYS_FALSE && return false + effects.effect_free === ALWAYS_FALSE && return false + effects.terminates || return false + effects.nonoverlayed || return false + return true end should_infer_this_call(::AbstractInterpreter, ::IRInterpretationState) = true diff --git a/test/compiler/effects.jl b/test/compiler/effects.jl index ee1d5dc569702..bd8465f1e2611 100644 --- a/test/compiler/effects.jl +++ b/test/compiler/effects.jl @@ -874,7 +874,7 @@ end |> Core.Compiler.is_foldable getfield(w, s) end |> Core.Compiler.is_foldable -# Flow-sensitive consistenct for _typevar +# Flow-sensitive consistent for _typevar @test Base.infer_effects() do return WrapperOneField == (WrapperOneField{T} where T) end |> Core.Compiler.is_foldable_nothrow @@ -982,3 +982,19 @@ isassigned_effects(s) = isassigned(Ref(s)) @test fully_eliminated(; retval=true) do isassigned_effects(:foo) end + +# inference on throw block should be disabled only when the effects are already known to be +# concrete-eval ineligible: +function optimize_throw_block_for_effects(x) + a = [x] + if x < 0 + throw(ArgumentError(lazy"negative number given: $x")) + end + return a +end +let effects = Base.infer_effects(optimize_throw_block_for_effects, (Int,)) + @test Core.Compiler.is_consistent_if_notreturned(effects) + @test Core.Compiler.is_effect_free(effects) + @test !Core.Compiler.is_nothrow(effects) + @test Core.Compiler.is_terminates(effects) +end