diff --git a/base/compiler/abstractinterpretation.jl b/base/compiler/abstractinterpretation.jl index a6e0463e34b3d..daf87525e0228 100644 --- a/base/compiler/abstractinterpretation.jl +++ b/base/compiler/abstractinterpretation.jl @@ -2667,18 +2667,18 @@ struct BestguessInfo{Interp<:AbstractInterpreter} end end -function widenreturn(@nospecialize(rt), info::BestguessInfo) +@noinfer function widenreturn(@nospecialize(rt), info::BestguessInfo) return widenreturn(typeinf_lattice(info.interp), rt, info) end -function widenreturn(๐•ƒแตข::AbstractLattice, @nospecialize(rt), info::BestguessInfo) +@noinfer function widenreturn(๐•ƒแตข::AbstractLattice, @nospecialize(rt), info::BestguessInfo) return widenreturn(widenlattice(๐•ƒแตข), rt, info) end -function widenreturn_noslotwrapper(๐•ƒแตข::AbstractLattice, @nospecialize(rt), info::BestguessInfo) +@noinfer function widenreturn_noslotwrapper(๐•ƒแตข::AbstractLattice, @nospecialize(rt), info::BestguessInfo) return widenreturn_noslotwrapper(widenlattice(๐•ƒแตข), rt, info) end -function widenreturn(๐•ƒแตข::MustAliasesLattice, @nospecialize(rt), info::BestguessInfo) +@noinfer function widenreturn(๐•ƒแตข::MustAliasesLattice, @nospecialize(rt), info::BestguessInfo) if isa(rt, MustAlias) if 1 โ‰ค rt.slot โ‰ค info.nargs rt = InterMustAlias(rt) @@ -2690,7 +2690,7 @@ function widenreturn(๐•ƒแตข::MustAliasesLattice, @nospecialize(rt), info::Bestg return widenreturn(widenlattice(๐•ƒแตข), rt, info) end -function widenreturn(๐•ƒแตข::ConditionalsLattice, @nospecialize(rt), info::BestguessInfo) +@noinfer function widenreturn(๐•ƒแตข::ConditionalsLattice, @nospecialize(rt), info::BestguessInfo) โŠ‘แตข = โŠ‘(๐•ƒแตข) if !(โŠ‘(ipo_lattice(info.interp), info.bestguess, Bool)) || info.bestguess === Bool # give up inter-procedural constraint back-propagation @@ -2727,7 +2727,7 @@ function widenreturn(๐•ƒแตข::ConditionalsLattice, @nospecialize(rt), info::Best isa(rt, InterConditional) && return rt return widenreturn(widenlattice(๐•ƒแตข), rt, info) end -function bool_rt_to_conditional(@nospecialize(rt), info::BestguessInfo) +@noinfer function bool_rt_to_conditional(@nospecialize(rt), info::BestguessInfo) bestguess = info.bestguess if isa(bestguess, InterConditional) # if the bestguess so far is already `Conditional`, try to convert @@ -2745,7 +2745,7 @@ function bool_rt_to_conditional(@nospecialize(rt), info::BestguessInfo) end return rt end -function bool_rt_to_conditional(@nospecialize(rt), slot_id::Int, info::BestguessInfo) +@noinfer function bool_rt_to_conditional(@nospecialize(rt), slot_id::Int, info::BestguessInfo) โŠ‘แตข = โŠ‘(typeinf_lattice(info.interp)) old = info.slottypes[slot_id] new = widenslotwrapper(info.changes[slot_id].typ) # avoid nested conditional @@ -2764,13 +2764,13 @@ function bool_rt_to_conditional(@nospecialize(rt), slot_id::Int, info::Bestguess return rt end -function widenreturn(๐•ƒแตข::PartialsLattice, @nospecialize(rt), info::BestguessInfo) +@noinfer function widenreturn(๐•ƒแตข::PartialsLattice, @nospecialize(rt), info::BestguessInfo) return widenreturn_partials(๐•ƒแตข, rt, info) end -function widenreturn_noslotwrapper(๐•ƒแตข::PartialsLattice, @nospecialize(rt), info::BestguessInfo) +@noinfer function widenreturn_noslotwrapper(๐•ƒแตข::PartialsLattice, @nospecialize(rt), info::BestguessInfo) return widenreturn_partials(๐•ƒแตข, rt, info) end -function widenreturn_partials(๐•ƒแตข::PartialsLattice, @nospecialize(rt), info::BestguessInfo) +@noinfer function widenreturn_partials(๐•ƒแตข::PartialsLattice, @nospecialize(rt), info::BestguessInfo) if isa(rt, PartialStruct) fields = copy(rt.fields) local anyrefine = false @@ -2793,21 +2793,21 @@ function widenreturn_partials(๐•ƒแตข::PartialsLattice, @nospecialize(rt), info: return widenreturn(widenlattice(๐•ƒแตข), rt, info) end -function widenreturn(::ConstsLattice, @nospecialize(rt), ::BestguessInfo) +@noinfer function widenreturn(::ConstsLattice, @nospecialize(rt), ::BestguessInfo) return widenreturn_consts(rt) end -function widenreturn_noslotwrapper(::ConstsLattice, @nospecialize(rt), ::BestguessInfo) +@noinfer function widenreturn_noslotwrapper(::ConstsLattice, @nospecialize(rt), ::BestguessInfo) return widenreturn_consts(rt) end -function widenreturn_consts(@nospecialize(rt)) +@noinfer function widenreturn_consts(@nospecialize(rt)) isa(rt, Const) && return rt return widenconst(rt) end -function widenreturn(::JLTypeLattice, @nospecialize(rt), ::BestguessInfo) +@noinfer function widenreturn(::JLTypeLattice, @nospecialize(rt), ::BestguessInfo) return widenconst(rt) end -function widenreturn_noslotwrapper(::JLTypeLattice, @nospecialize(rt), ::BestguessInfo) +@noinfer function widenreturn_noslotwrapper(::JLTypeLattice, @nospecialize(rt), ::BestguessInfo) return widenconst(rt) end diff --git a/base/compiler/abstractlattice.jl b/base/compiler/abstractlattice.jl index a84050816cb21..d9aa802074ede 100644 --- a/base/compiler/abstractlattice.jl +++ b/base/compiler/abstractlattice.jl @@ -161,7 +161,7 @@ If `๐•ƒ` is `JLTypeLattice`, this is equivalent to subtyping. """ function โŠ‘ end -โŠ‘(::JLTypeLattice, @nospecialize(a::Type), @nospecialize(b::Type)) = a <: b +@noinfer โŠ‘(::JLTypeLattice, @nospecialize(a::Type), @nospecialize(b::Type)) = a <: b """ โŠ(๐•ƒ::AbstractLattice, a, b) -> Bool @@ -169,7 +169,7 @@ function โŠ‘ end The strict partial order over the type inference lattice. This is defined as the irreflexive kernel of `โŠ‘`. """ -โŠ(๐•ƒ::AbstractLattice, @nospecialize(a), @nospecialize(b)) = โŠ‘(๐•ƒ, a, b) && !โŠ‘(๐•ƒ, b, a) +@noinfer โŠ(๐•ƒ::AbstractLattice, @nospecialize(a), @nospecialize(b)) = โŠ‘(๐•ƒ, a, b) && !โŠ‘(๐•ƒ, b, a) """ โ‹ค(๐•ƒ::AbstractLattice, a, b) -> Bool @@ -177,7 +177,7 @@ This is defined as the irreflexive kernel of `โŠ‘`. This order could be used as a slightly more efficient version of the strict order `โŠ`, where we can safely assume `a โŠ‘ b` holds. """ -โ‹ค(๐•ƒ::AbstractLattice, @nospecialize(a), @nospecialize(b)) = !โŠ‘(๐•ƒ, b, a) +@noinfer โ‹ค(๐•ƒ::AbstractLattice, @nospecialize(a), @nospecialize(b)) = !โŠ‘(๐•ƒ, b, a) """ is_lattice_equal(๐•ƒ::AbstractLattice, a, b) -> Bool @@ -186,7 +186,7 @@ Check if two lattice elements are partial order equivalent. This is basically `a โŠ‘ b && b โŠ‘ a` in the lattice of `๐•ƒ` but (optionally) with extra performance optimizations. """ -function is_lattice_equal(๐•ƒ::AbstractLattice, @nospecialize(a), @nospecialize(b)) +@noinfer function is_lattice_equal(๐•ƒ::AbstractLattice, @nospecialize(a), @nospecialize(b)) a === b && return true return โŠ‘(๐•ƒ, a, b) && โŠ‘(๐•ƒ, b, a) end @@ -197,14 +197,14 @@ end Determines whether the given lattice element `t` of `๐•ƒ` has non-trivial extended lattice information that would not be available from the type itself. """ -has_nontrivial_extended_info(๐•ƒ::AbstractLattice, @nospecialize t) = +@noinfer has_nontrivial_extended_info(๐•ƒ::AbstractLattice, @nospecialize t) = has_nontrivial_extended_info(widenlattice(๐•ƒ), t) -function has_nontrivial_extended_info(๐•ƒ::PartialsLattice, @nospecialize t) +@noinfer function has_nontrivial_extended_info(๐•ƒ::PartialsLattice, @nospecialize t) isa(t, PartialStruct) && return true isa(t, PartialOpaque) && return true return has_nontrivial_extended_info(widenlattice(๐•ƒ), t) end -function has_nontrivial_extended_info(๐•ƒ::ConstsLattice, @nospecialize t) +@noinfer function has_nontrivial_extended_info(๐•ƒ::ConstsLattice, @nospecialize t) isa(t, PartialTypeVar) && return true if isa(t, Const) val = t.val @@ -212,7 +212,7 @@ function has_nontrivial_extended_info(๐•ƒ::ConstsLattice, @nospecialize t) end return has_nontrivial_extended_info(widenlattice(๐•ƒ), t) end -has_nontrivial_extended_info(::JLTypeLattice, @nospecialize(t)) = false +@noinfer has_nontrivial_extended_info(::JLTypeLattice, @nospecialize(t)) = false """ is_const_prop_profitable_arg(๐•ƒ::AbstractLattice, t) -> Bool @@ -220,9 +220,9 @@ has_nontrivial_extended_info(::JLTypeLattice, @nospecialize(t)) = false Determines whether the given lattice element `t` of `๐•ƒ` has new extended lattice information that should be forwarded along with constant propagation. """ -is_const_prop_profitable_arg(๐•ƒ::AbstractLattice, @nospecialize t) = +@noinfer is_const_prop_profitable_arg(๐•ƒ::AbstractLattice, @nospecialize t) = is_const_prop_profitable_arg(widenlattice(๐•ƒ), t) -function is_const_prop_profitable_arg(๐•ƒ::PartialsLattice, @nospecialize t) +@noinfer function is_const_prop_profitable_arg(๐•ƒ::PartialsLattice, @nospecialize t) if isa(t, PartialStruct) return true # might be a bit aggressive, may want to enable some check like follows: # for i = 1:length(t.fields) @@ -236,7 +236,7 @@ function is_const_prop_profitable_arg(๐•ƒ::PartialsLattice, @nospecialize t) isa(t, PartialOpaque) && return true return is_const_prop_profitable_arg(widenlattice(๐•ƒ), t) end -function is_const_prop_profitable_arg(๐•ƒ::ConstsLattice, @nospecialize t) +@noinfer function is_const_prop_profitable_arg(๐•ƒ::ConstsLattice, @nospecialize t) if isa(t, Const) # don't consider mutable values useful constants val = t.val @@ -245,24 +245,24 @@ function is_const_prop_profitable_arg(๐•ƒ::ConstsLattice, @nospecialize t) isa(t, PartialTypeVar) && return false # this isn't forwardable return is_const_prop_profitable_arg(widenlattice(๐•ƒ), t) end -is_const_prop_profitable_arg(::JLTypeLattice, @nospecialize t) = false +@noinfer is_const_prop_profitable_arg(::JLTypeLattice, @nospecialize t) = false -is_forwardable_argtype(๐•ƒ::AbstractLattice, @nospecialize(x)) = +@noinfer is_forwardable_argtype(๐•ƒ::AbstractLattice, @nospecialize(x)) = is_forwardable_argtype(widenlattice(๐•ƒ), x) -function is_forwardable_argtype(๐•ƒ::ConditionalsLattice, @nospecialize x) +@noinfer function is_forwardable_argtype(๐•ƒ::ConditionalsLattice, @nospecialize x) isa(x, Conditional) && return true return is_forwardable_argtype(widenlattice(๐•ƒ), x) end -function is_forwardable_argtype(๐•ƒ::PartialsLattice, @nospecialize x) +@noinfer function is_forwardable_argtype(๐•ƒ::PartialsLattice, @nospecialize x) isa(x, PartialStruct) && return true isa(x, PartialOpaque) && return true return is_forwardable_argtype(widenlattice(๐•ƒ), x) end -function is_forwardable_argtype(๐•ƒ::ConstsLattice, @nospecialize x) +@noinfer function is_forwardable_argtype(๐•ƒ::ConstsLattice, @nospecialize x) isa(x, Const) && return true return is_forwardable_argtype(widenlattice(๐•ƒ), x) end -function is_forwardable_argtype(::JLTypeLattice, @nospecialize x) +@noinfer function is_forwardable_argtype(::JLTypeLattice, @nospecialize x) return false end @@ -281,9 +281,9 @@ External lattice `๐•ƒแตข::ExternalLattice` may overload: """ function widenreturn end, function widenreturn_noslotwrapper end -is_valid_lattice(๐•ƒ::AbstractLattice, @nospecialize(elem)) = +@noinfer is_valid_lattice(๐•ƒ::AbstractLattice, @nospecialize(elem)) = is_valid_lattice_norec(๐•ƒ, elem) && is_valid_lattice(widenlattice(๐•ƒ), elem) -is_valid_lattice(๐•ƒ::JLTypeLattice, @nospecialize(elem)) = is_valid_lattice_norec(๐•ƒ, elem) +@noinfer is_valid_lattice(๐•ƒ::JLTypeLattice, @nospecialize(elem)) = is_valid_lattice_norec(๐•ƒ, elem) has_conditional(๐•ƒ::AbstractLattice) = has_conditional(widenlattice(๐•ƒ)) has_conditional(::AnyConditionalsLattice) = true @@ -306,12 +306,12 @@ has_extended_unionsplit(::JLTypeLattice) = false const fallback_lattice = InferenceLattice(BaseInferenceLattice.instance) const fallback_ipo_lattice = InferenceLattice(IPOResultLattice.instance) -โŠ‘(@nospecialize(a), @nospecialize(b)) = โŠ‘(fallback_lattice, a, b) -tmeet(@nospecialize(a), @nospecialize(b)) = tmeet(fallback_lattice, a, b) -tmerge(@nospecialize(a), @nospecialize(b)) = tmerge(fallback_lattice, a, b) -โŠ(@nospecialize(a), @nospecialize(b)) = โŠ(fallback_lattice, a, b) -โ‹ค(@nospecialize(a), @nospecialize(b)) = โ‹ค(fallback_lattice, a, b) -is_lattice_equal(@nospecialize(a), @nospecialize(b)) = is_lattice_equal(fallback_lattice, a, b) +@noinfer @nospecialize(a) โŠ‘ @nospecialize(b) = โŠ‘(fallback_lattice, a, b) +@noinfer @nospecialize(a) โŠ @nospecialize(b) = โŠ(fallback_lattice, a, b) +@noinfer @nospecialize(a) โ‹ค @nospecialize(b) = โ‹ค(fallback_lattice, a, b) +@noinfer tmeet(@nospecialize(a), @nospecialize(b)) = tmeet(fallback_lattice, a, b) +@noinfer tmerge(@nospecialize(a), @nospecialize(b)) = tmerge(fallback_lattice, a, b) +@noinfer is_lattice_equal(@nospecialize(a), @nospecialize(b)) = is_lattice_equal(fallback_lattice, a, b) # Widenlattice with argument widenlattice(::JLTypeLattice, @nospecialize(t)) = widenconst(t) diff --git a/base/compiler/typelattice.jl b/base/compiler/typelattice.jl index 700a6d333cbc4..7126ca95025bd 100644 --- a/base/compiler/typelattice.jl +++ b/base/compiler/typelattice.jl @@ -244,7 +244,7 @@ const CompilerTypes = Union{MaybeUndef, Const, Conditional, MustAlias, NotFound, # slot wrappers # ============= -function assert_nested_slotwrapper(@nospecialize t) +@noinfer function assert_nested_slotwrapper(@nospecialize t) @assert !(t isa Conditional) "found nested Conditional" @assert !(t isa InterConditional) "found nested InterConditional" @assert !(t isa MustAlias) "found nested MustAlias" @@ -252,7 +252,7 @@ function assert_nested_slotwrapper(@nospecialize t) return t end -function widenslotwrapper(@nospecialize typ) +@noinfer function widenslotwrapper(@nospecialize typ) if isa(typ, AnyConditional) return widenconditional(typ) elseif isa(typ, AnyMustAlias) @@ -261,7 +261,7 @@ function widenslotwrapper(@nospecialize typ) return typ end -function widenwrappedslotwrapper(@nospecialize typ) +@noinfer function widenwrappedslotwrapper(@nospecialize typ) if isa(typ, LimitedAccuracy) return LimitedAccuracy(widenslotwrapper(typ.typ), typ.causes) end @@ -271,7 +271,7 @@ end # Conditional # =========== -function widenconditional(@nospecialize typ) +@noinfer function widenconditional(@nospecialize typ) if isa(typ, AnyConditional) if typ.thentype === Union{} return Const(false) @@ -285,7 +285,7 @@ function widenconditional(@nospecialize typ) end return typ end -function widenwrappedconditional(@nospecialize typ) +@noinfer function widenwrappedconditional(@nospecialize typ) if isa(typ, LimitedAccuracy) return LimitedAccuracy(widenconditional(typ.typ), typ.causes) end @@ -294,7 +294,7 @@ end # `Conditional` and `InterConditional` are valid in opposite contexts # (i.e. local inference and inter-procedural call), as such they will never be compared -function issubconditional(lattice::AbstractLattice, a::C, b::C) where {C<:AnyConditional} +@noinfer function issubconditional(lattice::AbstractLattice, a::C, b::C) where {C<:AnyConditional} if is_same_conditionals(a, b) if โŠ‘(lattice, a.thentype, b.thentype) if โŠ‘(lattice, a.elsetype, b.elsetype) @@ -307,7 +307,7 @@ end is_same_conditionals(a::C, b::C) where C<:AnyConditional = a.slot == b.slot -is_lattice_bool(lattice::AbstractLattice, @nospecialize(typ)) = typ !== Bottom && โŠ‘(lattice, typ, Bool) +@noinfer is_lattice_bool(lattice::AbstractLattice, @nospecialize(typ)) = typ !== Bottom && โŠ‘(lattice, typ, Bool) maybe_extract_const_bool(c::Const) = (val = c.val; isa(val, Bool)) ? val : nothing function maybe_extract_const_bool(c::AnyConditional) @@ -315,12 +315,12 @@ function maybe_extract_const_bool(c::AnyConditional) (c.elsetype === Bottom && !(c.thentype === Bottom)) && return true nothing end -maybe_extract_const_bool(@nospecialize c) = nothing +@noinfer maybe_extract_const_bool(@nospecialize c) = nothing # MustAlias # ========= -function widenmustalias(@nospecialize typ) +@noinfer function widenmustalias(@nospecialize typ) if isa(typ, AnyMustAlias) return typ.fldtyp elseif isa(typ, LimitedAccuracy) @@ -329,13 +329,13 @@ function widenmustalias(@nospecialize typ) return typ end -function isalreadyconst(@nospecialize t) +@noinfer function isalreadyconst(@nospecialize t) isa(t, Const) && return true isa(t, DataType) && isdefined(t, :instance) && return true return isconstType(t) end -function maybe_const_fldidx(@nospecialize(objtyp), @nospecialize(fldval)) +@noinfer function maybe_const_fldidx(@nospecialize(objtyp), @nospecialize(fldval)) t = widenconst(objtyp) if isa(fldval, Int) fldidx = fldval @@ -352,7 +352,7 @@ function maybe_const_fldidx(@nospecialize(objtyp), @nospecialize(fldval)) return fldidx end -function form_mustalias_conditional(alias::MustAlias, @nospecialize(thentype), @nospecialize(elsetype)) +@noinfer function form_mustalias_conditional(alias::MustAlias, @nospecialize(thentype), @nospecialize(elsetype)) (; slot, vartyp, fldidx) = alias if isa(vartyp, PartialStruct) fields = vartyp.fields @@ -401,7 +401,7 @@ ignorelimited(typ::LimitedAccuracy) = typ.typ # lattice order # ============= -function โŠ‘(lattice::InferenceLattice, @nospecialize(a), @nospecialize(b)) +@noinfer function โŠ‘(lattice::InferenceLattice, @nospecialize(a), @nospecialize(b)) r = โŠ‘(widenlattice(lattice), ignorelimited(a), ignorelimited(b)) r || return false isa(b, LimitedAccuracy) || return true @@ -420,7 +420,7 @@ function โŠ‘(lattice::InferenceLattice, @nospecialize(a), @nospecialize(b)) return b.causes โŠ† a.causes end -function โŠ‘(lattice::OptimizerLattice, @nospecialize(a), @nospecialize(b)) +@noinfer function โŠ‘(lattice::OptimizerLattice, @nospecialize(a), @nospecialize(b)) if isa(a, MaybeUndef) isa(b, MaybeUndef) || return false a, b = a.typ, b.typ @@ -430,7 +430,7 @@ function โŠ‘(lattice::OptimizerLattice, @nospecialize(a), @nospecialize(b)) return โŠ‘(widenlattice(lattice), a, b) end -function โŠ‘(lattice::AnyConditionalsLattice, @nospecialize(a), @nospecialize(b)) +@noinfer function โŠ‘(lattice::AnyConditionalsLattice, @nospecialize(a), @nospecialize(b)) # Fast paths for common cases b === Any && return true a === Any && return false @@ -450,7 +450,7 @@ function โŠ‘(lattice::AnyConditionalsLattice, @nospecialize(a), @nospecialize(b) return โŠ‘(widenlattice(lattice), a, b) end -function โŠ‘(๐•ƒ::AnyMustAliasesLattice, @nospecialize(a), @nospecialize(b)) +@noinfer function โŠ‘(๐•ƒ::AnyMustAliasesLattice, @nospecialize(a), @nospecialize(b)) MustAliasT = isa(๐•ƒ, MustAliasesLattice) ? MustAlias : InterMustAlias if isa(a, MustAliasT) if isa(b, MustAliasT) @@ -463,7 +463,7 @@ function โŠ‘(๐•ƒ::AnyMustAliasesLattice, @nospecialize(a), @nospecialize(b)) return โŠ‘(widenlattice(๐•ƒ), a, b) end -function โŠ‘(lattice::PartialsLattice, @nospecialize(a), @nospecialize(b)) +@noinfer function โŠ‘(lattice::PartialsLattice, @nospecialize(a), @nospecialize(b)) if isa(a, PartialStruct) if isa(b, PartialStruct) if !(length(a.fields) == length(b.fields) && a.typ <: b.typ) @@ -526,7 +526,7 @@ function โŠ‘(lattice::PartialsLattice, @nospecialize(a), @nospecialize(b)) return โŠ‘(widenlattice(lattice), a, b) end -function โŠ‘(lattice::ConstsLattice, @nospecialize(a), @nospecialize(b)) +@noinfer function โŠ‘(lattice::ConstsLattice, @nospecialize(a), @nospecialize(b)) if isa(a, Const) if isa(b, Const) return a.val === b.val @@ -548,7 +548,7 @@ function โŠ‘(lattice::ConstsLattice, @nospecialize(a), @nospecialize(b)) return โŠ‘(widenlattice(lattice), a, b) end -function is_lattice_equal(lattice::InferenceLattice, @nospecialize(a), @nospecialize(b)) +@noinfer function is_lattice_equal(lattice::InferenceLattice, @nospecialize(a), @nospecialize(b)) if isa(a, LimitedAccuracy) isa(b, LimitedAccuracy) || return false a.causes == b.causes || return false @@ -560,7 +560,7 @@ function is_lattice_equal(lattice::InferenceLattice, @nospecialize(a), @nospecia return is_lattice_equal(widenlattice(lattice), a, b) end -function is_lattice_equal(lattice::OptimizerLattice, @nospecialize(a), @nospecialize(b)) +@noinfer function is_lattice_equal(lattice::OptimizerLattice, @nospecialize(a), @nospecialize(b)) if isa(a, MaybeUndef) || isa(b, MaybeUndef) # TODO: Unwrap these and recurse to is_lattice_equal return โŠ‘(lattice, a, b) && โŠ‘(lattice, b, a) @@ -568,7 +568,7 @@ function is_lattice_equal(lattice::OptimizerLattice, @nospecialize(a), @nospecia return is_lattice_equal(widenlattice(lattice), a, b) end -function is_lattice_equal(lattice::AnyConditionalsLattice, @nospecialize(a), @nospecialize(b)) +@noinfer function is_lattice_equal(lattice::AnyConditionalsLattice, @nospecialize(a), @nospecialize(b)) ConditionalT = isa(lattice, ConditionalsLattice) ? Conditional : InterConditional if isa(a, ConditionalT) || isa(b, ConditionalT) # TODO: Unwrap these and recurse to is_lattice_equal @@ -577,7 +577,7 @@ function is_lattice_equal(lattice::AnyConditionalsLattice, @nospecialize(a), @no return is_lattice_equal(widenlattice(lattice), a, b) end -function is_lattice_equal(lattice::PartialsLattice, @nospecialize(a), @nospecialize(b)) +@noinfer function is_lattice_equal(lattice::PartialsLattice, @nospecialize(a), @nospecialize(b)) if isa(a, PartialStruct) isa(b, PartialStruct) || return false length(a.fields) == length(b.fields) || return false @@ -600,7 +600,7 @@ function is_lattice_equal(lattice::PartialsLattice, @nospecialize(a), @nospecial return is_lattice_equal(widenlattice(lattice), a, b) end -function is_lattice_equal(lattice::ConstsLattice, @nospecialize(a), @nospecialize(b)) +@noinfer function is_lattice_equal(lattice::ConstsLattice, @nospecialize(a), @nospecialize(b)) a === b && return true if a isa Const if issingletontype(b) @@ -625,7 +625,7 @@ end # lattice operations # ================== -function tmeet(lattice::PartialsLattice, @nospecialize(v), @nospecialize(t::Type)) +@noinfer function tmeet(lattice::PartialsLattice, @nospecialize(v), @nospecialize(t::Type)) if isa(v, PartialStruct) has_free_typevars(t) && return v widev = widenconst(v) @@ -663,7 +663,7 @@ function tmeet(lattice::PartialsLattice, @nospecialize(v), @nospecialize(t::Type return tmeet(widenlattice(lattice), v, t) end -function tmeet(lattice::ConstsLattice, @nospecialize(v), @nospecialize(t::Type)) +@noinfer function tmeet(lattice::ConstsLattice, @nospecialize(v), @nospecialize(t::Type)) if isa(v, Const) if !has_free_typevars(t) && !isa(v.val, t) return Bottom @@ -673,7 +673,7 @@ function tmeet(lattice::ConstsLattice, @nospecialize(v), @nospecialize(t::Type)) tmeet(widenlattice(lattice), widenconst(v), t) end -function tmeet(lattice::ConditionalsLattice, @nospecialize(v), @nospecialize(t::Type)) +@noinfer function tmeet(lattice::ConditionalsLattice, @nospecialize(v), @nospecialize(t::Type)) if isa(v, Conditional) if !(Bool <: t) return Bottom @@ -683,33 +683,33 @@ function tmeet(lattice::ConditionalsLattice, @nospecialize(v), @nospecialize(t:: tmeet(widenlattice(lattice), v, t) end -function tmeet(๐•ƒ::MustAliasesLattice, @nospecialize(v), @nospecialize(t::Type)) +@noinfer function tmeet(๐•ƒ::MustAliasesLattice, @nospecialize(v), @nospecialize(t::Type)) if isa(v, MustAlias) v = widenmustalias(v) end return tmeet(widenlattice(๐•ƒ), v, t) end -function tmeet(lattice::InferenceLattice, @nospecialize(v), @nospecialize(t::Type)) +@noinfer function tmeet(lattice::InferenceLattice, @nospecialize(v), @nospecialize(t::Type)) # TODO: This can probably happen and should be handled @assert !isa(v, LimitedAccuracy) tmeet(widenlattice(lattice), v, t) end -function tmeet(lattice::InterConditionalsLattice, @nospecialize(v), @nospecialize(t::Type)) +@noinfer function tmeet(lattice::InterConditionalsLattice, @nospecialize(v), @nospecialize(t::Type)) # TODO: This can probably happen and should be handled @assert !isa(v, AnyConditional) tmeet(widenlattice(lattice), v, t) end -function tmeet(๐•ƒ::InterMustAliasesLattice, @nospecialize(v), @nospecialize(t::Type)) +@noinfer function tmeet(๐•ƒ::InterMustAliasesLattice, @nospecialize(v), @nospecialize(t::Type)) if isa(v, InterMustAlias) v = widenmustalias(v) end return tmeet(widenlattice(๐•ƒ), v, t) end -function tmeet(lattice::OptimizerLattice, @nospecialize(v), @nospecialize(t::Type)) +@noinfer function tmeet(lattice::OptimizerLattice, @nospecialize(v), @nospecialize(t::Type)) # TODO: This can probably happen and should be handled @assert !isa(v, MaybeUndef) tmeet(widenlattice(lattice), v, t) @@ -727,7 +727,7 @@ widenconst(m::MaybeUndef) = widenconst(m.typ) widenconst(::PartialTypeVar) = TypeVar widenconst(t::PartialStruct) = t.typ widenconst(t::PartialOpaque) = t.typ -widenconst(t::Type) = t +@noinfer widenconst(@nospecialize t::Type) = t widenconst(::TypeVar) = error("unhandled TypeVar") widenconst(::TypeofVararg) = error("unhandled Vararg") widenconst(::LimitedAccuracy) = error("unhandled LimitedAccuracy") @@ -743,7 +743,7 @@ function smerge(lattice::AbstractLattice, sa::Union{NotFound,VarState}, sb::Unio return VarState(tmerge(lattice, sa.typ, sb.typ), sa.undef | sb.undef) end -@inline schanged(lattice::AbstractLattice, @nospecialize(n), @nospecialize(o)) = +@noinfer @inline schanged(lattice::AbstractLattice, @nospecialize(n), @nospecialize(o)) = (n !== o) && (o === NOT_FOUND || (n !== NOT_FOUND && !(n.undef <= o.undef && โŠ‘(lattice, n.typ, o.typ)))) # remove any lattice elements that wrap the reassigned slot object from the vartable diff --git a/base/compiler/typelimits.jl b/base/compiler/typelimits.jl index b5bbcde63e699..b998816dda9da 100644 --- a/base/compiler/typelimits.jl +++ b/base/compiler/typelimits.jl @@ -303,7 +303,7 @@ end # A simplified type_more_complex query over the extended lattice # (assumes typeb โŠ‘ typea) -function issimplertype(๐•ƒ::AbstractLattice, @nospecialize(typea), @nospecialize(typeb)) +@noinfer function issimplertype(๐•ƒ::AbstractLattice, @nospecialize(typea), @nospecialize(typeb)) typea isa MaybeUndef && (typea = typea.typ) # n.b. does not appear in inference typeb isa MaybeUndef && (typeb = typeb.typ) # n.b. does not appear in inference @assert !isa(typea, LimitedAccuracy) && !isa(typeb, LimitedAccuracy) "LimitedAccuracy not supported by simplertype lattice" # n.b. the caller was supposed to handle these @@ -413,7 +413,7 @@ function merge_causes(causesa::IdSet{InferenceState}, causesb::IdSet{InferenceSt end end -@noinline function tmerge_limited(lattice::InferenceLattice, @nospecialize(typea), @nospecialize(typeb)) +@noinfer @noinline function tmerge_limited(lattice::InferenceLattice, @nospecialize(typea), @nospecialize(typeb)) typea === Union{} && return typeb typeb === Union{} && return typea @@ -464,7 +464,7 @@ end return LimitedAccuracy(tmerge(widenlattice(lattice), typea, typeb), causes) end -function tmerge(lattice::InferenceLattice, @nospecialize(typea), @nospecialize(typeb)) +@noinfer function tmerge(lattice::InferenceLattice, @nospecialize(typea), @nospecialize(typeb)) if isa(typea, LimitedAccuracy) || isa(typeb, LimitedAccuracy) return tmerge_limited(lattice, typea, typeb) end @@ -474,7 +474,7 @@ function tmerge(lattice::InferenceLattice, @nospecialize(typea), @nospecialize(t return tmerge(widenlattice(lattice), typea, typeb) end -function tmerge(lattice::ConditionalsLattice, @nospecialize(typea), @nospecialize(typeb)) +@noinfer function tmerge(lattice::ConditionalsLattice, @nospecialize(typea), @nospecialize(typeb)) # type-lattice for Conditional wrapper (NOTE never be merged with InterConditional) if isa(typea, Conditional) && isa(typeb, Const) if typeb.val === true @@ -509,7 +509,7 @@ function tmerge(lattice::ConditionalsLattice, @nospecialize(typea), @nospecializ return tmerge(widenlattice(lattice), typea, typeb) end -function tmerge(lattice::InterConditionalsLattice, @nospecialize(typea), @nospecialize(typeb)) +@noinfer function tmerge(lattice::InterConditionalsLattice, @nospecialize(typea), @nospecialize(typeb)) # type-lattice for InterConditional wrapper (NOTE never be merged with Conditional) if isa(typea, InterConditional) && isa(typeb, Const) if typeb.val === true @@ -544,7 +544,7 @@ function tmerge(lattice::InterConditionalsLattice, @nospecialize(typea), @nospec return tmerge(widenlattice(lattice), typea, typeb) end -function tmerge(๐•ƒ::AnyMustAliasesLattice, @nospecialize(typea), @nospecialize(typeb)) +@noinfer function tmerge(๐•ƒ::AnyMustAliasesLattice, @nospecialize(typea), @nospecialize(typeb)) typea = widenmustalias(typea) typeb = widenmustalias(typeb) return tmerge(widenlattice(๐•ƒ), typea, typeb) @@ -552,7 +552,7 @@ end # N.B. This can also be called with both typea::Const and typeb::Const to # to recover PartialStruct from `Const`s with overlapping fields. -function tmerge_partial_struct(lattice::PartialsLattice, @nospecialize(typea), @nospecialize(typeb)) +@noinfer function tmerge_partial_struct(lattice::PartialsLattice, @nospecialize(typea), @nospecialize(typeb)) aty = widenconst(typea) bty = widenconst(typeb) if aty === bty @@ -610,7 +610,7 @@ function tmerge_partial_struct(lattice::PartialsLattice, @nospecialize(typea), @ return nothing end -function tmerge(lattice::PartialsLattice, @nospecialize(typea), @nospecialize(typeb)) +@noinfer function tmerge(lattice::PartialsLattice, @nospecialize(typea), @nospecialize(typeb)) # type-lattice for Const and PartialStruct wrappers aps = isa(typea, PartialStruct) bps = isa(typeb, PartialStruct) @@ -653,8 +653,7 @@ function tmerge(lattice::PartialsLattice, @nospecialize(typea), @nospecialize(ty return tmerge(wl, typea, typeb) end - -function tmerge(lattice::ConstsLattice, @nospecialize(typea), @nospecialize(typeb)) +@noinfer function tmerge(lattice::ConstsLattice, @nospecialize(typea), @nospecialize(typeb)) acp = isa(typea, Const) || isa(typea, PartialTypeVar) bcp = isa(typeb, Const) || isa(typeb, PartialTypeVar) if acp && bcp @@ -666,7 +665,7 @@ function tmerge(lattice::ConstsLattice, @nospecialize(typea), @nospecialize(type return tmerge(wl, typea, typeb) end -function tmerge(::JLTypeLattice, @nospecialize(typea::Type), @nospecialize(typeb::Type)) +@noinfer function tmerge(::JLTypeLattice, @nospecialize(typea::Type), @nospecialize(typeb::Type)) # it's always ok to form a Union of two concrete types act = isconcretetype(typea) bct = isconcretetype(typeb) @@ -682,7 +681,7 @@ function tmerge(::JLTypeLattice, @nospecialize(typea::Type), @nospecialize(typeb return tmerge_types_slow(typea, typeb) end -@noinline function tmerge_types_slow(@nospecialize(typea::Type), @nospecialize(typeb::Type)) +@noinfer @noinline function tmerge_types_slow(@nospecialize(typea::Type), @nospecialize(typeb::Type)) # collect the list of types from past tmerge calls returning Union # and then reduce over that list types = Any[] diff --git a/base/compiler/utilities.jl b/base/compiler/utilities.jl index 0d81008125ddc..57d42f109851b 100644 --- a/base/compiler/utilities.jl +++ b/base/compiler/utilities.jl @@ -346,7 +346,7 @@ end # types # ######### -function singleton_type(@nospecialize(ft)) +@noinfer function singleton_type(@nospecialize(ft)) ft = widenslotwrapper(ft) if isa(ft, Const) return ft.val @@ -358,7 +358,7 @@ function singleton_type(@nospecialize(ft)) return nothing end -function maybe_singleton_const(@nospecialize(t)) +@noinfer function maybe_singleton_const(@nospecialize(t)) if isa(t, DataType) if issingletontype(t) return Const(t.instance)