indeed tells the compiler that $my should be a My object. This information is not used for type-checking, however (neither at run-time nor at compile time). It is currently only used to make use of the fields
pragma, which lets you define your class' fields:

In addition to checking the spelling of field names, you
get the improved performance of having the hash access turned
into an array/pseudo-hash access (On the other hand,
pseudo-hashes seem to be evil, the docs warn about their imminent removal from Perl).

On the other hand, pseudo-hashes seem to be evil, the docs warn about their imminent removal from Perl

They have been removed from 5.10. On the other hand, 5.10 adds support for field hashes, which in turn are used for Inside Out objects, which is what all the cool kids are using these days.

The main thing to remember about field hashes, if you haven't heard about them, is that they allow references to be used as hash keys in an efficient manner. (Yes, there are modules that let you do this already, but the performance stinks).

Assigning the Foo object $foo to a lexical my My $bar makes it into a My object. Or it seems to do so;
the object's body still is an array reference blessed into package Foo, while its fields seem to be of the My package.
But then, the 'My' package didnn' import field 'foo'...? Scary stuff, that, great for obfus and to annoy your cow-orkers and maintainers, and for writing hard to spot bugs...