@@ -592,7 +592,7 @@ function fieldcount_noerror(@nospecialize t)
592592end
593593
594594
595- function try_compute_fieldidx (@nospecialize ( typ) , @nospecialize (field))
595+ function try_compute_fieldidx (typ:: DataType , @nospecialize (field))
596596 if isa (field, Symbol)
597597 field = fieldindex (typ, field, false )
598598 field == 0 && return nothing
@@ -802,6 +802,7 @@ fieldtype_tfunc(@nospecialize(s0), @nospecialize(name), @nospecialize(inbounds))
802802 fieldtype_tfunc (s0, name)
803803
804804function fieldtype_nothrow (@nospecialize (s0), @nospecialize (name))
805+ s0 === Bottom && return true # unreachable
805806 if s0 === Any || s0 === Type || DataType ⊑ s0 || UnionAll ⊑ s0
806807 # We have no idea
807808 return false
@@ -815,17 +816,27 @@ function fieldtype_nothrow(@nospecialize(s0), @nospecialize(name))
815816
816817 su = unwrap_unionall (s0)
817818 if isa (su, Union)
818- return fieldtype_nothrow (rewrap_unionall (su. a, s0), name) && fieldtype_nothrow (rewrap_unionall (su. b, s0), name)
819+ return fieldtype_nothrow (rewrap_unionall (su. a, s0), name) &&
820+ fieldtype_nothrow (rewrap_unionall (su. b, s0), name)
819821 end
820822
821- s = instanceof_tfunc (s0)[ 1 ]
822- u = unwrap_unionall (s)
823- return _fieldtype_nothrow (u , name)
823+ s, exact = instanceof_tfunc (s0)
824+ s === Bottom && return false # always
825+ return _fieldtype_nothrow (s, exact , name)
824826end
825827
826- function _fieldtype_nothrow (@nospecialize (u), name:: Const )
828+ function _fieldtype_nothrow (@nospecialize (s), exact:: Bool , name:: Const )
829+ u = unwrap_unionall (s)
827830 if isa (u, Union)
828- return _fieldtype_nothrow (u. a, name) || _fieldtype_nothrow (u. b, name)
831+ a = _fieldtype_nothrow (u. a, exact, name)
832+ b = _fieldtype_nothrow (u. b, exact, name)
833+ return exact ? (a || b) : (a && b)
834+ end
835+ u isa DataType || return false
836+ u. abstract && return false
837+ if u. name === _NAMEDTUPLE_NAME && ! isconcretetype (u)
838+ # TODO : better approximate inference
839+ return false
829840 end
830841 fld = name. val
831842 if isa (fld, Symbol)
@@ -844,6 +855,9 @@ function _fieldtype_nothrow(@nospecialize(u), name::Const)
844855end
845856
846857function fieldtype_tfunc (@nospecialize (s0), @nospecialize (name))
858+ if s0 === Bottom
859+ return Bottom
860+ end
847861 if s0 === Any || s0 === Type || DataType ⊑ s0 || UnionAll ⊑ s0
848862 return Type
849863 end
@@ -855,18 +869,28 @@ function fieldtype_tfunc(@nospecialize(s0), @nospecialize(name))
855869 return Bottom
856870 end
857871
858- s = instanceof_tfunc (s0)[1 ]
859- u = unwrap_unionall (s)
860-
861- if isa (u, Union)
862- return tmerge (rewrap (fieldtype_tfunc (Type{u. a}, name), s),
863- rewrap (fieldtype_tfunc (Type{u. b}, name), s))
872+ su = unwrap_unionall (s0)
873+ if isa (su, Union)
874+ return tmerge (fieldtype_tfunc (rewrap (su. a, s0), name),
875+ fieldtype_tfunc (rewrap (su. b, s0), name))
864876 end
865877
866- if ! isa (u, DataType) || u. abstract
867- return Type
878+ s, exact = instanceof_tfunc (s0)
879+ s === Bottom && return Bottom
880+ return _fieldtype_tfunc (s, exact, name)
881+ end
882+
883+ function _fieldtype_tfunc (@nospecialize (s), exact:: Bool , @nospecialize (name))
884+ exact = exact && ! has_free_typevars (s)
885+ u = unwrap_unionall (s)
886+ if isa (u, Union)
887+ return tmerge (_fieldtype_tfunc (rewrap (u. a, s), exact, name),
888+ _fieldtype_tfunc (rewrap (u. b, s), exact, name))
868889 end
890+ u isa DataType || return Type
891+ u. abstract && return Type
869892 if u. name === _NAMEDTUPLE_NAME && ! isconcretetype (u)
893+ # TODO : better approximate inference
870894 return Type
871895 end
872896 ftypes = u. types
@@ -875,12 +899,25 @@ function fieldtype_tfunc(@nospecialize(s0), @nospecialize(name))
875899 end
876900
877901 if ! isa (name, Const)
902+ name = widenconst (name)
878903 if ! (Int <: name || Symbol <: name )
879904 return Bottom
880905 end
881906 t = Bottom
882907 for i in 1 : length (ftypes)
883- t = tmerge (t, fieldtype_tfunc (s0, Const (i)))
908+ ft1 = unwrapva (ftypes[i])
909+ exactft1 = exact || ! has_free_typevars (ft1)
910+ ft1 = rewrap_unionall (ft1, s)
911+ if exactft1
912+ if issingletontype (ft1)
913+ ft1 = Const (ft1) # ft unique via type cache
914+ else
915+ ft1 = Type{ft1}
916+ end
917+ else
918+ ft1 = Type{ft} where ft<: ft1
919+ end
920+ t = tmerge (t, ft1)
884921 t === Any && break
885922 end
886923 return t
@@ -902,10 +939,13 @@ function fieldtype_tfunc(@nospecialize(s0), @nospecialize(name))
902939 ft = ftypes[fld]
903940 end
904941
905- exact = ( isa (s0, Const) || isType (s0)) && ! has_free_typevars (s )
942+ exactft = exact || ! has_free_typevars (ft )
906943 ft = rewrap_unionall (ft, s)
907- if exact
908- return Const (ft)
944+ if exactft
945+ if issingletontype (ft)
946+ return Const (ft) # ft unique via type cache
947+ end
948+ return Type{ft}
909949 end
910950 return Type{<: ft }
911951end
0 commit comments