Skip to content

Commit

Permalink
Redefine defs when constant and number in generic arguments are equal
Browse files Browse the repository at this point in the history
  • Loading branch information
HertzDevil committed Nov 27, 2022
1 parent 022e1f9 commit c71534f
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 0 deletions.
40 changes: 40 additions & 0 deletions spec/compiler/semantic/restrictions_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,46 @@ describe "Restrictions" do
end
end

describe "Path vs NumberLiteral" do
it "inserts constant before number literal of same value with generic arguments" do
assert_type(<<-CR) { bool }
X = 1
class Foo(N)
end
def foo(a : Foo(1))
'a'
end
def foo(a : Foo(X))
true
end
foo(Foo(1).new)
CR
end

it "inserts number literal before constant of same value with generic arguments" do
assert_type(<<-CR) { bool }
X = 1
class Foo(N)
end
def foo(a : Foo(X))
'a'
end
def foo(a : Foo(1))
true
end
foo(Foo(1).new)
CR
end
end

describe "free variables" do
it "inserts path before free variable with same name" do
assert_type(<<-CR) { tuple_of([char, bool]) }
Expand Down
46 changes: 46 additions & 0 deletions src/compiler/crystal/semantic/restrictions.cr
Original file line number Diff line number Diff line change
Expand Up @@ -605,11 +605,57 @@ module Crystal
false
end

def restriction_of?(other : NumberLiteral, owner, self_free_vars = nil, other_free_vars = nil)
# this happens when `self` and `other` are generic arguments:
#
# ```
# X = 1
#
# def foo(param : StaticArray(Int32, X))
# end
#
# def foo(param : StaticArray(Int32, 1))
# end
# ```
case self_type = owner.lookup_path(self)
when Const
self_type.value == other
when NumberLiteral
self_type == other
else
false
end
end

def restriction_of?(other, owner, self_free_vars = nil, other_free_vars = nil)
false
end
end

class NumberLiteral
def restriction_of?(other : Path, owner, self_free_vars = nil, other_free_vars = nil)
# this happens when `self` and `other` are generic arguments:
#
# ```
# X = 1
#
# def foo(param : StaticArray(Int32, 1))
# end
#
# def foo(param : StaticArray(Int32, X))
# end
# ```
case other_type = owner.lookup_path(other)
when Const
other_type.value == self
when NumberLiteral
other_type == self
else
false
end
end
end

class Union
def restriction_of?(other, owner, self_free_vars = nil, other_free_vars = nil)
# For a union to be considered before another restriction,
Expand Down

0 comments on commit c71534f

Please sign in to comment.