Skip to content

Commit a3a0794

Browse files
committed
WIP: fix unsoundness in fieldtype of Tuple with non-Type params
1 parent d7da2a4 commit a3a0794

File tree

1 file changed

+19
-5
lines changed

1 file changed

+19
-5
lines changed

base/compiler/tfuncs.jl

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -957,8 +957,8 @@ function fieldtype_tfunc(@nospecialize(s0), @nospecialize(name))
957957
end
958958
if s0 === Any || s0 === Type || DataType s0 || UnionAll s0
959959
# For a generic DataType, one of the fields could still be a TypeVar
960-
# which is not a Type
961-
return Union{Type, TypeVar}
960+
# which is not a Type. Tuple{...} can also contain Symbols etc.
961+
return Any
962962
end
963963
# fieldtype only accepts Types
964964
if isa(s0, Const) && !(isa(s0.val, DataType) || isa(s0.val, UnionAll) || isa(s0.val, Union))
@@ -986,14 +986,14 @@ function _fieldtype_tfunc(@nospecialize(s), exact::Bool, @nospecialize(name))
986986
return tmerge(_fieldtype_tfunc(rewrap(u.a, s), exact, name),
987987
_fieldtype_tfunc(rewrap(u.b, s), exact, name))
988988
end
989-
u isa DataType || return Union{Type, TypeVar}
989+
u isa DataType || return Any
990990
if u.abstract
991991
# Abstract types have no fields
992992
exact && return Bottom
993993
# Type{...} without free typevars has no subtypes, so it is actually
994994
# exact, even if `exact` is false.
995995
isType(u) && !has_free_typevars(u.parameters[1]) && return Bottom
996-
return Union{Type, TypeVar}
996+
return Any
997997
end
998998
if u.name === _NAMEDTUPLE_NAME && !isconcretetype(u)
999999
# TODO: better approximate inference
@@ -1020,8 +1020,15 @@ function _fieldtype_tfunc(@nospecialize(s), exact::Bool, @nospecialize(name))
10201020
else
10211021
ft1 = Type{ft1}
10221022
end
1023+
elseif ft1 isa Type || ft1 isa TypeVar
1024+
if ft1 === Any && u.name === Tuple.name
1025+
# Tuple{:x}
1026+
ft1 = Any
1027+
else
1028+
ft1 = Type{ft} where ft<:ft1
1029+
end
10231030
else
1024-
ft1 = Type{ft} where ft<:ft1
1031+
ft1 = Const(ft1)
10251032
end
10261033
t = tmerge(t, ft1)
10271034
t === Any && break
@@ -1044,6 +1051,9 @@ function _fieldtype_tfunc(@nospecialize(s), exact::Bool, @nospecialize(name))
10441051
else
10451052
ft = ftypes[fld]
10461053
end
1054+
if !isa(ft, Type) && !isa(ft, TypeVar)
1055+
return Const(ft)
1056+
end
10471057

10481058
exactft = exact || (!has_free_typevars(ft) && u.name !== Tuple.name)
10491059
ft = rewrap_unionall(ft, s)
@@ -1053,6 +1063,10 @@ function _fieldtype_tfunc(@nospecialize(s), exact::Bool, @nospecialize(name))
10531063
end
10541064
return Type{ft}
10551065
end
1066+
if u.name === Tuple.name && ft === Any
1067+
# Tuple{:x} is possible
1068+
return Any
1069+
end
10561070
return Type{<:ft}
10571071
end
10581072
add_tfunc(fieldtype, 2, 3, fieldtype_tfunc, 0)

0 commit comments

Comments
 (0)