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

Compiler: fix overload of union type through alias against type #8258

Merged

Conversation

@asterite
Copy link
Member

asterite commented Oct 2, 2019

If you do this:

def foo(x : Int32)
  1
end

def foo(x : Int8 | Int32)
  'a'
end

foo(1) # =>  1

It works because Int32 is "stricter" than Int8 | Int32 and the other way around is not true, so the Int32 overload takes precedence (when ordering overloads).

However, before this PR, when using an alias to define the union:

alias A = Int8 | Int32

def foo(x : Int32)
  1
end

def foo(x : A)
  'a'
end

foo(1) # =>  'a'

It didn't work well! The reason was an incorrect logic when defining which type is stricter than the other. In this case, the union type, through the alias type, ended up stricter than the other type and eventually overwrote the other method (the first method could never be called/reached).

While working on something else I noticed this was affecting this line:

def divmod(number : LibGMP::ULong)

and this line:

def divmod(number : Int::Unsigned)

Because Int::Unsigned is an alias, the first overload was overwritten because of this bug.

This PR fixes this situation.

Changing any? to all? is also consistent with another part of the code where unions are checked for strictness:

types.all? &.restriction_of?(other, owner)

@asterite asterite merged commit 65ba903 into crystal-lang:master Oct 2, 2019
5 of 6 checks passed
5 of 6 checks passed
ci/circleci: test_preview_mt Your tests failed on CircleCI
Details
ci/circleci: check_format Your tests passed on CircleCI!
Details
ci/circleci: test_darwin Your tests passed on CircleCI!
Details
ci/circleci: test_linux Your tests passed on CircleCI!
Details
ci/circleci: test_linux32 Your tests passed on CircleCI!
Details
continuous-integration/travis-ci/pr The Travis CI build passed
Details
@asterite asterite deleted the asterite:bug/union-type-restriction-of branch Oct 2, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants
You can’t perform that action at this time.