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: 5f372c1c4407
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: 753ee6ce5d5f
Choose a head ref
  • 2 commits
  • 41 files changed
  • 1 contributor

Commits on Sep 14, 2016

  1. Compiler: introduce forall syntax for free variables. Fixes #3288

    Ary Borenszweig committed Sep 14, 2016
    Copy the full SHA
    9623dfc View commit details
  2. Compiler: lift the restriction that top-level type names can't be nam…

    …ed with single letters. Fixes #3269
    Ary Borenszweig committed Sep 14, 2016
    Copy the full SHA
    753ee6c View commit details
Showing with 198 additions and 96 deletions.
  1. +1 −1 spec/compiler/codegen/block_spec.cr
  2. +2 −2 spec/compiler/codegen/closure_spec.cr
  3. +1 −1 spec/compiler/codegen/def_spec.cr
  4. +2 −2 spec/compiler/codegen/macro_spec.cr
  5. +3 −3 spec/compiler/codegen/proc_spec.cr
  6. +1 −1 spec/compiler/codegen/tuple_spec.cr
  7. +1 −1 spec/compiler/codegen/union_type_spec.cr
  8. +1 −0 spec/compiler/formatter/formatter_spec.cr
  9. +6 −0 spec/compiler/parser/parser_spec.cr
  10. +1 −0 spec/compiler/parser/to_s_spec.cr
  11. +9 −9 spec/compiler/semantic/block_spec.cr
  12. +5 −4 spec/compiler/semantic/class_spec.cr
  13. +4 −4 spec/compiler/semantic/closure_spec.cr
  14. +1 −1 spec/compiler/semantic/const_spec.cr
  15. +13 −13 spec/compiler/semantic/def_overload_spec.cr
  16. +35 −1 spec/compiler/semantic/def_spec.cr
  17. +2 −2 spec/compiler/semantic/double_splat_spec.cr
  18. +2 −2 spec/compiler/semantic/generic_class_spec.cr
  19. +1 −1 spec/compiler/semantic/module_spec.cr
  20. +1 −1 spec/compiler/semantic/named_tuple_spec.cr
  21. +1 −1 spec/compiler/semantic/primitives_spec.cr
  22. +5 −5 spec/compiler/semantic/proc_spec.cr
  23. +2 −2 spec/compiler/semantic/restrictions_spec.cr
  24. +1 −1 spec/compiler/semantic/return_spec.cr
  25. +5 −5 spec/compiler/semantic/splat_spec.cr
  26. +3 −3 spec/compiler/semantic/static_array_spec.cr
  27. +3 −3 spec/compiler/semantic/tuple_spec.cr
  28. +1 −1 spec/compiler/semantic/union_spec.cr
  29. +3 −1 src/compiler/crystal/semantic/call.cr
  30. +1 −1 src/compiler/crystal/semantic/call_error.cr
  31. +2 −1 src/compiler/crystal/semantic/default_arguments.cr
  32. +5 −2 src/compiler/crystal/semantic/match.cr
  33. +2 −0 src/compiler/crystal/semantic/method_lookup.cr
  34. +1 −0 src/compiler/crystal/semantic/new.cr
  35. +15 −0 src/compiler/crystal/semantic/restrictions.cr
  36. +0 −18 src/compiler/crystal/semantic/top_level_visitor.cr
  37. +3 −2 src/compiler/crystal/syntax/ast.cr
  38. +24 −1 src/compiler/crystal/syntax/parser.cr
  39. +6 −0 src/compiler/crystal/syntax/to_s.cr
  40. +5 −0 src/compiler/crystal/tools/doc/method.cr
  41. +18 −0 src/compiler/crystal/tools/formatter.cr
2 changes: 1 addition & 1 deletion spec/compiler/codegen/block_spec.cr
Original file line number Diff line number Diff line change
@@ -1300,7 +1300,7 @@ describe "Code gen: block" do

