Skip to content
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 restrictions with multiple free vars #10371

Open
HertzDevil opened this issue Feb 6, 2021 · 0 comments
Open

Union type restrictions with multiple free vars #10371

HertzDevil opened this issue Feb 6, 2021 · 0 comments
Labels
kind:bug A bug in the code. Does not apply to documentation, specs, etc. topic:compiler:semantic

Comments

@HertzDevil
Copy link
Contributor

#10267 disallows unions in type restrictions that refer to more than one free var. However, some unions with multiple free vars are in fact solvable:

def foo(x : T, y : U, z : T | U) forall T, U
end

foo(1, 'a', 1)   # okay, T = Int32, U = Char
foo(1, 'a', 'a') # okay, T = Int32, U = Char
foo(1, 1, 1)     # okay, T = Int32, U = Int32

That PR also doesn't raise on free vars that aren't directly under the union type, so the following oddity happens on 0.36.1: (contrast this to #8973 and #10370)

def foo(x : Array(T) | T) forall T
  T
end

def bar(x : T | Array(T)) forall T
  T
end

foo([1]) # => Int32
bar([1]) # => Array(Int32)

foo([[1]] || [[1], 1]) # => (Array(Int32) | Int32)
# note that typeof(x) <= (Array(T) | T) is false in this case; somewhere
# Crystal considers Array(X | Y) to be distributive over the union, turning
# Array(Array(Int32) | Int32) into Array(Array(Int32)) | Array(Int32)

bar([[1]] || [[1], 1]) # => (Array(Int32) | Int32)

Until we figure out how to unify those kinds of free vars, I think we should disallow any union type restrictions that use more than one free var, whether they are identical or not, and whether they appear as generic type / metaclass arguments or not.

@straight-shoota straight-shoota added kind:bug A bug in the code. Does not apply to documentation, specs, etc. topic:compiler:semantic labels Feb 6, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind:bug A bug in the code. Does not apply to documentation, specs, etc. topic:compiler:semantic
Projects
None yet
Development

No branches or pull requests

2 participants