@@ -820,19 +820,22 @@ function fieldtype_nothrow(@nospecialize(s0), @nospecialize(name))
820820 fieldtype_nothrow (rewrap_unionall (su. b, s0), name)
821821 end
822822
823- s = instanceof_tfunc (s0)[ 1 ]
823+ s, exact = instanceof_tfunc (s0)
824824 s === Bottom && return false # always
825- return _fieldtype_nothrow (s, name)
825+ return _fieldtype_nothrow (s, exact, name)
826826end
827827
828- function _fieldtype_nothrow (@nospecialize (s), name:: Const )
828+ function _fieldtype_nothrow (@nospecialize (s), exact :: Bool , name:: Const )
829829 u = unwrap_unionall (s)
830830 if isa (u, Union)
831- 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)
832834 end
833835 u isa DataType || return false
834- u. abstract && return true
836+ u. abstract && return false
835837 if u. name === _NAMEDTUPLE_NAME && ! isconcretetype (u)
838+ # TODO : better approximate inference
836839 return false
837840 end
838841 fld = name. val
@@ -887,6 +890,7 @@ function _fieldtype_tfunc(@nospecialize(s), exact::Bool, @nospecialize(name))
887890 u isa DataType || return Type
888891 u. abstract && return Type
889892 if u. name === _NAMEDTUPLE_NAME && ! isconcretetype (u)
893+ # TODO : better approximate inference
890894 return Type
891895 end
892896 ftypes = u. types
@@ -904,7 +908,15 @@ function _fieldtype_tfunc(@nospecialize(s), exact::Bool, @nospecialize(name))
904908 ft1 = unwrapva (ftypes[i])
905909 exactft1 = exact || ! has_free_typevars (ft1)
906910 ft1 = rewrap_unionall (ft1, s)
907- ft1 = exactft1 ? Const (ft1) : Type{ft} where ft<: ft1
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
908920 t = tmerge (t, ft1)
909921 t === Any && break
910922 end
@@ -930,7 +942,10 @@ function _fieldtype_tfunc(@nospecialize(s), exact::Bool, @nospecialize(name))
930942 exactft = exact || ! has_free_typevars (ft)
931943 ft = rewrap_unionall (ft, s)
932944 if exactft
933- return Const (ft)
945+ if issingletontype (ft)
946+ return Const (ft) # ft unique via type cache
947+ end
948+ return Type{ft}
934949 end
935950 return Type{<: ft }
936951end
0 commit comments