Skip to content

Commit be6fac4

Browse files
authored
Merge pull request #287 from JuliaSymbolics/myb/fn
More robust subtype check
2 parents 4480b8b + 8107658 commit be6fac4

File tree

2 files changed

+15
-13
lines changed

2 files changed

+15
-13
lines changed

src/types.jl

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -215,18 +215,11 @@ function promote_symtype(f::Sym{FnType{X,Y}}, args...) where {X, Y}
215215
return Y
216216
end
217217

218-
nrequired = fieldcount(X)
219-
ngiven = nfields(args)
220-
221-
if nrequired !== ngiven
222-
error("$f takes $nrequired arguments; $ngiven arguments given")
223-
end
224-
225-
for i in 1:ngiven
226-
t = X.parameters[i]
227-
if !(args[i] <: t)
228-
error("Argument to $f at position $i must be of symbolic type $t")
229-
end
218+
# This is to handle `Tuple{T} where T`, so we cannot reliably query the type
219+
# parameters of the `Tuple` in `FnType`.
220+
t = Tuple{args...}
221+
if !(t <: X)
222+
error("$t is not a subtype of $X.")
230223
end
231224
return Y
232225
end
@@ -291,7 +284,9 @@ end
291284

292285
function Base.show(io::IO, f::Sym{<:FnType{X,Y}}) where {X,Y}
293286
print(io, f.name)
294-
argrepr = join(map(t->"::"*string(t), X.parameters), ", ")
287+
# Use `Base.unwrap_unionall` to handle `Tuple{T} where T`. This is not the
288+
# best printing, but it's better than erroring.
289+
argrepr = join(map(t->"::"*string(t), Base.unwrap_unionall(X).parameters), ", ")
295290
print(io, "(", argrepr, ")")
296291
print(io, "::", Y)
297292
end

test/basics.jl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,3 +212,10 @@ end
212212
@syms a b c
213213
@test isequal(a + b, a + b + 0.01 - 0.01)
214214
end
215+
216+
@testset "subtyping" begin
217+
T = FnType{Tuple{T,S,Int} where {T,S}, Real}
218+
s = Sym{T}(:t)
219+
@syms a b c::Int
220+
@test isequal(arguments(s(a, b, c)), [a, b, c])
221+
end

0 commit comments

Comments
 (0)