@@ -25,6 +25,7 @@ function find_tfunc(@nospecialize f)
2525end
2626
2727const DATATYPE_TYPES_FIELDINDEX = fieldindex (DataType, :types )
28+ const DATATYPE_NAME_FIELDINDEX = fieldindex (DataType, :name )
2829
2930# #########
3031# tfuncs #
@@ -823,7 +824,11 @@ function getfield_nothrow(@nospecialize(s00), @nospecialize(name), boundscheck::
823824 if isa (s, Union)
824825 return getfield_nothrow (rewrap_unionall (s. a, s00), name, boundscheck) &&
825826 getfield_nothrow (rewrap_unionall (s. b, s00), name, boundscheck)
826- elseif isa (s, DataType)
827+ elseif isType (s)
828+ sv = s. parameters[1 ]
829+ s = s0 = typeof (sv)
830+ end
831+ if isa (s, DataType)
827832 # Can't say anything about abstract types
828833 isabstracttype (s) && return false
829834 s. name. atomicfields == C_NULL || return false # TODO : currently we're only testing for ordering === :not_atomic
@@ -863,15 +868,40 @@ function getfield_tfunc(s00, name, order, boundscheck)
863868 return getfield_tfunc (s00, name)
864869end
865870getfield_tfunc (@nospecialize (s00), @nospecialize (name)) = _getfield_tfunc (s00, name, false )
871+
872+ function _getfield_fieldindex (@nospecialize (s), name:: Const )
873+ nv = name. val
874+ if isa (nv, Symbol)
875+ nv = fieldindex (s, nv, false )
876+ end
877+ if isa (nv, Int)
878+ return nv
879+ end
880+ return nothing
881+ end
882+
883+ function _getfield_tfunc_const (@nospecialize (sv), name:: Const , setfield:: Bool )
884+ if isa (name, Const)
885+ nv = _getfield_fieldindex (typeof (sv), name)
886+ nv === nothing && return Bottom
887+ if isa (sv, DataType) && nv == DATATYPE_TYPES_FIELDINDEX && isdefined (sv, nv)
888+ return Const (getfield (sv, nv))
889+ end
890+ if isconst (typeof (sv), nv)
891+ if isdefined (sv, nv)
892+ return Const (getfield (sv, nv))
893+ end
894+ return Union{}
895+ end
896+ end
897+ return nothing
898+ end
899+
866900function _getfield_tfunc (@nospecialize (s00), @nospecialize (name), setfield:: Bool )
867901 if isa (s00, Conditional)
868902 return Bottom # Bool has no fields
869- elseif isa (s00, Const) || isconstType (s00)
870- if ! isa (s00, Const)
871- sv = s00. parameters[1 ]
872- else
873- sv = s00. val
874- end
903+ elseif isa (s00, Const)
904+ sv = s00. val
875905 if isa (name, Const)
876906 nv = name. val
877907 if isa (sv, Module)
@@ -881,31 +911,15 @@ function _getfield_tfunc(@nospecialize(s00), @nospecialize(name), setfield::Bool
881911 end
882912 return Bottom
883913 end
884- if isa (nv, Symbol)
885- nv = fieldindex (typeof (sv), nv, false )
886- end
887- if ! isa (nv, Int)
888- return Bottom
889- end
890- if isa (sv, DataType) && nv == DATATYPE_TYPES_FIELDINDEX && isdefined (sv, nv)
891- return Const (getfield (sv, nv))
892- end
893- if isconst (typeof (sv), nv)
894- if isdefined (sv, nv)
895- return Const (getfield (sv, nv))
896- end
897- return Union{}
898- end
914+ r = _getfield_tfunc_const (sv, name, setfield)
915+ r != = nothing && return r
899916 end
900917 s = typeof (sv)
901918 elseif isa (s00, PartialStruct)
902919 s = widenconst (s00)
903920 sty = unwrap_unionall (s):: DataType
904921 if isa (name, Const)
905- nv = name. val
906- if isa (nv, Symbol)
907- nv = fieldindex (sty, nv, false )
908- end
922+ nv = _getfield_fieldindex (sty, name)
909923 if isa (nv, Int) && 1 <= nv <= length (s00. fields)
910924 return unwrapva (s00. fields[nv])
911925 end
@@ -917,6 +931,26 @@ function _getfield_tfunc(@nospecialize(s00), @nospecialize(name), setfield::Bool
917931 return tmerge (_getfield_tfunc (rewrap_unionall (s. a, s00), name, setfield),
918932 _getfield_tfunc (rewrap_unionall (s. b, s00), name, setfield))
919933 end
934+ if isType (s)
935+ if isconstType (s)
936+ sv = s00. parameters[1 ]
937+ if isa (name, Const)
938+ r = _getfield_tfunc_const (sv, name, setfield)
939+ r != = nothing && return r
940+ end
941+ s = typeof (sv)
942+ else
943+ sv = s. parameters[1 ]
944+ if isa (sv, DataType) && isa (name, Const) && (! isType (sv) && sv != = Core. TypeofBottom)
945+ nv = _getfield_fieldindex (DataType, name)
946+ if nv == DATATYPE_NAME_FIELDINDEX
947+ # N.B. This doesn't work in general, because
948+ return Const (sv. name)
949+ end
950+ s = DataType
951+ end
952+ end
953+ end
920954 isa (s, DataType) || return Any
921955 isabstracttype (s) && return Any
922956 if s <: Tuple && ! hasintersect (widenconst (name), Int)
@@ -972,13 +1006,8 @@ function _getfield_tfunc(@nospecialize(s00), @nospecialize(name), setfield::Bool
9721006 end
9731007 return t
9741008 end
975- fld = name. val
976- if isa (fld, Symbol)
977- fld = fieldindex (s, fld, false )
978- end
979- if ! isa (fld, Int)
980- return Bottom
981- end
1009+ fld = _getfield_fieldindex (s, name)
1010+ fld === nothing && return Bottom
9821011 if s <: Tuple && fld >= nf && isvarargtype (ftypes[nf])
9831012 return rewrap_unionall (unwrapva (ftypes[nf]), s00)
9841013 end
0 commit comments