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

Implements the Never ! types as a TypeInfo bottom type. #5602

Merged
merged 11 commits into from
Feb 20, 2024

Conversation

esdrubal
Copy link
Contributor

@esdrubal esdrubal commented Feb 12, 2024

Description

We now parse the ! as a TypeInfo::Never, and remove the usage of empty enums as Never type in our code.

This commit removes completely the DeterministicallyAborts and TypeCheckUnificationContext.

The DeterministicallyAborts can be removed because the Never TypeInfo is now propagated using the type checker. Code blocks that return, break, continue, or call an expression that returns Never, are marked as Never.

Partially fixes #5562.

Checklist

  • I have linked to any relevant issues.
  • I have commented my code, particularly in hard-to-understand areas.
  • I have updated the documentation where relevant (API docs, the reference, and the Sway book).
  • I have added tests that prove my fix is effective or that my feature works.
  • I have added (or requested a maintainer to add) the necessary Breaking* or New Feature labels where relevant.
  • I have done my best to ensure that my PR adheres to the Fuel Labs Code Review Standards.
  • I have requested a review from the relevant team or maintainers.

@esdrubal esdrubal added language feature Core language features visible to end users breaking May cause existing user code to break. Requires a minor or major release. compiler: frontend Everything to do with type checking, control flow analysis, and everything between parsing and IRgen labels Feb 12, 2024
@esdrubal esdrubal self-assigned this Feb 12, 2024
@esdrubal esdrubal force-pushed the esdrubal/typeinfo_never branch 3 times, most recently from 1e3a257 to f8ca1c7 Compare February 12, 2024 15:23
We now parse the `!` as a TypeInfo::Never, and remove the usage of empty enums as Never type in our code.

This commit removes completely the DeterministicallyAborts and TypeCheckUnificationContext.

The DeterministicallyAborts can be removed because the Never TypeInfo is now propagated using the type checker.
Code blocks that return, break, continue, or call an expression that returns Never, are marked as Never.

Partially fixes #5562.
@esdrubal esdrubal requested a review from a team February 12, 2024 15:49
@esdrubal esdrubal marked this pull request as ready for review February 12, 2024 15:49
Copy link
Contributor

@IGI-111 IGI-111 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do so love PRs with negative line totals. Getting rid of all this complex logic in favor of a defined type is nice. The end result looks a lot cleaner.

But I'm about to ruin it by asking you to write some documentation for it.
! is a fairly complex concept and the book should absolutely cover it.

@IGI-111 IGI-111 requested a review from a team February 12, 2024 17:03
Copy link
Member

@ironcev ironcev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome!! Can you please check the questions regarding the coercion and equality on the IR level?

Also, assuming how crucial Never is for the type system, I would expect new dedicated tests. E.g., testing coercion rules could be an example, having ! as a type in different positions, e.g., as a function parameter, etc.

sway-core/src/type_system/unify/unifier.rs Outdated Show resolved Hide resolved
sway-core/src/type_system/unify/unifier.rs Outdated Show resolved Hide resolved
sway-ir/src/verify.rs Outdated Show resolved Hide resolved
sway-ir/src/verify.rs Outdated Show resolved Hide resolved
@ironcev
Copy link
Member

ironcev commented Feb 12, 2024

BDW solving #5560 would be a great test of the new type system (as a separate PR of course). I wouldn't be surprised if the bug is no more reproducible on this branch 😄

@ironcev
Copy link
Member

ironcev commented Feb 12, 2024

But I'm about to ruin it by asking you to write some documentation for it.

@IGI-111 Completely agree about the need for the docs! But want to selfishly ask if the documentation could be a part of a separate PR if that will speed up the merge of this PR. I was doing changes in the Unifier and UnifyCheck and in general in the area of type cheking and would love to get those changes rebased on this PR before pushing them.

@IGI-111
Copy link
Contributor

IGI-111 commented Feb 12, 2024

Okay sure, if that blocks some other work we can split it into another PR.

@esdrubal
Copy link
Contributor Author

But I'm about to ruin it by asking you to write some documentation for it.
! is a fairly complex concept and the book should absolutely cover it.

Added docs for Never type to the Sway book.

Also, assuming how crucial Never is for the type system, I would expect new dedicated tests. E.g., testing coercion rules could be an example, having ! as a type in different positions, e.g., as a function parameter, etc.

Added more coercion positive and negative tests.

About the ! as type parameters I created this issue: #5623

Copy link

Benchmark for bb163e2

