The reason is that the JLS #5.2 (Assignment conversion) says so:
If the expression is a constant expression (§15.28) of type byte, short, char, or int, a narrowing primitive conversion may be used if the type of the variable is byte, short, or char, and the value of the constant expression is representable in the type of the variable.
In your example, char c = 'c';
is not a constant but final char c = 'c';
is.
The rationale is probably that the addition operator +
first converts its operands to integers. So the operation could overflow unless everything is constant in which case the compiler can prove that there is no overflow.