Além de todas as ótimas respostas até agora:
Você tem um "viés de observador". Você não observa bugs e, portanto, assume que não há nenhum.
Eu costumava pensar como você. Então eu comecei a escrever compiladores profissionalmente, e deixe-me dizer, existem muitos erros por aí!
Você não vê os bugs porque escreve um código que é igual a 99,999% de todo o restante do código que as pessoas escrevem. Você provavelmente escreve um código perfeitamente normal, direto e claramente correto, que chama métodos e executa loops e não faz nada extravagante ou estranho, porque você é um desenvolvedor normal resolvendo problemas comerciais normais.
Você não vê nenhum erro do compilador porque os erros do compilador não estão nos cenários de código normal fáceis de analisar; os erros estão na análise do código estranho que você não escreve.
Eu, por outro lado, tenho o viés oposto de observador. Eu vejo códigos malucos o dia todo, todos os dias e, para mim, os compiladores parecem estar cheios de bugs.
Se você sentou-se com a especificação de idioma de qualquer idioma e adotou qualquer implementação de compilador para esse idioma, e realmente tentou determinar se o compilador implementou exatamente a especificação ou não, concentrando-se em casos de canto obscuros, logo você descobriria erros do compilador com bastante frequência. Deixe-me dar um exemplo, aqui está um bug do compilador C # que encontrei literalmente cinco minutos atrás.
static void N(ref int x){}
...
N(ref 123);
O compilador fornece três erros.
- Um argumento ref ou out deve ser uma variável atribuível.
- A melhor correspondência para N (ref int x) possui argumentos inválidos.
- "Ref" ausente no argumento 1.
Obviamente, a primeira mensagem de erro está correta e a terceira é um erro. O algoritmo de geração de erro está tentando descobrir por que o primeiro argumento era inválido, olha para ele, vê que é uma constante e não volta ao código fonte para verificar se foi marcado como "ref"; ao contrário, assume que ninguém seria tolo o suficiente para marcar uma constante como ref e decide que o juiz deve estar ausente.
Não está claro qual é a terceira mensagem de erro correta, mas não é isso. De fato, também não está claro se a segunda mensagem de erro está correta. A resolução de sobrecarga deve falhar ou "ref 123" deve ser tratado como um argumento ref do tipo correto? Agora vou ter que pensar um pouco e conversar com a equipe de triagem para que possamos determinar qual é o comportamento correto.
Você nunca viu esse bug porque provavelmente nunca faria algo tão bobo a ponto de passar por 123 por ref. E se você o fizesse, provavelmente nem notaria que a terceira mensagem de erro não faz sentido, pois a primeira é correta e suficiente para diagnosticar o problema. Mas eu tento fazer coisas assim, porque estou tentando quebrar o compilador. Se você tentasse, também veria os erros.