Skip to content

Commit

Permalink
Showing 6 changed files with 52 additions and 21 deletions.
2 changes: 1 addition & 1 deletion etc/completion.bash
Original file line number Diff line number Diff line change
@@ -14,7 +14,7 @@ _crystal()
local cur="${COMP_WORDS[COMP_CWORD]}"
local prev="${COMP_WORDS[COMP_CWORD-1]}"

commands="init compile deps docs eval play run spec tool help version --help --version"
commands="init build deps docs eval play run spec tool help version --help --version"

case "${cmd}" in
init)
4 changes: 2 additions & 2 deletions spec/compiler/compiler_spec.cr
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@ describe "Compiler" do
tempfile = Tempfile.new "compiler_spec_output"
tempfile.close

Crystal::Command.run ["compile", "#{__DIR__}/data/compiler_sample", "-o", tempfile.path]
Crystal::Command.run ["build", "#{__DIR__}/data/compiler_sample", "-o", tempfile.path]

File.exists?(tempfile.path).should be_true

@@ -18,7 +18,7 @@ describe "Compiler" do
tempfile = Tempfile.new "compiler_spec_output"
tempfile.close

Crystal::Command.run ["compile", "#{__DIR__}/data/compiler_sample", "-o", tempfile.path]
Crystal::Command.run ["build", "#{__DIR__}/data/compiler_sample", "-o", tempfile.path]

File.exists?(tempfile.path).should be_true

37 changes: 28 additions & 9 deletions spec/compiler/type_inference/uninitialized_spec.cr
Original file line number Diff line number Diff line change
@@ -25,15 +25,6 @@ describe "Type inference: uninitialized" do
") { int32 }
end

it "errors if using uninitialize for instance var outside method" do
assert_error %(
class Foo
@a = uninitialized Int32
end
),
"can't uninitialize instance variable outside method"
end

it "errors if declaring generic type without type vars (with instance var)" do
assert_error %(
class Foo(T)
@@ -69,6 +60,34 @@ describe "Type inference: uninitialized" do
"variable 'buf' already declared with type Int32"
end

it "can uninitialize variable outside initialize (#2828)" do
assert_type(%(
class Foo
@x = uninitialized Int32
def x
@x
end
end
Foo.new.x
)) { int32 }
end

it "can uninitialize variable outside initialize, generic (#2828)" do
assert_type(%(
class Foo(T)
@x = uninitialized T
def x
@x
end
end
Foo(Int32).new.x
)) { int32 }
end

%w(Object Value Reference Number Int Float Struct Class Enum).each do |type|
it "disallows declaring var of type #{type}" do
assert_error %(
16 changes: 8 additions & 8 deletions src/compiler/crystal/command.cr
Original file line number Diff line number Diff line change
@@ -7,14 +7,14 @@ class Crystal::Command
Command:
init generate a new project
compile compile program
build build an executable
deps install project dependencies
docs generate documentation
env print Crystal environment information
eval eval code from args or standard input
play starts crystal playground server
run (default) compile and run program
spec compile and run specs (in spec directory)
run (default) build and run program
spec build and run specs (in spec directory)
tool run a tool
help, --help, -h show this help
version, --version, -v show version
@@ -53,11 +53,11 @@ class Crystal::Command
options.shift
init
when "build".starts_with?(command), "compile".starts_with?(command)
if "build".starts_with?(command)
STDERR.puts "Deprecation: The build command was renamed to compile and will be removed in a future version."
if "compile".starts_with?(command)
STDERR.puts "Deprecation: The compile command was renamed to build and will be removed in a future version."
end
options.shift
compile
build
when "play".starts_with?(command)
options.shift
playground
@@ -155,8 +155,8 @@ class Crystal::Command
Init.run(options)
end

private def compile
config = create_compiler "compile"
private def build
config = create_compiler "build"
config.compile
end

4 changes: 3 additions & 1 deletion src/compiler/crystal/semantic/main_visitor.cr
Original file line number Diff line number Diff line change
@@ -241,7 +241,9 @@ module Crystal
@vars[var.name] = MetaVar.new(var.name, var_type)
end
else
node.raise "can't uninitialize instance variable outside method"
# Already handled in a previous visitor
node.type = @mod.nil
return false
end

case type
10 changes: 10 additions & 0 deletions src/compiler/crystal/semantic/type_guess_visitor.cr
Original file line number Diff line number Diff line change
@@ -377,6 +377,11 @@ module Crystal
end

def process_uninitialized_instance_var_on_non_generic(owner, target, value)
if @outside_def
outside_vars = @instance_vars_outside[owner] ||= [] of String
outside_vars << target.name unless outside_vars.includes?(target.name)
end

# If there is already a type restriction, skip
existing = @explicit_instance_vars[owner]?.try &.[target.name]?
if existing
@@ -393,6 +398,11 @@ module Crystal
end

def process_uninitialized_instance_var_on_generic(owner, target, value)
if @outside_def
outside_vars = @instance_vars_outside[owner] ||= [] of String
outside_vars << target.name unless outside_vars.includes?(target.name)
end

# Skip if the generic class already defines an explicit type
existing = @explicit_instance_vars[owner]?.try &.[target.name]?
if existing

0 comments on commit 855e925

Please sign in to comment.