Skip to content

Commit

Permalink
inference: add more assertions for nested lattice elements (#45527)
Browse files Browse the repository at this point in the history
This allows us to make sure we don't create any lattice element that
wraps slot wrappers (currently `Conditional` and `InterConditional`),
that are hard to be invalidated properly.
  • Loading branch information
aviatesk committed Jun 1, 2022
1 parent cbbcf07 commit d84f890
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 8 deletions.
3 changes: 2 additions & 1 deletion base/boot.jl
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,8 @@ eval(Core, quote
relocatability)
end
Const(@nospecialize(v)) = $(Expr(:new, :Const, :v))
PartialStruct(typ::DataType, fields::Array{Any, 1}) = $(Expr(:new, :PartialStruct, :typ, :fields))
# NOTE the main constructor is defined within `Core.Compiler`
_PartialStruct(typ::DataType, fields::Array{Any, 1}) = $(Expr(:new, :PartialStruct, :typ, :fields))
PartialOpaque(@nospecialize(typ), @nospecialize(env), parent::MethodInstance, source::Method) = $(Expr(:new, :PartialOpaque, :typ, :env, :parent, :source))
MethodMatch(@nospecialize(spec_types), sparams::SimpleVector, method::Method, fully_covers::Bool) = $(Expr(:new, :MethodMatch, :spec_types, :sparams, :method, :fully_covers))
end)
Expand Down
4 changes: 2 additions & 2 deletions base/compiler/abstractinterpretation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,7 @@ function conditional_argtype(@nospecialize(rt), @nospecialize(sig), argtypes::Ve
if isa(rt, InterConditional) && rt.slot == i
return rt
else
thentype = elsetype = tmeet(argtypes[i], fieldtype(sig, i))
thentype = elsetype = tmeet(widenconditional(argtypes[i]), fieldtype(sig, i))
condval = maybe_extract_const_bool(rt)
condval === true && (elsetype = Bottom)
condval === false && (thentype = Bottom)
Expand Down Expand Up @@ -2167,7 +2167,7 @@ function widenreturn_noconditional(@nospecialize(rt))
local anyrefine = false
for i in 1:length(fields)
a = fields[i]
a = isvarargtype(a) ? a : widenreturn_noconditional(widenconditional(a))
a = isvarargtype(a) ? a : widenreturn_noconditional(a)
if !anyrefine
# TODO: consider adding && const_prop_profitable(a) here?
anyrefine = has_const_info(a) ||
Expand Down
20 changes: 15 additions & 5 deletions base/compiler/typelattice.jl
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@
# fields::Vector{Any} # elements are other type lattice members
# end
import Core: Const, PartialStruct
function PartialStruct(typ::DataType, fields::Vector{Any})
for i = 1:length(fields) assert_nested_type(fields[i]) end
return Core._PartialStruct(typ, fields)
end

"""
cnd::Conditional
Expand All @@ -42,8 +46,10 @@ struct Conditional
slot::Int
thentype
elsetype
Conditional(slot::Int, @nospecialize(thentype), @nospecialize(elsetype)) =
new(slot, thentype, elsetype)
function Conditional(slot::Int, @nospecialize(thentype), @nospecialize(elsetype))
assert_nested_type(thentype); assert_nested_type(elsetype)
return new(slot, thentype, elsetype)
end
end
Conditional(var::SlotNumber, @nospecialize(thentype), @nospecialize(elsetype)) =
Conditional(slot_id(var), thentype, elsetype)
Expand All @@ -60,8 +66,10 @@ struct InterConditional
slot::Int
thentype
elsetype
InterConditional(slot::Int, @nospecialize(thentype), @nospecialize(elsetype)) =
new(slot, thentype, elsetype)
function InterConditional(slot::Int, @nospecialize(thentype), @nospecialize(elsetype))
assert_nested_type(thentype); assert_nested_type(elsetype)
return new(slot, thentype, elsetype)
end
end
InterConditional(var::SlotNumber, @nospecialize(thentype), @nospecialize(elsetype)) =
InterConditional(slot_id(var), thentype, elsetype)
Expand Down Expand Up @@ -101,7 +109,7 @@ struct LimitedAccuracy
typ
causes::IdSet{InferenceState}
function LimitedAccuracy(@nospecialize(typ), causes::IdSet{InferenceState})
@assert !isa(typ, LimitedAccuracy) "malformed LimitedAccuracy"
@assert !isa(typ, LimitedAccuracy) "found nested LimitedAccuracy"
return new(typ, causes)
end
end
Expand All @@ -128,6 +136,8 @@ const CompilerTypes = Union{MaybeUndef, Const, Conditional, NotFound, PartialStr
# lattice logic #
#################

assert_nested_type(@nospecialize t) = @assert !(t isa AnyConditional) "found nested conditional"

# `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(a::C, b::C) where {C<:AnyConditional}
Expand Down

0 comments on commit d84f890

Please sign in to comment.