Not a bug, as S04 <https://design.perl6.org/S04.html#line_101> explains:
Blocks are delimited by curlies, or by the beginning and end of the current compilation unit (either the current file or the current EVAL string). Unlike in Perl 5, there are (by policy) no implicit blocks around standard control structures. This means that the `my $foo` in your example isn't scoped to the inside of the loop block, but rather to the parent scope. It's true that this can be a little annoying in the case of `loop`, where (unlike `while/for/if`) the outer lexical variable can't be avoided. But that's the sacrifice that was made in return for greater consistency w.r.t. variable scoping. On the bright side, it is almost never necessary to use the `loop` construct in Perl 6 - usually there's a better way to do the same thing with `for`.