From 1a70bfadfc3ab8fcb6793692d72f17b0fa7c4d0c Mon Sep 17 00:00:00 2001 From: Collided Scope <75840710+collidedscope@users.noreply.github.com> Date: Fri, 14 May 2021 20:26:20 -0400 Subject: [PATCH 1/3] Preserve integer sizes in `NumberLiteral#int_bin_op` --- src/compiler/crystal/macros/methods.cr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/crystal/macros/methods.cr b/src/compiler/crystal/macros/methods.cr index 36ef41f37e6d..7b88339a6d35 100644 --- a/src/compiler/crystal/macros/methods.cr +++ b/src/compiler/crystal/macros/methods.cr @@ -530,7 +530,7 @@ module Crystal raise "argument to NumberLiteral##{op} can't be float literal: #{self}" end - yield me.to_i, other.to_i + yield me.as(Int), other.as(Int) end) end From 95c5fc060bb20c7bfa750d6dd30bed8234407cc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20M=C3=BCller?= Date: Wed, 9 Jun 2021 14:00:13 +0200 Subject: [PATCH 2/3] Add spec for fix --- spec/compiler/macro/macro_methods_spec.cr | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/spec/compiler/macro/macro_methods_spec.cr b/spec/compiler/macro/macro_methods_spec.cr index c60be8566a65..657a6e4c2b71 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 From 837c913071af66b0b3ed62f1c98550b60bbe4e43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20M=C3=BCller?= Date: Wed, 9 Jun 2021 14:00:28 +0200 Subject: [PATCH 3/3] Refactor int_bin_op for inherent type safety --- src/compiler/crystal/macros/methods.cr | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/compiler/crystal/macros/methods.cr b/src/compiler/crystal/macros/methods.cr index 7b88339a6d35..1bdee6ad8030 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.as(Int), other.as(Int) - end) + NumberLiteral.new result end def bin_op(op, args)