Skip to content

Commit e32af99

Browse files
committed
tfunc: Constant fold isdefined for (dt::DataType).fields
In PR #53750, we stopped constant folding `isdefined` for non-`const` fields assuming that they may revert to `undef`. Unfortunately, this broke `fieldcount` for `Tuple`s, causing significant inference quality degradation. Adjust `fieldcount` to avoid this.
1 parent c38e7cd commit e32af99

File tree

3 files changed

+9
-3
lines changed

3 files changed

+9
-3
lines changed

base/boot.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,7 @@ macro _boundscheck() Expr(:boundscheck) end
295295
TypeVar(@nospecialize(n)) = _typevar(n::Symbol, Union{}, Any)
296296
TypeVar(@nospecialize(n), @nospecialize(ub)) = _typevar(n::Symbol, Union{}, ub)
297297
TypeVar(@nospecialize(n), @nospecialize(lb), @nospecialize(ub)) = _typevar(n::Symbol, lb, ub)
298-
UnionAll(@nospecialize(v), @nospecialize(t)) = ccall(:jl_type_unionall, Any, (Any, Any), v::TypeVar, t)
298+
UnionAll(@nospecialize(v), @nospecialize(t)) = (@_foldable_meta; ccall(:jl_type_unionall, Any, (Any, Any), v::TypeVar, t))
299299

300300
const Memory{T} = GenericMemory{:not_atomic, T, CPU}
301301
const MemoryRef{T} = GenericMemoryRef{:not_atomic, T, CPU}

base/reflection.jl

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1003,12 +1003,15 @@ function datatype_fieldcount(t::DataType)
10031003
return fieldcount(types)
10041004
end
10051005
return nothing
1006-
elseif isabstracttype(t) || (t.name === Tuple.name && isvatuple(t))
1006+
elseif isabstracttype(t)
10071007
return nothing
10081008
end
1009-
if isdefined(t, :types)
1009+
if t.name === Tuple.name
1010+
isvatuple(t) && return nothing
10101011
return length(t.types)
10111012
end
1013+
# Equivalent to length(t.types), but `t.types` is lazy and we do not want
1014+
# to be forced to compute it.
10121015
return length(t.name.names)
10131016
end
10141017

test/compiler/inference.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5725,3 +5725,6 @@ let interp = CachedConditionalInterp();
57255725
result.linfo.def.name === :func_cached_conditional
57265726
end == 1
57275727
end
5728+
5729+
# fieldcount on `Tuple` should constant fold, even though `.fields` not const
5730+
@test fully_eliminated(Base.fieldcount, Tuple{Type{Tuple{Nothing, Int, Int}}})

0 commit comments

Comments
 (0)