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: 67ad92847432
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: d81c32c07284
Choose a head ref
  • 3 commits
  • 6 files changed
  • 1 contributor

Commits on Sep 16, 2016

  1. Compiler: fixed wrong multiple binding of free variable

    Ary Borenszweig committed Sep 16, 2016
    Copy the full SHA
    6e8f4fa View commit details
  2. Copy the full SHA
    5e94bf7 View commit details
  3. Updated Changelog

    Ary Borenszweig committed Sep 16, 2016
    2
    Copy the full SHA
    d81c32c View commit details
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
## 0.19.2 (16-09-2016)

* Generic type variables no longer need to be single-letter names (for example `class Gen(Foo)` is now possible)
* Added syntax to denote free variables: `def foo(x : T) forall T`. The old rule of single-letter name still applies but will be removed in the future.
* Removed the restriction that top-level types and constants can't have single-letter names
* Added `@[Extern]` attribute to mark regular Crystal structs as being able to be used in C bindings
* Faster `Char#to_s` when it's ASCII: this improves the performance of JSON and CSV parsing
* `crystal spec`: allow passing `--release` and other options
* `crystal spec`: allow running all specs in a given directory
* `crystal playground`: support custom workbook resources (thanks @bcardiff)
* `crystal playground`: standard output now understands ANSI colors (thanks @bcardiff)
* Added many more macro methods to traverse AST nodes (thanks @BlaXpirit)
* Error messages no longer include a type trace by default, pass `--error-trace` to show the full trace (the trace is often useless and makes it harder to understand error messages)
* [Several bug fixes](https://github.com/crystal-lang/crystal/issues?q=is%3Aclosed+milestone%3A0.19.2)

## 0.19.1 (09-09-2016)

* Types (class, module, etc.) can now be marked as `private`.
23 changes: 23 additions & 0 deletions spec/compiler/semantic/def_overload_spec.cr
Original file line number Diff line number Diff line change
@@ -921,4 +921,27 @@ describe "Semantic: def overload" do
{foo(1), foo(nil)}
)) { tuple_of([char, bool]) }
end

it "errors when binding free variable to different types" do
assert_error %(
def foo(x : T, y : T) forall T
end
foo(1, 'a')
),
"no overload matches"
end

it "errors when binding free variable to different types (2)" do
assert_error %(
class Gen(T)
end
def foo(x : T, y : Gen(T)) forall T
end
foo(1, Gen(Char).new)
),
"no overload matches"
end
end
10 changes: 10 additions & 0 deletions spec/compiler/semantic/macro_spec.cr
Original file line number Diff line number Diff line change
@@ -908,4 +908,14 @@ describe "Semantic: macro" do
->{ foo }.call
)) { int32 }
end

it "finds var in proc for macros" do
assert_type(%(
macro foo(x)
{{x}}
end
->(x : Int32) { foo(x) }.call(1)
)) { int32 }
end
end
5 changes: 5 additions & 0 deletions src/compiler/crystal/semantic/match.cr
Original file line number Diff line number Diff line change
@@ -63,6 +63,11 @@ module Crystal
free_vars[name] = type
end

def has_def_free_var?(name)
return false if get_free_var(name)
!!(@def_free_vars.try &.includes?(name))
end

# Returns the type that corresponds to using `self` when looking
# a type relative to this context.
#
4 changes: 2 additions & 2 deletions src/compiler/crystal/semantic/restrictions.cr
Original file line number Diff line number Diff line change
@@ -347,7 +347,7 @@ module Crystal
single_name = other.names.size == 1
if single_name
first_name = other.names.first
if context.def_free_vars.try(&.includes?(first_name))
if context.has_def_free_var?(first_name)
return context.set_free_var(first_name, self)
end
end
@@ -835,7 +835,7 @@ module Crystal
single_name = other.names.size == 1
if single_name
first_name = other.names.first
if context.def_free_vars.try(&.includes?(first_name))
if context.has_def_free_var?(first_name)
return context.set_free_var(first_name, self)
end
end
12 changes: 12 additions & 0 deletions src/compiler/crystal/semantic/top_level_visitor.cr
Original file line number Diff line number Diff line change
@@ -642,7 +642,19 @@ class Crystal::TopLevelVisitor < Crystal::SemanticVisitor
end

def visit(node : ProcLiteral)
old_vars_keys = @vars.keys

node.def.args.each do |arg|
@vars[arg.name] = MetaVar.new(arg.name)
end

node.def.body.accept self

# Now remove these vars, but only if they weren't vars before
node.def.args.each do |arg|
@vars.delete(arg.name) unless old_vars_keys.includes?(arg.name)
end

false
end