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: 5d3a458a925d
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: da4601605f63
Choose a head ref
  • 3 commits
  • 3 files changed
  • 1 contributor

Commits on May 8, 2018

  1. Copy the full SHA
    249a498 View commit details
  2. Copy the full SHA
    f1ff079 View commit details
  3. Merge pull request #6077 from asterite/bug/initialize-with-type

    Bug: initialize with {% @type %}
    asterite authored May 8, 2018
    Copy the full SHA
    da46016 View commit details
44 changes: 44 additions & 0 deletions spec/compiler/semantic/instance_var_spec.cr
Original file line number Diff line number Diff line change
@@ -4429,6 +4429,21 @@ describe "Semantic: instance var" do
), inject_primitives: false) { types["Foo"] }
end

it "is more permissive with macro def initialize, bug with named args" do
assert_error %(
class Foo
@x : Int32
def initialize(**args)
{% @type %}
end
end
Foo.new(x: 1)
),
"instance variable '@x' of Foo was not initialized"
end

it "is more permissive with macro def initialize, other initialize" do
assert_type(%(
class Foo
@@ -4449,6 +4464,35 @@ describe "Semantic: instance var" do
), inject_primitives: false) { types["Foo"] }
end

it "is more permissive with macro def initialize, multiple" do
assert_type(%(
class Foo
@x : Int32
def initialize
{% begin %}
{% @type %}
@x = 1
{% end %}
end
def initialize(x)
{% begin %}
{% @type %}
@x = x
{% end %}
end
def x
@x
end
end
Foo.new
Foo.new(1).x
)) { int32 }
end

it "errors with macro def but another def doesn't initialize all" do
assert_error %(
class Foo
5 changes: 4 additions & 1 deletion src/compiler/crystal/semantic/main_visitor.cr
Original file line number Diff line number Diff line change
@@ -116,7 +116,10 @@ module Crystal
@while_stack = [] of While
@needs_type_filters = 0
@typeof_nest = 0
@is_initialize = !!(typed_def && typed_def.name == "initialize")
@is_initialize = !!(typed_def && (
typed_def.name == "initialize" ||
typed_def.name.starts_with?("initialize:") # Because of expanded methods from named args
))
@found_self_in_initialize_call = nil
@used_ivars_in_calls_in_initialize = nil
@in_is_a = false
4 changes: 2 additions & 2 deletions src/compiler/crystal/semantic/type_declaration_processor.cr
Original file line number Diff line number Diff line change
@@ -108,7 +108,7 @@ struct Crystal::TypeDeclarationProcessor
# removed if an explicit type is found (in remove_error).
@errors = {} of Type => Hash(String, Error)

# Types that have a single macro def initialize
# Types whose initialize methods are all macro defs
@has_macro_def = Set(Type).new

@type_decl_visitor = TypeDeclarationVisitor.new(@program, @explicit_instance_vars)
@@ -417,7 +417,7 @@ struct Crystal::TypeDeclarationProcessor
infos = find_initialize_infos(owner)

if infos
@has_macro_def << owner if infos.size == 1 && infos.first.def.macro_def?
@has_macro_def << owner if infos.all?(&.def.macro_def?)
non_nilable = compute_non_nilable_instance_vars_multi(owner, infos)
end