Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Explosive birth of automatic casts! #6074

Merged
merged 1 commit into from May 8, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
218 changes: 218 additions & 0 deletions spec/compiler/codegen/automatic_cast.cr
@@ -0,0 +1,218 @@
require "../../spec_helper"

describe "Code gen: automatic cast" do
it "casts literal integer (Int32 -> Int64)" do
run(%(
def foo(x : Int64)
x
end

foo(12345)
)).to_i.should eq(12345)
end

it "casts literal integer (Int64 -> Int32, ok)" do
run(%(
def foo(x : Int32)
x
end

foo(2147483647_i64)
)).to_i.should eq(2147483647)
end

it "casts literal integer (Int32 -> Float32)" do
run(%(
def foo(x : Float32)
x
end

foo(12345).to_i
)).to_i.should eq(12345)
end

it "casts literal integer (Int32 -> Float64)" do
run(%(
def foo(x : Float64)
x
end

foo(12345).to_i
)).to_i.should eq(12345)
end

it "casts literal float (Float32 -> Float64)" do
run(%(
def foo(x : Float64)
x
end

foo(12345.0_f32).to_i
)).to_i.should eq(12345)
end

it "casts literal float (Float64 -> Float32)" do
run(%(
def foo(x : Float32)
x
end

foo(12345.0).to_i
)).to_i.should eq(12345)
end

it "casts symbol literal to enum" do
run(%(
:four

enum Foo
One
Two
Three
end

def foo(x : Foo)
x
end

foo(:three)
)).to_i.should eq(2)
end

it "casts Int32 to Int64 in ivar assignment" do
run(%(
class Foo
@x : Int64

def initialize
@x = 10
end

def x
@x
end
end

Foo.new.x
)).to_i.should eq(10)
end

it "casts Symbol to Enum in ivar assignment" do
run(%(
enum E
One
Two
Three
end

class Foo
@x : E

def initialize
@x = :three
end

def x
@x
end
end

Foo.new.x
)).to_i.should eq(2)
end

it "casts Int32 to Int64 in cvar assignment" do
run(%(
class Foo
@@x : Int64 = 0_i64

def self.x
@@x = 10
@@x
end
end

Foo.x
)).to_i.should eq(10)
end

it "casts Int32 to Int64 in lvar assignment" do
run(%(
x : Int64
x = 123
x
)).to_i.should eq(123)
end

it "casts Int32 to Int64 in ivar type declaration" do
run(%(
class Foo
@x : Int64 = 10

def x
@x
end
end

Foo.new.x
)).to_i.should eq(10)
end

it "casts Symbol to Enum in ivar type declaration" do
run(%(
enum Color
Red
Green
Blue
end

class Foo
@x : Color = :blue

def x
@x
end
end

Foo.new.x
)).to_i.should eq(2)
end

it "casts Int32 to Int64 in cvar type declaration" do
run(%(
class Foo
@@x : Int64 = 10

def self.x
@@x
end
end

Foo.x
)).to_i.should eq(10)
end

it "casts Int32 -> Int64 in arg restriction" do
run(%(
def foo(x : Int64 = 123)
x
end

foo
)).to_i.should eq(123)
end

it "casts Int32 to Int64 in ivar type declaration in generic" do
run(%(
class Foo(T)
@x : T = 10

def x
@x
end
end

Foo(Int64).new.x
)).to_i.should eq(10)
end
end
12 changes: 9 additions & 3 deletions spec/compiler/normalize/def_spec.cr
Expand Up @@ -33,16 +33,22 @@ describe "Normalize: def" do
a_def = parse("def foo(x, y : Int32 = 1, z : Int64 = 2i64); x + y + z; end").as(Def)
actual = a_def.expand_default_arguments(Program.new, 1)
expected = parse("def foo(x); y = 1; z = 2i64; x + y + z; end").as(Def)
expected.body.as(Expressions).expressions.insert 1, TypeRestriction.new Var.new("y"), Path.new(["Int32"])
expected.body.as(Expressions).expressions.insert 3, TypeRestriction.new Var.new("z"), Path.new(["Int64"])

exps = expected.body.as(Expressions).expressions
exps[0] = AssignWithRestriction.new(exps[0].as(Assign), Path.new("Int32"))
exps[1] = AssignWithRestriction.new(exps[1].as(Assign), Path.new("Int64"))

actual.should eq(expected)
end

it "expands a def on request with default arguments and type restrictions (2)" do
a_def = parse("def foo(x, y : Int32 = 1, z : Int64 = 2i64); x + y + z; end").as(Def)
actual = a_def.expand_default_arguments(Program.new, 2)
expected = parse("def foo(x, y : Int32); z = 2i64; x + y + z; end").as(Def)
expected.body.as(Expressions).expressions.insert 1, TypeRestriction.new Var.new("z"), Path.new(["Int64"])

exps = expected.body.as(Expressions).expressions
exps[0] = AssignWithRestriction.new(exps[0].as(Assign), Path.new("Int64"))

actual.should eq(expected)
end

Expand Down