The usual arithmetic conversions do cause the x and the 1 in the implicit x+=1 to be promoted to int before the addition, and the addition is performed in an int. However, since the lvalue that is the left hand operand of the assignment has type char, the result is converted back to char (which, if char is signed and the result is not in the range of char gives an implementation-defined result) and stored in the object designated by the lvalue. The result of the expression is this converted char value.
The important point here is that the result of an assignment expression (including pre- and post- increment and decrement) is the value that was stored in the object that was assigned to.
You can readily check this by examining the value of sizeof ++x (where x has type char).