Nowadays the error message is:

$ perl6 -e 'subset UInt of Int where * >= 0; sub foo (UInt $bar?) { }; foo()'
Invocant requires an instance of type Int, but a type object was passed.  Did 
you forget a .new?
  in block <unit> at -e:1

I did some reading and it looks like this is not a bug after all. From S06: 
"Missing optional arguments default to their default values, or to an undefined 
value if they have no default." In this case $bar defaults to (Int) and the 
type check is applied to this default value. Therefore the where clause is 
comparing a type object to 0, like so:

$ perl6 -e 'say Int >= 0'
Invocant requires an instance of type Int, but a type object was passed.  Did 
you forget a .new?
  in block <unit> at -e:1

I've found two older tickets for the same problem (both rejected with 'not a 
bug'):

* https://rt.perl.org/Ticket/Display.html?id=76514

* https://rt.perl.org/Ticket/Display.html?id=109182

In both tickets it is argued that type checks apply to default values as well. 
To prevent the above failure one could either provide a defined default value 
or check for an undefined value in the constraint:

$ perl6 -e 'subset UInt of Int where * >= 0; sub foo (UInt $bar? = 0) { say 
"hi" }; foo()'
hi

$ perl6 -e 'subset UInt of Int where !.defined || * >= 0; sub foo (UInt $bar?) 
{ say "hi" }; foo()'
hi

I'm rejecting this ticket. Please reopen if you don't agree with the above 
reasoning.

Reply via email to