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

Interpreter: implement variable autocast #12563

Merged
merged 2 commits into from
Oct 4, 2022
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions spec/compiler/interpreter/autocast_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -102,5 +102,38 @@ describe Crystal::Repl::Interpreter do
foo.color.value
CODE
end

it "autocasts integer var to integer (#12560)" do
interpret(<<-CODE).should eq(1)
def foo(x : Int64)
x
end

x = 1_i32
foo(x)
CODE
end

it "autocasts integer var to float (#12560)" do
interpret(<<-CODE).should eq(1)
def foo(x : Float64)
x
end

x = 1_i32
foo(x)
CODE
end

it "autocasts float32 var to float64 (#12560)" do
interpret(<<-CODE).should eq(1)
def foo(x : Float64)
x
end

x = 1.0_f32
foo(x)
CODE
end
end
end
11 changes: 8 additions & 3 deletions src/compiler/crystal/interpreter/compiler.cr
Original file line number Diff line number Diff line change
Expand Up @@ -2341,9 +2341,14 @@ class Crystal::Repl::Compiler < Crystal::Visitor

request_value(arg)

# We first cast the argument to the def's arg type,
# which is the external methods' type.
downcast arg, arg_type, target_def_arg_type
# Check number autocast but for non-literals
if arg_type != target_def_arg_type && arg_type.is_a?(IntegerType | FloatType) && target_def_arg_type.is_a?(IntegerType | FloatType)
primitive_convert(arg, arg_type, target_def_arg_type, checked: false)
else
# We first cast the argument to the def's arg type,
# which is the external methods' type.
downcast arg, arg_type, target_def_arg_type
end

# Then we need to cast the argument to the target_def variable
# corresponding to the argument. If for example we have this:
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/crystal/interpreter/primitives.cr
Original file line number Diff line number Diff line change
Expand Up @@ -646,7 +646,7 @@ class Crystal::Repl::Compiler
to_kind = integer_or_float_kind(to_type)

unless from_kind && to_kind
node.raise "BUG: missing handling of unchecked_convert for #{from_type} (#{node.name})"
node.raise "BUG: missing handling of unchecked_convert for #{from_type} (#{node})"
end

primitive_convert(node, from_kind, to_kind, checked: checked)
Expand Down