From 6103d5a94c3183b97a001833a958d8e827bf8f7c Mon Sep 17 00:00:00 2001 From: Collided Scope <75840710+collidedscope@users.noreply.github.com> Date: Sun, 13 Jun 2021 16:11:16 -0400 Subject: [PATCH] Preserve integer sizes in `NumberLiteral#int_bin_op` (#10713) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Preserve integer sizes in `NumberLiteral#int_bin_op` * Refactor int_bin_op for inherent type safety Co-authored-by: Johannes Müller --- spec/compiler/macro/macro_methods_spec.cr | 4 ++++ src/compiler/crystal/macros/methods.cr | 17 ++++++++--------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/spec/compiler/macro/macro_methods_spec.cr b/spec/compiler/macro/macro_methods_spec.cr index f4107ffc4c9a..54980d22928d 100644 --- a/spec/compiler/macro/macro_methods_spec.cr +++ b/spec/compiler/macro/macro_methods_spec.cr @@ -213,6 +213,10 @@ module Crystal assert_macro "", "{{5 % 3}}", [] of ASTNode, "2" end + it "preserves integer size (#10713)" do + assert_macro "", "{{ 3000000000u64 % 2 }}", [] of ASTNode, "0_u64" + end + it "executes &" do assert_macro "", "{{5 & 3}}", [] of ASTNode, "1" end diff --git a/src/compiler/crystal/macros/methods.cr b/src/compiler/crystal/macros/methods.cr index 7bfc4dcaf311..8947b1e3cf3f 100644 --- a/src/compiler/crystal/macros/methods.cr +++ b/src/compiler/crystal/macros/methods.cr @@ -520,18 +520,17 @@ module Crystal end def int_bin_op(op, args) - if @kind == :f32 || @kind == :f64 - raise "undefined method '#{op}' for float literal: #{self}" - end - - NumberLiteral.new(bin_op(op, args) do |me, other| - other_kind = args.first.as(NumberLiteral).kind - if other_kind == :f32 || other_kind == :f64 + result = bin_op(op, args) do |me, other| + if me.is_a?(Int) && other.is_a?(Int) + yield me, other + elsif me.is_a?(Float) + raise "undefined method '#{op}' for float literal: #{self}" + else raise "argument to NumberLiteral##{op} can't be float literal: #{self}" end + end - yield me.to_i, other.to_i - end) + NumberLiteral.new result end def bin_op(op, args)