Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix TyExpression::deterministically_aborts(), and eliminate its use during IR generation #5438

Closed
Tracked by #5562
jjcnn opened this issue Jan 5, 2024 · 2 comments
Closed
Tracked by #5562
Labels
bug Something isn't working compiler: frontend Everything to do with type checking, control flow analysis, and everything between parsing and IRgen compiler: ir IRgen and sway-ir including optimization passes

Comments

@jjcnn
Copy link
Contributor

jjcnn commented Jan 5, 2024

The function TyExpression::deterministically_aborts() almost certainly computes the wrong result in some cases. The most obvious example is return break, which does not abort, but for which deterministically_aborts() returns true.

Additionally, deterministically_aborts() is only supposed to be used during typechecking, but it is currently being used when generating IR for variable declarations as well. During IR generation it should be sufficient to use Value::is_diverging(), but removing the single use causes an internal compiler error.

Edit: #5496 has removed the call to deterministically_aborts() from IR generation, so that part has been fixed.

@jjcnn jjcnn added bug Something isn't working compiler: ir IRgen and sway-ir including optimization passes compiler: frontend Everything to do with type checking, control flow analysis, and everything between parsing and IRgen labels Jan 5, 2024
@jjcnn
Copy link
Contributor Author

jjcnn commented Jan 11, 2024

The function diverge_with_if_else in the test case e2e_vm_tests/test_programs/should_pass/language/diverging_exprs/ shows why the call exists in the IR generation.

IGI-111 pushed a commit that referenced this issue Jan 29, 2024
## Description

This PR refactors how `Value` is used during IR conversion. The PR
introduces `TerminatorValue` which forces the converter to handle
diverging expressions properly. There were checks for divergence
scattered around the code before, but it's now been made more systematic
and thus more robust.

Additionally, this change allows for early returns from some functions.
For instance, if the condition of a `while` diverges, then we don't need
to generate code for the body of the loop. In fact, if an expression
does diverge then the algorithm assumes that a terminator value (e.g., a
`branch` or a `return`) is returned, but this was not always the case,
and led to a number of spurious checks that probably didn't quite work.

The heavy lifting is done by the macro
`return_on_termination_or_extract`, which acts as destructor of
`TerminatorValue`s.

Most changes are straightforward, but do review the functions
`compile_lazy_op`, `compile_fn_call`, `compile_if`,
`compile_while_loop`, `compile_var_decl` and `compile_array_expr` extra
carefully, as they contain changes to the conversion algorithm. Mostly
the changes are small, but they need an extra pair of eyes. In a few
cases the algorithm was and still is a bit convoluted, but that's
because the typechecker unhelpfully assigns `Unknown` instead of `Never`
to diverging expressions, so the first sub-expression needs to be
compiled and divergence checked before we can generate IR for anything
that relies on the type of the expression.

Finally, I have taken the liberty of removing `Value::is_diverging()`
and using its alias `Value::is_terminator()` everywhere. The concept of
divergence lives in the source language, whereas the concept of
terminators lives in the IR, so `is_terminator` seems to be more
appropriate at this stage of the compilation.

Fixes #2051. 

Partial fix of #5438 (the call to `deterministically_aborts()` is
removed).

## Checklist

- [x] I have linked to any relevant issues.
- [x] I have commented my code, particularly in hard-to-understand
areas.
- [x] I have updated the documentation where relevant (API docs, the
reference, and the Sway book).
- [x] I have added tests that prove my fix is effective or that my
feature works.
- [x] I have added (or requested a maintainer to add) the necessary
`Breaking*` or `New Feature` labels where relevant.
- [x] I have done my best to ensure that my PR adheres to [the Fuel Labs
Code Review
Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md).
- [x] I have requested a review from the relevant team or maintainers.

---------

Co-authored-by: Igor Rončević <[email protected]>
@ironcev
Copy link
Member

ironcev commented Feb 7, 2024

As explained in #5562 deterministically_aborts tried to compensate for the missing bottom type in the type system. Since we want to introduce it, there will be no need for fixing deterministically_aborts, we will rather remove it completely.

Closing in favor of #5562.

@ironcev ironcev closed this as completed Feb 7, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working compiler: frontend Everything to do with type checking, control flow analysis, and everything between parsing and IRgen compiler: ir IRgen and sway-ir including optimization passes
Projects
None yet
Development

No branches or pull requests

2 participants