Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: crystal-lang/crystal
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: ff006ffc045b
Choose a base ref
...
head repository: crystal-lang/crystal
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 4451d7674a66
Choose a head ref
  • 4 commits
  • 6 files changed
  • 1 contributor

Commits on Jun 6, 2016

  1. Forward double splat in a few methods

    Ary Borenszweig committed Jun 6, 2016
    Copy the full SHA
    2e43c5c View commit details
  2. Fixed #2764: Method with splat and optional named argument doesn't ma…

    …tch zero args call
    Ary Borenszweig committed Jun 6, 2016
    Copy the full SHA
    5e8aaac View commit details
  3. Fixed #2765: Default value is allowed for a splat argument or double …

    …splat argument
    Ary Borenszweig committed Jun 6, 2016
    Copy the full SHA
    d9b7825 View commit details
  4. Fixed #2766: Method with default arguments and splat doesn't match ca…

    …ll with one arg
    Ary Borenszweig committed Jun 6, 2016
    Copy the full SHA
    4451d76 View commit details
Showing with 39 additions and 12 deletions.
  1. +3 −0 spec/compiler/parser/parser_spec.cr
  2. +20 −0 spec/compiler/type_inference/splat_spec.cr
  3. +3 −2 src/compiler/crystal/syntax/ast.cr
  4. +3 −0 src/compiler/crystal/syntax/parser.cr
  5. +6 −6 src/io.cr
  6. +4 −4 src/kernel.cr
3 changes: 3 additions & 0 deletions spec/compiler/parser/parser_spec.cr
Original file line number Diff line number Diff line change
@@ -1324,6 +1324,9 @@ describe "Parser" do

assert_syntax_error "'''", "invalid empty char literal"

assert_syntax_error "def foo(*args = 1); end", "splat argument can't have default value"
assert_syntax_error "def foo(**args = 1); end", "double splat argument can't have default value"

describe "end locations" do
assert_end_location "nil"
assert_end_location "false"
20 changes: 20 additions & 0 deletions spec/compiler/type_inference/splat_spec.cr
Original file line number Diff line number Diff line change
@@ -417,6 +417,26 @@ describe "Type inference: splat" do
"no overload matches"
end

it "method with splat and optional named argument matches zero args call (#2746)" do
assert_type(%(
def foo(*args, k1 = nil)
args
end
foo
)) { tuple_of([] of Type) }
end

it "method with default arguments and splat matches call with one arg (#2766)" do
assert_type(%(
def foo(a = nil, b = nil, *, c = nil)
a
end
foo(10)
)) { int32 }
end

describe Splat do
it "without splat" do
a_def = Def.new("foo", args: [Arg.new("x"), Arg.new("y")])
5 changes: 3 additions & 2 deletions src/compiler/crystal/syntax/ast.cr
Original file line number Diff line number Diff line change
@@ -952,9 +952,10 @@ module Crystal
splat_index = self.splat_index
if splat_index
if args[splat_index].name.empty?
min_size = max_size = splat_index
min_size = {default_value_index || splat_index, splat_index}.min
max_size = splat_index
else
min_size -= 1 unless default_value_index
min_size -= 1 unless default_value_index && default_value_index < splat_index
max_size = Int32::MAX
end
end
3 changes: 3 additions & 0 deletions src/compiler/crystal/syntax/parser.cr
Original file line number Diff line number Diff line change
@@ -3190,6 +3190,9 @@ module Crystal
end

if @token.type == :"="
raise "splat argument can't have default value", @token if splat
raise "double splat argument can't have default value", @token if double_splat

next_token_skip_space_or_newline

case @token.type
12 changes: 6 additions & 6 deletions src/io.cr
Original file line number Diff line number Diff line change
@@ -657,8 +657,8 @@ module IO
end

# Same as `gets`, but raises `EOFError` if called at the end of this IO.
def read_line(*args) : String?
gets(*args) || raise EOFError.new
def read_line(*args, **options) : String?
gets(*args, **options) || raise EOFError.new
end

# Reads and discards *bytes_count* bytes.
@@ -754,8 +754,8 @@ module IO
# olleh
# dlrow
# ```
def each_line(*args)
while line = gets(*args)
def each_line(*args, **options)
while line = gets(*args, **options)
yield line
end
end
@@ -770,8 +770,8 @@ module IO
# iter.next # => "hello\n"
# iter.next # => "world"
# ```
def each_line(*args)
LineIterator.new(self, args)
def each_line(*args, **options)
LineIterator.new(self, args, **options)
end

# Inovkes the given block with each `Char` in this IO.
8 changes: 4 additions & 4 deletions src/kernel.cr
Original file line number Diff line number Diff line change
@@ -28,13 +28,13 @@ def loop
end

# Reads a line from STDIN. See `IO#gets`.
def gets(*args)
STDIN.gets(*args)
def gets(*args, **options)
STDIN.gets(*args, **options)
end

# Reads a line from STDIN. See `IO#read_line`.
def read_line(*args)
STDIN.read_line(*args)
def read_line(*args, **options)
STDIN.read_line(*args, **options)
end

# Prints objects to STDOUT and then invokes `STDOUT.flush`. See `IO#print`.