You've shown that it works with both a do-end block and a curly-brace block, but what if the user passes both?  Which block should win?  I think the curly brace block should win (since technically, the do...end block is being passed to `to`, and the curly brace block is being passed to `have_received`).  It would be good to add a spec for that to ensure you got that behavior correct.  Example:

https://github.com/rspec/rspec-mocks/blob/6770f2f4fb43f4c1133b7c78810afcb4256bbbf4/spec/rspec/mocks/matchers/receive_spec.rb#L40-L47