Skip to content

Commit f4cb617

Browse files
maxfierkeRX14
authored andcommittedAug 31, 2017
Don't mark ivar as nilable if super present and non-nilable (#4863)
If initialize calls super and declares instance var that has already been typed as non-nilable by an ancestor, it'll be non-nilable in the child class. Fixes #4764
1 parent 280e822 commit f4cb617

File tree

2 files changed

+23
-0
lines changed

2 files changed

+23
-0
lines changed
 

Diff for: ‎spec/compiler/semantic/initialize_spec.cr

+19
Original file line numberDiff line numberDiff line change
@@ -731,4 +731,23 @@ describe "Semantic: initialize" do
731731
),
732732
"no argument named 'x'"
733733
end
734+
735+
it "doesn't type ivar as nilable if super call present and parent has already typed ivar (#4764)" do
736+
assert_type(%(
737+
class Foo
738+
def initialize(@a = 1)
739+
end
740+
end
741+
742+
class Bar < Foo
743+
def initialize
744+
super
745+
end
746+
def initialize(@a)
747+
end
748+
end
749+
750+
Bar.new
751+
)) { types["Bar"] }
752+
end
734753
end

Diff for: ‎src/compiler/crystal/semantic/type_declaration_processor.cr

+4
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,10 @@ struct Crystal::TypeDeclarationProcessor
498498
# It's non-nilable if it's initialized outside
499499
next if initialized_outside?(owner, instance_var)
500500

501+
# If an initialize with an ivar calls super and an ancestor has already
502+
# typed the instance var as non-nilable
503+
next if info.def.calls_super? && ancestor_non_nilable.try(&.includes?(instance_var))
504+
501505
unless info.try(&.instance_vars.try(&.includes?(instance_var)))
502506
all_assigned = false
503507
# Rememebr that this variable wasn't initialized here, and later error

0 commit comments

Comments
 (0)
Please sign in to comment.