I feel like this could be worked around because it’s impossible to have an empty tuple (in normal code anyway) and braces wrapped in parentheses and not prefixed with an identifier would explicitly indicate the value is a hash and not a block, i.e.
def foo(value : Hash(String, String)) : Nil
end
def bar(& -> _) : Nil
end
foo {} # invalid, parsed as a block
foo(bar {}) # invalid, parsed as a call to `bar`
foo({}) # valid, cannot be parsed as any other expression
The same can be said for initialization with the same rules:
class Foo
@bar : Hash(String, Int32) = {} # still valid
def initialize(@bar = {}) # also valid
end
end