Consider a scenario where the bean provider accidentally used the same role name that the app assembler has in mind

. Quite common, if you think about it. If that's the case, the spec does not burden the app assembler to put an unnecessary <role-link> with the same <role-name>. That's why the tag is optional even for the app assembler. If you deploy the app without a <role-link>, the container would look for a <security-role> element with a role-name matching the hard-coded role name in the code.
Having said that, it is important to understand one thing. Even if there is a direct match between the hard-coded role name and a <security-role> role name, if there is a <role-link>, the container always goes by the role-link. This makes sense because the app assembler might want to map "Payroll Director" hardcoded by the bean provider to "Payroll Manager" and use "Payroll Director" for something else.
hope this clarifies