Skip to content

Commit 9f43871

Browse files
authored
Make T.instance inferable (#30086)
1 parent 69fabf7 commit 9f43871

File tree

2 files changed

+22
-8
lines changed

2 files changed

+22
-8
lines changed

base/compiler/tfuncs.jl

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ const DATATYPE_PARAMETERS_FIELDINDEX = fieldindex(DataType, :parameters)
3131
const DATATYPE_TYPES_FIELDINDEX = fieldindex(DataType, :types)
3232
const DATATYPE_SUPER_FIELDINDEX = fieldindex(DataType, :super)
3333
const DATATYPE_MUTABLE_FIELDINDEX = fieldindex(DataType, :mutable)
34+
const DATATYPE_INSTANCE_FIELDINDEX = fieldindex(DataType, :instance)
3435

3536
const TYPENAME_NAME_FIELDINDEX = fieldindex(Core.TypeName, :name)
3637
const TYPENAME_MODULE_FIELDINDEX = fieldindex(Core.TypeName, :module)
@@ -292,8 +293,11 @@ function isdefined_tfunc(@nospecialize(args...))
292293
return Const(false)
293294
elseif !isvatuple(a1) && isbitstype(fieldtype(a1, idx))
294295
return Const(true)
295-
elseif isa(arg1, Const) && isimmutable((arg1::Const).val)
296-
return Const(isdefined((arg1::Const).val, idx))
296+
elseif isa(arg1, Const)
297+
arg1v = (arg1::Const).val
298+
if isimmutable(arg1v) || isdefined(arg1v, idx) || (isa(arg1v, DataType) && is_dt_const_field(idx))
299+
return Const(isdefined(arg1v, idx))
300+
end
297301
end
298302
end
299303
end
@@ -518,13 +522,19 @@ function subtype_tfunc(@nospecialize(a), @nospecialize(b))
518522
end
519523
add_tfunc(<:, 2, 2, subtype_tfunc, 0)
520524

525+
is_dt_const_field(fld::Int) = (
526+
fld == DATATYPE_NAME_FIELDINDEX ||
527+
fld == DATATYPE_PARAMETERS_FIELDINDEX ||
528+
fld == DATATYPE_TYPES_FIELDINDEX ||
529+
fld == DATATYPE_SUPER_FIELDINDEX ||
530+
fld == DATATYPE_MUTABLE_FIELDINDEX ||
531+
fld == DATATYPE_INSTANCE_FIELDINDEX
532+
)
521533
function const_datatype_getfield_tfunc(@nospecialize(sv), fld::Int)
522-
if (fld == DATATYPE_NAME_FIELDINDEX ||
523-
fld == DATATYPE_PARAMETERS_FIELDINDEX ||
524-
fld == DATATYPE_TYPES_FIELDINDEX ||
525-
fld == DATATYPE_SUPER_FIELDINDEX ||
526-
fld == DATATYPE_MUTABLE_FIELDINDEX)
527-
return AbstractEvalConstant(getfield(sv, fld))
534+
if fld == DATATYPE_INSTANCE_FIELDINDEX
535+
return isdefined(sv, fld) ? Const(getfield(sv, fld)) : Union{}
536+
elseif is_dt_const_field(fld)
537+
return Const(getfield(sv, fld))
528538
end
529539
return nothing
530540
end

test/compiler/compiler.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2130,3 +2130,7 @@ let ci = code_typed(bar_inlining_apply, Tuple{})[1].first
21302130
@test length(ci.code) == 2
21312131
@test ci.code[1].head == :foreigncall
21322132
end
2133+
2134+
# Test that inference can infer .instance of types
2135+
f_instance(::Type{T}) where {T} = T.instance
2136+
@test @inferred(f_instance(Nothing)) === nothing

0 commit comments

Comments
 (0)