New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Union Type on Module is Incorrectly Rejected by Compiler #13243
Comments
It's definitely a bug because the error message doesn't make sense. Btw. you get the same error message with |
One workaround I've found is discarding the module type for the includer types. This can be done at using macro includes(call)
{%
types_to_resolve = [call]
types = { } of Nil => Nil
types_to_resolve.each do |t|
if t.is_a?(Call)
types_to_resolve << t.receiver
t.args.each { |tv| types_to_resolve << tv }
else
t.resolve.includers.each { |ti|
types[ti] = true
}
end
end
%}
{{ "Union(#{types.keys.splat})".id }}
end
ab_list = array.select(includes A|B) It's not ideal. But in case someone finds this issue, having a workaround may be useful. |
I'm not sure if I should make a new issue, however I was fiddling with some code after reading #2404 and found a similar bug to the one I reported here: module A; end
module B; end
module C; end
class ClassA; include A; end
class ClassB; include B; end
class ClassC; include C; end
class ClassAB; include A; include B; end
class ClassAC; include A; include C; end
class ClassBC; include B; include C; end
# In /usr/lib/crystal/pointer.cr:132:29
#
# 132 | (self + offset).value = value
# ^----
# Error: type must be (ClassAB | ClassABC | ClassAC | ClassBC | ClassC), not (C | ClassAB)
ys = Array(A|B|C).new.compact_map{|x|
x if (x.is_a? A && x.is_a? B) || x.is_a? C
}
# Okay, `itself` changes `C` into one of its individual members
zs = Array(A|B|C).new.compact_map{|x|
x.itself if (x.is_a? A && x.is_a? B) || x.is_a? C
} It seems like
|
System Info
OS: Arch Linux
Crystal Version: 1.7.3
LLVM: 14.0.6
Defaulttarget: x86_64-pc-linux-gnu
Bug Report
When preforming type unions on modules, the crystal compiler will reject the following code:
Additionally, it produces that unusual error message that Crystal "expected argument #1 to 'g' to be Array(A | B), not Array(A | B)". This is despite the fact that
ab_list
is of typeArray(A|B)
. There is nothing in the docs that says this code is invalid. So, I'm lead to believe there is a bug in how the compiler resolves unions of modules.The text was updated successfully, but these errors were encountered: