diff --git a/samples/tree.cr b/samples/tree.cr
index 5ab1ccfc51a242e47871fd469c8f0d9475d30288..63edd3e63b579048482c7713517cb7c99fd22d51 100644
--- a/samples/tree.cr
+++ b/samples/tree.cr
@@ -5,14 +5,14 @@ class Node
 
   def add(x)
     if x < @value
-      if @left
-        @left.add(x)
+      if left = @left
+        left.add(x)
       else
         @left = Node.new(x)
       end
     else
-      if @right
-        @right.add(x)
+      if right = @right
+        right.add(x)
       else
         @right = Node.new(x)
       end
@@ -20,9 +20,9 @@ class Node
   end
 
   def print
-    @left.print if @left
+    @left.try &.print
     print @value
-    @right.print if @right
+    @right.try &.print
   end
 end
 
diff --git a/spec/compiler/codegen/void_spec.cr b/spec/compiler/codegen/void_spec.cr
index 4747edbe4e2618550443d2c5540a16c1f7f08bf5..75c643b5378f0fb8dc6538edfb2d449c01ce316c 100644
--- a/spec/compiler/codegen/void_spec.cr
+++ b/spec/compiler/codegen/void_spec.cr
@@ -55,4 +55,13 @@ describe "Code gen: void" do
       1
       ").to_i.should eq(1)
   end
+
+  it "codegens unreachable code" do
+    run(%(
+      a = nil
+      if a
+        b = a.foo
+      end
+      ))
+  end
 end
diff --git a/src/compiler/crystal/ast.cr b/src/compiler/crystal/ast.cr
index 822894ab07cead41e8e8832fcb3b5db396891b7c..e1cb52c6416381769f89de3d19b2ecaf432bb70e 100644
--- a/src/compiler/crystal/ast.cr
+++ b/src/compiler/crystal/ast.cr
@@ -27,7 +27,7 @@ module Crystal
     end
 
     def name_column_number
-      @location ? @location.column_number : nil
+      @location.try &.column_number
     end
 
     def name_length
@@ -780,8 +780,8 @@ module Crystal
     end
 
     def accept_children(visitor)
-      @default_value.accept visitor if @default_value
-      @restriction.accept visitor if @restriction
+      @default_value.try &.accept visitor
+      @restriction.try &.accept visitor
     end
 
     def ==(other : self)
@@ -878,10 +878,10 @@ module Crystal
     end
 
     def accept_children(visitor)
-      @receiver.accept visitor if @receiver
+      @receiver.try &.accept visitor
       @args.each { |arg| arg.accept visitor }
       @body.accept visitor
-      @block_arg.accept visitor if @block_arg
+      @block_arg.try &.accept visitor
     end
 
     def ==(other : self)
diff --git a/src/compiler/crystal/codegen.cr b/src/compiler/crystal/codegen.cr
index 7a5f2e4e32c8bde0f7ad31d00bc85b46ad61e4f3..d73658474187679fd416f05c7e19d23d08d6a0d0 100644
--- a/src/compiler/crystal/codegen.cr
+++ b/src/compiler/crystal/codegen.cr
@@ -1886,7 +1886,12 @@ module Crystal
           new_entry_block
 
           setup_closure_context target_def, is_closure
-          alloca_vars target_def.vars
+          begin
+            alloca_vars target_def.vars
+          rescue ex
+            puts mangled_name
+            raise ex
+          end
           create_local_copy_of_fun_args(target_def, self_type, args)
 
           context.return_type = target_def.type?
@@ -2490,15 +2495,17 @@ module Crystal
         vars.each do |name, var|
           next if name == "self" || context.vars[name]?
 
-          if var.type.void?
+          var_type = var.type? || @mod.nil
+
+          if var_type.void?
             context.vars[name] = LLVMVar.new(llvm_nil, @mod.void)
           else
-            ptr = @builder.alloca llvm_type(var.type), name
-            context.vars[name] = LLVMVar.new(ptr, var.type)
+            ptr = @builder.alloca llvm_type(var_type), name
+            context.vars[name] = LLVMVar.new(ptr, var_type)
 
             # Assign default nil for variables that are bound to the nil variable
             if var.dependencies.any? &.same?(@mod.nil_var)
-              assign ptr, var.type, @mod.nil, llvm_nil
+              assign ptr, var_type, @mod.nil, llvm_nil
             end
           end
         end
diff --git a/src/compiler/crystal/exception.cr b/src/compiler/crystal/exception.cr
index d193a5bf9e6e8514bd459031fcaa087171c2fa38..14bd0e5c571f1b72975cc290264decb2406e2562 100644
--- a/src/compiler/crystal/exception.cr
+++ b/src/compiler/crystal/exception.cr
@@ -127,7 +127,7 @@ module Crystal
         str << msg
       end
 
-      if lines && @line && (line = lines[@line - 1]?)
+      if lines && (line_number = @line) && (line = lines[line_number - 1]?)
         str << "\n\n"
         str << line.chomp
         str << "\n"
@@ -161,8 +161,8 @@ module Crystal
     end
 
     def deepest_error_message
-      if @inner
-        @inner.deepest_error_message
+      if inner = @inner
+        inner.deepest_error_message
       else
         @message
       end
diff --git a/src/compiler/crystal/type_inference/after_type_inference_transformer.cr b/src/compiler/crystal/type_inference/after_type_inference_transformer.cr
index 5b4bb310ccfd7d634f5c39c440a781db6a08ef8f..edc9e82896cd4783bf7fa67c82d950e14b5f8f90 100644
--- a/src/compiler/crystal/type_inference/after_type_inference_transformer.cr
+++ b/src/compiler/crystal/type_inference/after_type_inference_transformer.cr
@@ -237,27 +237,28 @@ module Crystal
     def transform(node : If)
       node.cond = node.cond.transform(self)
 
-      if node.cond.true_literal?
+      node_cond = node.cond
+
+      if node_cond.true_literal?
         node.then = node.then.transform(self)
         rebind_node node, node.then
         return node.then
       end
 
-      if node.cond.false_literal?
+      if node_cond.false_literal?
         node.else = node.else.transform(self)
         rebind_node node, node.else
         return node.else
       end
 
-      node.then = node.then.transform(self)
-      node.else = node.else.transform(self)
-
-      node_cond = node.cond
-
       if (cond_type = node_cond.type?) && cond_type.nil_type?
+        node.else = node.else.transform(self)
         return replace_if_with_branch(node, node.else)
       end
 
+      node.then = node.then.transform(self)
+      node.else = node.else.transform(self)
+
       if node_cond.is_a?(Assign)
         if node_cond.value.true_literal?
           return replace_if_with_branch(node, node.then)
diff --git a/src/compiler/crystal/types.cr b/src/compiler/crystal/types.cr
index 36e3763215f1c2a217679abf5b2503a0d8d1281f..bd61320228df93733fd0c9ea8d848f92629eedce 100644
--- a/src/compiler/crystal/types.cr
+++ b/src/compiler/crystal/types.cr
@@ -737,7 +737,7 @@ module Crystal
     def add_subclass(subclass)
       subclasses << subclass
       notify_subclass_added
-      @superclass.notify_subclass_added if @superclass
+      @superclass.try &.notify_subclass_added
     end
 
     def add_subclass_observer(observer)
@@ -792,7 +792,7 @@ module Crystal
     end
 
     def force_add_subclass
-      @superclass.add_subclass(self) if @superclass
+      @superclass.try &.add_subclass(self)
     end
 
     def all_subclasses
@@ -1235,8 +1235,8 @@ module Crystal
     end
 
     def declare_instance_var(name, node)
-      @declared_instance_vars ||= {} of String => ASTNode
-      @declared_instance_vars[name] = node
+      declared_instance_vars = (@declared_instance_vars ||= {} of String => ASTNode)
+      declared_instance_vars[name] = node
 
       generic_types.each do |key, instance|
         instance = instance as GenericClassInstanceType