Click to view benchmark
Test Base PR %
code_action 5.5±0.21ms 5.4±0.02ms -1.82%
code_lens 294.3±8.42ns 289.7±10.37ns -1.56%
compile 3.2±0.08s 3.2±0.05s 0.00%
completion 5.2±0.28ms 5.1±0.21ms -1.92%
did_change_with_caching 3.1±0.03s 3.1±0.09s 0.00%
document_symbol 978.3±31.73µs 967.5±20.18µs -1.10%
format 91.2±1.49ms 89.6±1.16ms -1.75%
goto_definition 376.8±10.43µs 359.9±7.67µs -4.49%
highlight 9.4±0.34ms 9.2±0.23ms -2.13%
hover 535.8±5.21µs 537.7±9.78µs +0.35%
idents_at_position 122.2±0.68µs 123.9±1.19µs +1.39%
inlay_hints 663.1±33.05µs 671.6±41.67µs +1.28%
on_enter 488.1±18.89ns 493.4±8.65ns +1.09%
parent_decl_at_position 3.7±0.06ms 3.7±0.10ms 0.00%
prepare_rename 362.6±6.85µs 364.9±6.38µs +0.63%
rename 10.3±1.28ms 9.9±0.24ms -3.88%
semantic_tokens 1028.8±20.44µs 1046.1±21.40µs +1.68%
token_at_position 351.5±2.92µs 353.8±3.24µs +0.65%
tokens_at_position 3.7±0.08ms 3.7±0.10ms 0.00%
tokens_for_file 410.8±3.96µs 409.6±4.96µs -0.29%
traverse 41.2±0.67ms 41.1±1.26ms -0.24%

Copy link

Benchmark for 057388c

Click to view benchmark
Test Base PR %
code_action 5.2±0.03ms 5.2±0.04ms 0.00%
code_lens 298.2±8.10ns 288.4±10.39ns -3.29%
compile 3.0±0.04s 3.1±0.06s +3.33%
completion 4.7±0.11ms 4.8±0.09ms +2.13%
did_change_with_caching 2.9±0.05s 2.9±0.03s 0.00%
document_symbol 997.6±22.72µs 956.2±11.88µs -4.15%
format 88.9±1.40ms 89.6±0.54ms +0.79%
goto_definition 365.4±5.94µs 361.0±8.04µs -1.20%
highlight 8.9±0.36ms 8.8±0.03ms -1.12%
hover 535.0±4.36µs 539.5±5.38µs +0.84%
idents_at_position 122.1±0.84µs 124.4±0.99µs +1.88%
inlay_hints 660.9±15.25µs 670.4±14.23µs +1.44%
on_enter 479.4±13.84ns 474.4±14.07ns -1.04%
parent_decl_at_position 3.6±0.03ms 3.6±0.03ms 0.00%
prepare_rename 429.7±4.75µs 361.2±12.35µs -15.94%
rename 9.2±0.22ms 9.3±0.19ms +1.09%
semantic_tokens 1049.6±14.63µs 1063.0±12.31µs +1.28%
token_at_position 361.7±11.97µs 360.4±19.37µs -0.36%
tokens_at_position 3.6±0.03ms 3.6±0.04ms 0.00%
tokens_for_file 410.3±2.50µs 415.0±3.18µs +1.15%
traverse 37.8±1.04ms 38.5±0.95ms +1.85%

sway-core/src/type_system/unify/unifier.rs Outdated Show resolved Hide resolved
sway-ir/src/irtype.rs Show resolved Hide resolved
sway-ir/src/verify.rs Outdated Show resolved Hide resolved
@esdrubal esdrubal force-pushed the esdrubal/typeinfo_never branch 2 times, most recently from e429daa to bd61bf7 Compare February 19, 2024 11:31
Copy link

Benchmark for d7eaee9

Click to view benchmark
Test Base PR %
code_action 5.1±0.01ms 5.2±0.18ms +1.96%
code_lens 292.6±7.58ns 286.2±9.24ns -2.19%
compile 3.0±0.03s 2.9±0.07s -3.33%
completion 4.7±0.07ms 4.7±0.14ms 0.00%
did_change_with_caching 2.8±0.02s 2.8±0.03s 0.00%
document_symbol 1118.8±39.64µs 952.1±10.56µs -14.90%
format 72.3±0.47ms 74.4±1.79ms +2.90%
goto_definition 378.7±13.73µs 362.3±6.63µs -4.33%
highlight 8.8±0.17ms 8.8±0.06ms 0.00%
hover 547.0±7.43µs 534.9±7.47µs -2.21%
idents_at_position 123.9±0.44µs 122.7±1.37µs -0.97%
inlay_hints 664.9±20.82µs 655.3±25.68µs -1.44%
on_enter 478.6±10.09ns 492.8±12.15ns +2.97%
parent_decl_at_position 3.6±0.16ms 3.6±0.03ms 0.00%
prepare_rename 374.5±6.35µs 363.7±9.25µs -2.88%
rename 9.1±0.02ms 9.2±0.21ms +1.10%
semantic_tokens 1057.2±16.15µs 1065.7±30.73µs +0.80%
token_at_position 373.5±2.95µs 355.7±3.44µs -4.77%
tokens_at_position 3.6±0.03ms 3.6±0.02ms 0.00%
tokens_for_file 407.6±1.72µs 491.1±4.02µs +20.49%
traverse 37.1±0.46ms 37.5±1.25ms +1.08%

@jjcnn
Copy link
Contributor

jjcnn commented Feb 19, 2024

Okay sure, if that blocks some other work we can split it into another PR.

As it happens this issue blocks the one I'm currently working on, so it would be nice to have it merged asap.

@esdrubal esdrubal enabled auto-merge (squash) February 19, 2024 17:36
Copy link

Benchmark for ae537d3

Click to view benchmark
Test Base PR %
code_action 5.1±0.07ms 5.2±0.06ms +1.96%
code_lens 287.0±7.64ns 288.7±8.06ns +0.59%
compile 2.9±0.02s 3.0±0.05s +3.45%
completion 4.7±0.01ms 4.9±0.31ms +4.26%
did_change_with_caching 2.8±0.03s 2.9±0.03s +3.57%
document_symbol 966.5±23.47µs 1032.3±27.35µs +6.81%
format 71.7±0.56ms 75.4±1.23ms +5.16%
goto_definition 359.0±6.37µs 362.3±7.29µs +0.92%
highlight 8.8±0.16ms 8.8±0.22ms 0.00%
hover 533.6±9.12µs 534.5±15.39µs +0.17%
idents_at_position 123.4±0.48µs 121.5±0.65µs -1.54%
inlay_hints 650.2±15.67µs 650.7±24.04µs +0.08%
on_enter 480.4±21.86ns 500.5±20.21ns +4.18%
parent_decl_at_position 3.6±0.04ms 3.6±0.06ms 0.00%
prepare_rename 357.0±5.71µs 365.3±5.10µs +2.32%
rename 9.1±0.02ms 9.3±0.26ms +2.20%
semantic_tokens 1031.4±23.16µs 1027.9±17.37µs -0.34%
token_at_position 346.9±2.12µs 352.8±2.81µs +1.70%
tokens_at_position 3.6±0.04ms 3.6±0.04ms 0.00%
tokens_for_file 408.5±2.25µs 408.9±3.87µs +0.10%
traverse 36.7±1.04ms 37.9±0.55ms +3.27%

@IGI-111 IGI-111 requested a review from ironcev February 19, 2024 20:24
@IGI-111 IGI-111 dismissed ironcev’s stale review February 20, 2024 01:44

Coercion has been removed

@esdrubal esdrubal merged commit b32d0e0 into master Feb 20, 2024
39 checks passed
@esdrubal esdrubal deleted the esdrubal/typeinfo_never branch February 20, 2024 01:44
IGI-111 pushed a commit that referenced this pull request Feb 27, 2024
…#5631)

## Description

Fixes #5616 and #5622.

When generating the IR for constant and variable declarations the name
being declared is not added to the local environment if the initializer
cannot be compiled. This can happen when initializing a constant using a
non-constant expression.

Since the name isn't added to the environment, and since we attempt to
continue compilation after an error, any attempt to use the name later
in the code will cause the name to not be found, which in turn causes
the IR converter to throw an ICE because it assumes that all used names
are in scope.

This PR fixes the issue by not throwing the initializer error until the
name has been added to the environment. Note that
1. The initializer must be compiled before the name is added to the
environment. The name should not be in scope during its own
initialization.
2. #5602 is blocking a more elegant solution to this problem. The lack
of a `Never` type means that the call to `convert_resolved_typeid` may
fail if the initializer diverges, and since that call must be made
before the new name can be added to the environment we check for
termination first. The order of operations is therefore currently a)
compile the initializer, then b) check that the initializer did not
result in an error and did not diverge, then c) resolve the type of the
name being declared, then d) add the name to the environment, and
finally e) throw an error if the initializer resulted in an error. Once
the `Never` type is introduced we can move the terminator check to the
end of that sequence.

## 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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking May cause existing user code to break. Requires a minor or major release. compiler: frontend Everything to do with type checking, control flow analysis, and everything between parsing and IRgen language feature Core language features visible to end users
Projects
None yet
4 participants