Skip Menu |
Report information
Id: 129844
Status: new
Priority: 0/
Queue: perl6

Owner: Nobody
Requestors: zoffix [at] zoffix.com
Cc:
AdminCc:

Severity: (no value)
Tag: Bug
Platform: (no value)
Patch Status: (no value)
VM: (no value)



Date: Mon, 10 Oct 2016 09:22:35 -0400
Subject: [BUG] literals and boxed types do not get unboxed for native types in multies
To: rakudobug [...] perl.org
From: zoffix [...] zoffix.com
Download (untitled) / with headers
text/plain 3.7k
We can use a literal numeral or an Int with a sub that takes a native: <Zoffix> m: sub foo (int) { say "OK!" }; foo 2 <camelia> rakudo-moar d03459: OUTPUT«OK!␤» <Zoffix> m: sub foo (int) { say "OK!" }; my Int $x = 2; foo $x <camelia> rakudo-moar d03459: OUTPUT«OK!␤» But, such auto-unboxing doesn't work if we use a multi instead: <Zoffix> m: multi foo (int) { say "OK!" }; foo 2 <camelia> rakudo-moar d03459: OUTPUT«Cannot resolve caller foo(Int); none of these signatures match:␤ (int)␤ in block <unit> at <tmp> line 1␤␤» <Zoffix> m: multi foo (int) { say "OK!" }; my Int $x = 2; foo $x <camelia> rakudo-moar d03459: OUTPUT«Cannot resolve caller foo(Int); none of these signatures match:␤ (int)␤ in block <unit> at <tmp> line 1␤␤» Even though auto-boxing for natives works regardless of whether we have a multi: <Zoffix> m: sub foo (Int) { say "OK!" }; my int $x = 2; foo $x <camelia> rakudo-moar d03459: OUTPUT«OK!␤» <Zoffix> m: multi foo (Int) { say "OK!" }; my int $x = 2; foo $x <camelia> rakudo-moar d03459: OUTPUT«OK!␤» I found this bug while out on a hunt for another one, and it looks like the solutions might be very similar, so I'm filing this with a tentative "leave it with me." As part of this issue and the one I'm resolving, I had to write out a list of rules of how literals, natives, and their related types behave in multi resolution: (I describe int/Int, but same applies for other natives that have a boxed Perl 6 equivalent): 0) Literal: treat as Int 1) Int: 1.1) Use as Int, if have candidate 1.2) Use as native, if: 1.2.1) have native candidate 1.2.2) size fits 2) Native: 2.1) Use as native, if have candidate 2.2) Use as Int, if have candidate And so we have: my int $i = 2; # used in all examples to indicate native int multi foo (int $x) {say "native" }; foo 2; # native; 0 => 1 => 1.2 multi foo (Int $x) {say "other Int" }; foo 2; # other Int; 0 => 1 => 1.1 multi foo (int $x) {say "native" }; foo $i; # native; 2 => 2.1 multi foo (Int $x) {say "other Int" }; foo $i; # other Int; 2 => 2.2 multi foo (int $x) {say "native" }; multi foo (Int $x) {say "other Int" }; foo 2; # other Int; 0 => 1 => 1.1 foo $i; # native; 2 => 2.1 multi foo (int $x) {say "native" }; multi foo (Str $x) {say "other Str" }; foo 2; # native; 0 => 1 => 1.2 foo $i; # native; 2 => 2.1 multi foo (Int $x) {say "other Int" }; multi foo (Str $x) {say "other Str" }; foo 2; # other Int; 0 => 1 => 1.1 foo $i; # other Int; 2 => 2.2 multi foo (int $x) {say "native" }; multi foo (Int $x) {say "other Int" }; foo 2; # other Int; 0 => 1 => 1.1 foo 2**100; # other Int; 0 => 1 => 1.1 multi foo (int $x) {say "native" }; foo 2; # native; 0 => 1.2 foo 2**100; # X::Multi::NoMatch (no Int candidate); # 0 => 1 => 1.2 => 1.2.2 (fails to match at this point) multi foo (int $x, int $y) {say "native" }; multi foo (Int $x, Int $y) {say "other Int" }; foo 2, $i; # other Int; (0 => 1 => 1.1), (2 => 2.1) foo 2, 2; # other Int; (0 => 1 => 1.1), (0 => 1 => 1.1) foo $i, $i; # native; (2 => 2.1), (2 => 2.1) multi foo (int $x, int $y) {say "native" }; multi foo (Int $x, int $y) {say "Int + native" }; multi foo (Int $x, Int $y) {say "other Int" }; foo 2, $i; # Int + native; (0 => 1 => 1.1), (2 => 2.1) foo 2, 2; # other Int; (0 => 1 => 1.1), (0 => 1 => 1.1) foo $i, $i; # native; (2 => 2.1), (2 => 2.1)


This service is sponsored and maintained by Best Practical Solutions and runs on Perl.org infrastructure.

For issues related to this RT instance (aka "perlbug"), please contact perlbug-admin at perl.org