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: 1fff36dfdba6
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: 26abbe9f2b4c
Choose a head ref
  • 2 commits
  • 3 files changed
  • 1 contributor

Commits on Sep 22, 2016

  1. Missing function LibGC.size

    Ary Borenszweig committed Sep 22, 2016
    Copy the full SHA
    85f99ae View commit details
  2. 1
    Copy the full SHA
    26abbe9 View commit details
Showing with 31 additions and 2 deletions.
  1. +14 −0 spec/compiler/semantic/block_spec.cr
  2. +15 −2 src/compiler/crystal/semantic/main_visitor.cr
  3. +2 −0 src/gc/boehm.cr
14 changes: 14 additions & 0 deletions spec/compiler/semantic/block_spec.cr
Original file line number Diff line number Diff line change
@@ -1331,4 +1331,18 @@ describe "Block inference" do
Foo.new(1).foo { |x| {x, x} }
)) { tuple_of([tuple_of([int32, int32]), tuple_of([int32, int32]).metaclass]) }
end

it "correctly types unpacked tuple block arg after block (#3339)" do
assert_type(%(
def foo
yield({""})
end
i = 1
foo do |(i)|
end
i
), inject_primitives: false) { int32 }
end
end
17 changes: 15 additions & 2 deletions src/compiler/crystal/semantic/main_visitor.cr
Original file line number Diff line number Diff line change
@@ -888,19 +888,29 @@ module Crystal
arg_counter = 0
body_exps = node.body.as?(Expressions).try(&.expressions)

# Variables that we don't want to get their type merged
# with local variables before the block occurrence:
# mainly block arguments (locally override vars), but
# also block arguments that result from tuple unpacking
# that the parser currently generated as local assignments.
ignored_vars_after_block = nil

meta_vars = @meta_vars.dup
node.args.each do |arg|
# The parser generates __argN block arguments for tuple unpacking,
# and they need a special treatment because they shouldn't override
# local variables. So we search the unpacked vars in the body.
if arg.name.starts_with?("__arg") && body_exps
ignored_vars_after_block = node.args.dup

while arg_counter < body_exps.size &&
(assign = body_exps[arg_counter]).is_a?(Assign) &&
(target = assign.target).is_a?(Var) &&
(call = assign.value).is_a?(Call) &&
(call_var = call.obj).is_a?(Var) &&
call_var.name == arg.name
bind_block_var(node, target, meta_vars, before_block_vars)
ignored_vars_after_block << Var.new(target.name)
arg_counter += 1
end
end
@@ -934,8 +944,9 @@ module Crystal
@block_nest -= 1

# Check re-assigned variables and bind them.
bind_vars block_visitor.vars, node.vars
bind_vars block_visitor.vars, node.after_vars, node.args
ignored_vars_after_block ||= node.args
bind_vars block_visitor.vars, node.vars, ignored_vars_after_block
bind_vars block_visitor.vars, node.after_vars, ignored_vars_after_block

# Special vars, even if only assigned inside a block,
# must be inside the def's metavars.
@@ -949,6 +960,8 @@ module Crystal

node.bind_to node.body

# pp node, @vars

false
end

2 changes: 2 additions & 0 deletions src/gc/boehm.cr
Original file line number Diff line number Diff line change
@@ -50,6 +50,8 @@ lib LibGC
# GC_on_collection_event isn't exported. Can't collect totals without it.
# bytes_allocd, heap_size, unmapped_bytes are macros

fun size = GC_size(addr : Void*) : LibC::SizeT

# Boehm GC requires to use GC_pthread_create and GC_pthread_join instead of pthread_create and pthread_join
fun pthread_create = GC_pthread_create(thread : LibC::PthreadT*, attr : Void*, start : Void* ->, arg : Void*) : LibC::Int
fun pthread_join = GC_pthread_join(thread : LibC::PthreadT, value : Void**) : LibC::Int