У вас есть общее представление о том, что не так, но не совсем.
Что случилось, когда вы написали
function_call(c, number);
Компилятор увидел, что вы вызываете функцию, которую он еще не видел, и поэтому должен был решить, какой должна быть ее подпись. На основании правила продвижения, которое вы цитировали ранее, он повысил значение char до int, а значение float - double и решило, что подпись
function_call(int, double)
Тогда, когда он видит
function_call(char c, float f)
он интерпретирует это как сигнатуру для другой функции с тем же именем, что недопустимо в C. Это точно такая же ошибка, как если бы вы создавали прототип функции не так, как вы ее фактически определяли, просто в этом случае Прототип неявно генерируется компилятором.
Итак, именно это правило вызывает проблему, но ошибка не имеет ничего общего с фактическим преобразованием значений между типами.