it "does next from captured block" do
run(%(
def foo(&block : -> T)
def foo(&block : -> T) forall T
block
end
4 changes: 2 additions & 2 deletions spec/compiler/codegen/closure_spec.cr
Original file line number Diff line number Diff line change
@@ -507,7 +507,7 @@ describe "Code gen: closure" do

it "transforms block to proc literal with free var" do
run("
def foo(&block : Int32 -> U)
def foo(&block : Int32 -> U) forall U
block
end
@@ -538,7 +538,7 @@ describe "Code gen: closure" do

it "allows giving less block args when transforming block to proc literal" do
run("
def foo(&block : Int32 -> U)
def foo(&block : Int32 -> U) forall U
block.call(1)
end
2 changes: 1 addition & 1 deletion spec/compiler/codegen/def_spec.cr
Original file line number Diff line number Diff line change
@@ -522,7 +522,7 @@ describe "Code gen: def" do

it "can match N type argument of static array (#1203)" do
run(%(
def fn(a : StaticArray(T, N))
def fn(a : StaticArray(T, N)) forall T, N
N
end
4 changes: 2 additions & 2 deletions spec/compiler/codegen/macro_spec.cr
Original file line number Diff line number Diff line change
@@ -1201,7 +1201,7 @@ describe "Code gen: macro" do

it "can access free variables" do
run(%(
def foo(x : T)
def foo(x : T) forall T
{{ T.stringify }}
end
@@ -1346,7 +1346,7 @@ describe "Code gen: macro" do
it "uses tuple T in method with free vars" do
run(%(
struct Tuple
def foo(x : U)
def foo(x : U) forall U
{{T.size}}
end
end
6 changes: 3 additions & 3 deletions spec/compiler/codegen/proc_spec.cr
Original file line number Diff line number Diff line change
@@ -292,7 +292,7 @@ describe "Code gen: proc" do

it "codegens nilable proc type dispatch (1)" do
run("
def foo(x : -> U)
def foo(x : -> U) forall U
x.call
end
@@ -307,7 +307,7 @@ describe "Code gen: proc" do

it "codegens nilable proc type dispatch (2)" do
run("
def foo(x : -> U)
def foo(x : -> U) forall U
x.call
end
@@ -428,7 +428,7 @@ describe "Code gen: proc" do
end
end
def func(&block : Foo -> U)
def func(&block : Foo -> U) forall U
block
end
2 changes: 1 addition & 1 deletion spec/compiler/codegen/tuple_spec.cr
Original file line number Diff line number Diff line change
@@ -66,7 +66,7 @@ describe "Code gen: tuple" do
end
end
def foo(x : T)
def foo(x : T) forall T
p = Pointer(T).malloc(1)
p.value = x
p
2 changes: 1 addition & 1 deletion spec/compiler/codegen/union_type_spec.cr
Original file line number Diff line number Diff line change
@@ -183,7 +183,7 @@ describe "Code gen: union type" do
str = run(%(
require "prelude"
def foo(x : T)
def foo(x : T) forall T
T.to_s
end
1 change: 1 addition & 0 deletions spec/compiler/formatter/formatter_spec.cr
Original file line number Diff line number Diff line change
@@ -189,6 +189,7 @@ describe Crystal::Formatter do
assert_format "def %(x)\n 1\nend"
assert_format "def `(x)\n 1\nend"
assert_format "def /(x)\n 1\nend"
assert_format "def foo(x : X) forall X , Y; end", "def foo(x : X) forall X, Y\nend"

assert_format "foo"
assert_format "foo()"
6 changes: 6 additions & 0 deletions spec/compiler/parser/parser_spec.cr
Original file line number Diff line number Diff line change
@@ -265,6 +265,12 @@ describe "Parser" do
assert_syntax_error "def foo @@var, █ end", "parentheses are mandatory for def arguments"
assert_syntax_error "def foo *y; 1; end", "parentheses are mandatory for def arguments"

it_parses "def foo(x : U) forall U; end", Def.new("foo", args: [Arg.new("x", restriction: "U".path)], free_vars: %w(U))
it_parses "def foo(x : U) forall T, U; end", Def.new("foo", args: [Arg.new("x", restriction: "U".path)], free_vars: %w(T U))
it_parses "def foo(x : U) : Int32 forall T, U; end", Def.new("foo", args: [Arg.new("x", restriction: "U".path)], return_type: "Int32".path, free_vars: %w(T U))
assert_syntax_error "def foo(x : U) forall; end"
assert_syntax_error "def foo(x : U) forall U,; end"

it_parses "foo", "foo".call
it_parses "foo()", "foo".call
it_parses "foo(1)", "foo".call(1.int32)
1 change: 1 addition & 0 deletions spec/compiler/parser/to_s_spec.cr
Original file line number Diff line number Diff line change
@@ -46,6 +46,7 @@ describe "ASTNode#to_s" do
expect_to_s %[1 & 2 & (3 | 4)], %[(1 & 2) & (3 | 4)]
expect_to_s %[(1 & 2) & (3 | 4)]
expect_to_s "def foo(x : T = 1)\nend"
expect_to_s "def foo(x : X, y : Y) forall X, Y\nend"
expect_to_s %(foo : A | (B -> C))
expect_to_s %[%("\#{foo}")], %["\\\"\#{foo}\\\""]
expect_to_s "class Foo\n private def bar\n end\nend"
18 changes: 9 additions & 9 deletions spec/compiler/semantic/block_spec.cr
Original file line number Diff line number Diff line change
@@ -130,7 +130,7 @@ describe "Block inference" do
end
end
def bar(&block : Int32 -> U)
def bar(&block : Int32 -> U) forall U
Foo(U).new(yield 1)
end
@@ -150,7 +150,7 @@ describe "Block inference" do
end
end
def foo(x : U, &block: U -> T)
def foo(x : U, &block: U -> T) forall T, U
Foo(T).new(yield x)
end
@@ -250,7 +250,7 @@ describe "Block inference" do
class Foo(T)
end
def foo(&block: Int32 -> Foo(T))
def foo(&block: Int32 -> Foo(T)) forall T
yield 1
Foo(T).new
end
@@ -838,7 +838,7 @@ describe "Block inference" do

it "recalculates call that uses block arg output as free var" do
assert_type(%(
def foo(&block : Int32 -> U)
def foo(&block : Int32 -> U) forall U
block
U
end
@@ -871,7 +871,7 @@ describe "Block inference" do
end
class Bar
def initialize(&block : Int32 -> U)
def initialize(&block : Int32 -> U) forall U
block
end
end
@@ -951,7 +951,7 @@ describe "Block inference" do

it "binds to proc, not only to its body (#1796)" do
assert_type(%(
def yielder(&block : Int32 -> U)
def yielder(&block : Int32 -> U) forall U
yield 1
U
end
@@ -962,7 +962,7 @@ describe "Block inference" do

it "binds block return type free variable even if there are no block arguments (#1797)" do
assert_type(%(
def yielder(&block : -> U)
def yielder(&block : -> U) forall U
yield
U
end
@@ -1031,7 +1031,7 @@ describe "Block inference" do

it "does next from captured block" do
assert_type(%(
def foo(&block : -> T)
def foo(&block : -> T) forall T
block
end
@@ -1073,7 +1073,7 @@ describe "Block inference" do
class Foo(T)
end
def foo(&block : -> Foo(T))
def foo(&block : -> Foo(T)) forall T
block
T
end
9 changes: 5 additions & 4 deletions spec/compiler/semantic/class_spec.cr
Original file line number Diff line number Diff line change
@@ -1043,11 +1043,12 @@ describe "Semantic: class" do
"Moo is not a class, it's a module"
end

it "disallows using free-var name for top-level type" do
assert_error %(
it "can use short name for top-level type" do
assert_type(%(
class T
end
),
"can't use T as a top-level type name: it's reserved for type arguments and free variables"
T.new
)) { types["T"] }
end
end
8 changes: 4 additions & 4 deletions spec/compiler/semantic/closure_spec.cr
Original file line number Diff line number Diff line change
@@ -339,7 +339,7 @@ describe "Semantic: closure" do

it "transforms block to proc literal with free var" do
assert_type("
def foo(&block : Int32 -> U)
def foo(&block : Int32 -> U) forall U
block.call(1)
end
@@ -351,7 +351,7 @@ describe "Semantic: closure" do

it "transforms block to proc literal without arguments" do
assert_type("
def foo(&block : -> U)
def foo(&block : -> U) forall U
block.call
end
@@ -376,7 +376,7 @@ describe "Semantic: closure" do

it "allows giving less block args when transforming block to proc literal" do
assert_type("
def foo(&block : Int32 -> U)
def foo(&block : Int32 -> U) forall U
block.call(1)
end
@@ -430,7 +430,7 @@ describe "Semantic: closure" do
it "lookups return type in correct scope" do
assert_type("
module Mod
def foo(&block : Int32 -> T)
def foo(&block : Int32 -> T) forall T
block
end
end
2 changes: 1 addition & 1 deletion spec/compiler/semantic/const_spec.cr
Original file line number Diff line number Diff line change
@@ -107,7 +107,7 @@ describe "Semantic: const" do
FOO = 'a'
end
def foo(x : U)
def foo(x : U) forall U
U::FOO
end
26 changes: 13 additions & 13 deletions spec/compiler/semantic/def_overload_spec.cr
Original file line number Diff line number Diff line change
@@ -223,7 +223,7 @@ describe "Semantic: def overload" do
it "matches types with free variables" do
assert_type("
require \"prelude\"
def foo(x : Array(T), y : T)
def foo(x : Array(T), y : T) forall T
1
end
@@ -280,7 +280,7 @@ describe "Semantic: def overload" do
class Foo(T)
end
def foo(x : T)
def foo(x : T) forall T
Foo(T).new
end
@@ -308,7 +308,7 @@ describe "Semantic: def overload" do
alias FooAlias = Foo
def foo(x : FooAlias(T))
def foo(x : FooAlias(T)) forall T
1
end
@@ -424,7 +424,7 @@ describe "Semantic: def overload" do

it "restrict virtual type with virtual type" do
assert_type("
def foo(x : T, y : T)
def foo(x : T, y : T) forall T
1
end
@@ -444,7 +444,7 @@ describe "Semantic: def overload" do
class Foo(T)
end
def foo(x : Foo(T))
def foo(x : Foo(T)) forall T
1
end
@@ -547,7 +547,7 @@ describe "Semantic: def overload" do

it "gets free variable from union restriction" do
assert_type("
def foo(x : Nil | U)
def foo(x : Nil | U) forall U
U
end
@@ -557,7 +557,7 @@ describe "Semantic: def overload" do

it "gets free variable from union restriction (2)" do
assert_type("
def foo(x : Nil | U)
def foo(x : Nil | U) forall U
U
end
@@ -567,7 +567,7 @@ describe "Semantic: def overload" do

it "gets free variable from union restriction without a union" do
assert_type("
def foo(x : Nil | U)
def foo(x : Nil | U) forall U
U
end
@@ -601,7 +601,7 @@ describe "Semantic: def overload" do
include Bar(Int32)
end
def foo(x : Bar(T))
def foo(x : Bar(T)) forall T
T
end
@@ -618,7 +618,7 @@ describe "Semantic: def overload" do
include Bar(T)
end
def foo(x : Bar(T))
def foo(x : Bar(T)) forall T
T
end
@@ -659,11 +659,11 @@ describe "Semantic: def overload" do

it "matches tuples of different sizes" do
assert_type("
def foo(x : {X, Y})
def foo(x : {X, Y}) forall X, Y
1
end
def foo(x : {X, Y, Z})
def foo(x : {X, Y, Z}) forall X, Y, Z
'a'
end
@@ -674,7 +674,7 @@ describe "Semantic: def overload" do

it "matches tuples and uses free var" do
assert_type("
def foo(x : {X, Y})
def foo(x : {X, Y}) forall X, Y
Y
end
Loading