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

Implement if let expressions and associated fixes #815

Merged
merged 47 commits into from
Mar 10, 2022
Merged

Conversation

sezna
Copy link
Contributor

@sezna sezna commented Feb 18, 2022

Why?

As we don't have any form of destructuring, getting values out of enums is impossible. This hinders our progress in developing the standard library and basic demos -- primarily SwaySwap.

What?

This PR implements if let for enums, although not to complete parity with Rust's pattern matching. Some general fixes around generic types/enums/etc., are included in this PR as well.

List O' Changes

  1. Previously, ​​return​​ statements inside of ​​if​​ expressions were not being type checked correctly. This PR fixes that.
  2. Enum monomorphization was not implemented at all, this PR implements that.
  3. Help text has been reintroduced to type errors.
  4. Implements if let expressions, which compare an enum's tag and conditionally pull out its contents into a variable.
  5. Improved error messages around generics: before

image

afer

image

7. Improved dead code detection such that publicly exported enums don't warn that their variants are unused. 8. Allow type annotations for enum instantiations, i.e. `let x = Result::Ok::(5u64)`

Remaining work

  1. Generic impl blocks and trait interactions are still not there. This PR was big enough as is, so that'll be coming later.
  2. Arbitrary pattern destructuring is not implemented. This version of if let only allows for destructuring the top-level enum. This is okay: if let Result::Ok(val) = foo { .. }, this is not okay: if let Result::Ok(Option::Some(Enum::Variant(x, y, Struct { field, .. } ) ) ) = foo { .. }

closes #817
closes #624

@sezna sezna self-assigned this Feb 18, 2022
@adlerjohn adlerjohn added compiler General compiler. Should eventually become more specific as the issue is triaged enhancement New feature or request labels Feb 18, 2022
@adlerjohn adlerjohn linked an issue Feb 18, 2022 that may be closed by this pull request
@sezna sezna mentioned this pull request Feb 18, 2022
19 tasks
@sezna sezna changed the title Implement if let expressions Implement if let expressions and associated fixes Mar 1, 2022
@sezna sezna marked this pull request as ready for review March 7, 2022 20:07
} => {
// sorry
let leaked_ix: &'static str = Box::leak(Box::new(elem_to_access_num.to_string()));
let access_ident = Ident::new_with_override(leaked_ix, elem_to_access_span.clone());
Copy link
Contributor

Choose a reason for hiding this comment

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

Obviously less than ideal. Should we make an issue to not need 'static strings for Ident?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm not sure. I was debating the performance costs. We clone Ident a lot throughout the compiler. I somewhat suspect that this leak is better for performance than using String everywhere for Ident. And using a scoped lifetime, like <'sc>, would be what we had before and nobody liked that.

This only happens specifically in these tuple accesses. I'm sure we can sort out a more localized solution that just updates the tuple access stuff. Maybe that's what the issue should be about.

@otrho
Copy link
Contributor

otrho commented Mar 8, 2022

Yikes, are we going to get Forc.lock conflicts like crazy from now on, or is this temporary?

@mitchmindtree
Copy link
Contributor

Yikes, are we going to get Forc.lock conflicts like crazy from now on, or is this temporary?

All of the Forc.tomls and Forc.lock files for the E2E tests were updated in #876 and shouldn't need to be updated in a PR like this (except for the new ones of course!). Conflicts in lock files should be no more common than conflicts related to changing version numbers in Forc.toml.

I think this is a unique case where the conflicts are potentially related to generating and committing lock files between #825 landing and #876 landing. I probably should have done #876 as a part of #825 to avoid this happening, but that PR was already massive enough! I would probably address this via a rebase onto master, but I know many prefer to avoid rebase and everyone has their own git wrangling strats :)

@adlerjohn adlerjohn requested a review from mohammadfawaz March 8, 2022 13:52
otrho
otrho previously approved these changes Mar 9, 2022
@sezna sezna requested review from otrho and mitchmindtree March 9, 2022 15:49
@adlerjohn adlerjohn marked this pull request as draft March 10, 2022 16:56
@adlerjohn
Copy link
Contributor

adlerjohn commented Mar 10, 2022

Do not merge until 0.6.1 is released #921

@adlerjohn adlerjohn marked this pull request as ready for review March 10, 2022 17:44
@sezna sezna merged commit cfeeecc into master Mar 10, 2022
@sezna sezna deleted the sezna/if_lets branch March 10, 2022 19:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler General compiler. Should eventually become more specific as the issue is triaged enhancement New feature or request
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

Remove OwnedTyped* and use new Spans Implement "if lets"
5 participants