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.