4.4 KiB
Ignored Call Results in Executable Lowering Agenda
Status
Open
Domain Owner
docs/compiler/pbs
Este tema pertence ao domínio PBS do compiler porque afeta:
- semântica prática de
expression statement; - lowering executável para
IRBackend/IRVM; - ergonomia de uso de SDKs e hosts que retornam status;
- compatibilidade entre o que o código-fonte parece permitir e o que o pipeline realmente aceita.
Problema
Hoje uma chamada com retorno usada como statement isolado pode deixar valor sobrando na stack no lowering executável.
Exemplo real:
Gfx.set_sprite(...);
No estado atual, isso compila no frontend, mas pode falhar no pipeline backend com erro de validação de stack no RET da função, porque o resultado da call não foi consumido explicitamente.
Isso cria uma inconsistência operacional:
- o código parece válido para o autor;
- o frontend aceita a forma;
- o backend exige, na prática, um consumo manual do retorno, por exemplo:
let sprite_status = Gfx.set_sprite(...);
Contexto
O problema apareceu ao migrar o consumo de sprite em PBS para o contrato novo de Gfx.set_sprite, que retorna um status inteiro.
Os pontos observados no código atual são:
ExpressionStatementfaz lowering apenas da expressão;- o lowering de
CallExpremiteCALL_HOST,CALL_FUNCouCALL_INTRINSICcomretSlots; - não há descarte automático do valor quando a expressão é usada apenas como statement;
- o validador de
IRVMexige que funçõesvoidretornem com stack height0.
Na prática, isso transforma "ignorar retorno" em comportamento parcialmente suportado pela linguagem, mas não suportado pelo pipeline executável.
Opções
Opção A
Manter o comportamento atual e exigir consumo explícito de todo retorno em PBS.
Opção B
Permitir que expression statements descartem automaticamente o resultado quando a expressão produzir valor.
Opção C
Permitir descarte automático apenas para um subconjunto de calls, como hosts/SDKs anotados como status descartável.
Tradeoffs
Opção A
- Prós:
- regra simples no backend;
- evita descarte implícito sem intenção.
- Contras:
- ergonomia ruim para APIs baseadas em status;
- surpresa para autores, porque
foo();parece natural mas falha mais tarde; - expõe detalhe de stack do backend ao código-fonte.
Opção B
- Prós:
- comportamento esperado para statement de expressão;
- reduz ruído em código de jogo e SDK;
- alinha parsing, semântica prática e lowering executável.
- Contras:
- introduz descarte implícito;
- exige regra clara para saber quando emitir
POP.
Opção C
- Prós:
- mais controle semântico;
- evita descarte implícito amplo.
- Contras:
- adiciona complexidade de contrato e metadata;
- mistura política de produto/API dentro do lowering;
- não resolve a expectativa geral sobre
expression statement.
Recomendação
Seguir com a Opção B.
Direção recomendada:
expression statementdeve ser permitido mesmo quando a expressão produzir valor;- o lowering executável deve emitir descarte explícito do resultado não usado;
- a regra deve ser geral para expressões com resultado materializado em stack, não especial para
Gfx.set_sprite; - testes de regressão devem cobrir host calls, callable calls e intrinsics com retorno ignorado.
Essa direção preserva a ergonomia esperada da linguagem e remove um vazamento indevido do modelo de stack do backend para o código PBS.
Perguntas em Aberto
- O descarte automático deve valer para qualquer
expression statementcom valor ou apenas para formas lowerables em v1? - O frontend semântico deve emitir algum warning opcional para retorno ignorado, ou isso fica fora do escopo atual?
- O descarte deve acontecer somente no lowering executável ou também virar regra explícita de spec para statements?
- Existe algum caso em que o descarte automático possa mascarar bug real de usuário que hoje seria detectado mais cedo?
Próximo Passo Sugerido
Converter esta agenda em uma decision do domínio compiler/pbs fechando a política para expression statement com resultado ignorado.
Depois disso, abrir um pull-request/plan curto para:
- ajustar o lowering de
ExpressionStatement; - adicionar fixtures e testes de regressão no frontend/backend pipeline;
- propagar a regra para specs relevantes de statements e lowering.