Consider the following arrangement:
interface GenericRepository<T, ID> extends Repository<T, ID> {
<P extends Projection<T>> Optional<P> dynamicBind(Class<P> type);
}
interface ParametrizedRepository extends GenericRepository<User, Long> {}
interface Projection<T> {
}
When comparing the method parameter Class<P> type against the return type definition, then we consider the containing class ParametrizedRepository at the parameter level (#2996) but we do not consider the containing class when introspecing the method return type.
This yields ? as parameter for Optional while the method parameter resolves correctly to Projection<User>. In a second step, we compare inner generics of the return type and therefore, the equality check fails.
While we previously always fell back to ?, fixing #2996 uncovered this bug.