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 identity comparison check with desugared creations #4182

Merged
merged 1 commit into from
Sep 15, 2022
Merged

Fix identity comparison check with desugared creations #4182

merged 1 commit into from
Sep 15, 2022

Conversation

leonardoce
Copy link
Contributor

While identity comparison with new objects was correctly catched by the
compiler as always false when using sugared syntax, it wasn't using
desugared one.

This patch makes the compiler in the latter case.

This example is now failing:

class C

actor Main
  new create(env: Env) =>
    env.out.print(if C.create() is C.create() then
      "C is C" else "C is NOT C" end)

Closes #4162

@ponylang-main ponylang-main added the discuss during sync Should be discussed during an upcoming sync label Aug 29, 2022
@SeanTAllen SeanTAllen added the changelog - fixed Automatically add "Fixed" CHANGELOG entry on merge label Aug 29, 2022
Copy link
Member

@SeanTAllen SeanTAllen left a comment

Choose a reason for hiding this comment

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

This looks like an excellent PR. I've left a couple comments on the release notes.

Assuming this passes CI, this has my approval.

.release-notes/4182.md Outdated Show resolved Hide resolved
.release-notes/4182.md Outdated Show resolved Hide resolved
.release-notes/4182.md Outdated Show resolved Hide resolved
.release-notes/4182.md Outdated Show resolved Hide resolved
@leonardoce
Copy link
Contributor Author

Thanks @SeanTAllen for your review! I should have applied the suggestions you made.
I'm waiting for the CI to finish. Last time the x86-64 Windows MSVC platform failed with a timeout.

@leonardoce leonardoce marked this pull request as ready for review August 30, 2022 21:46
{
// From issue #4162, this is just the desugared
// version of the previous test.
const char* src =
Copy link
Member

Choose a reason for hiding this comment

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

to go along with the missed cases that Joe mentions in his other comment, we need to also test with a constructor that isn't new.

So something like

class D
  new foo() => None

then as part of a test, that...

D.foo() is D.foo()

gives our error

For the sake of completeness, we should also the same with an actor and also an actor with a custom named constructor like foo.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes! The existence of constructors which aren't called new was even documented here: https://tutorial.ponylang.io/types/classes.html#constructors

I'm still a newbie when it comes to Pony. Ok, let me work on it.

// this will not create new objects.
return false;
}
if(strcmp(ast_name(message), "create"))
Copy link
Member

Choose a reason for hiding this comment

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

Not every constructor has the name "create", and it is possible to create a function whose name is "create". So the name is not the right criterion to check here.

Instead of checking here based on the name of the called method, we should be checking if it refers to a constructor on the type.

Here in the refer.c pass, that would be a bit complicated (though still possible).

My suggestion is that you move this entire function to the verify.c pass, as well as the entire valid_is_comparand function and the refer_is function that calls it (which would become verify_is).

The reason is that in the expr.c pass we actually resolve every TK_DOT to be specific to what it is calling. So each TK_DOT that calls a constructor gets turned into a TK_NEWREF or TK_NEWBEREF (for the case of an actor constructor).

So if you move this set of checks into the verify.c pass, it becomes simple to check if the call is to a constructor - just check the AST ID for TK_NEWREF or TK_NEWBEREF. And in that case you don't need to bother checking the left side (the type reference) so it becomes a bit simpler than you have here, which is nice.

Also, conceptually, this check doesn't really fit the refer.c pass anyway, as it has nothing to do with resolving TK_REFERENCE nodes. Instead, it belongs in the verify pass, which has a variety of post-type-analysis correctness checks.

Here is the link to the original commit where these checks were added, in case it helps you see which parts need to be moved to verify.c: f37e281

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nice idea bringing this to the verify step. Let me try changing this PR with your suggestions. Thanks @jemc @SeanTAllen

@leonardoce leonardoce requested review from SeanTAllen and jemc and removed request for SeanTAllen September 3, 2022 20:28
@leonardoce
Copy link
Contributor Author

Looks like GitHub allows to request a review by just one user, I think this is why my review request from @jemc removed the one for @SeanTAllen that I did previously. Sorry for the confusion.

I should have addressed your points. Can you please have a look? Thank you for reviewing this!

@SeanTAllen
Copy link
Member

SeanTAllen commented Sep 3, 2022

You can do more than 1, but the interface is wonky if you aren't used to it. Also, I see both of us as reviewers.

src/libponyc/pass/verify.c Outdated Show resolved Hide resolved
@jemc
Copy link
Member

jemc commented Sep 9, 2022

I only had the one small whitespace fix to mention above. Everything else looks okay 👍

While identity comparison with new objects was correctly catched by the
compiler as always false when using sugared syntax, it wasn't using
desugared one.

This patch makes the compiler in the latter case.

This example is now failing:

```pony
class C

actor Main
  new create(env: Env) =>
    env.out.print(if C.create() is C.create() then
      "C is C" else "C is NOT C" end)
```

Closes #4162

Co-authored-by: Joe Eli McIlvain <joe.eli.mac@gmail.com>
@leonardoce
Copy link
Contributor Author

I applied @jemc 's suggestion, squashed everything in one commit and rebased it on main.

@jemc
Copy link
Member

jemc commented Sep 14, 2022

@SeanTAllen - any further thoughts on this one?

@SeanTAllen
Copy link
Member

@jemc i leave for 10 days in a day and have a lot of work stuff to get through so I leave this entirely in your capable hands. If you think it is good, I think it is good! I don't have time to look before I leave and I'd rather than be an impediment to this being merged whenever you think it is ready.

@jemc jemc merged commit 5cc79a6 into ponylang:main Sep 15, 2022
@ponylang-main ponylang-main removed the discuss during sync Should be discussed during an upcoming sync label Sep 15, 2022
@jemc
Copy link
Member

jemc commented Sep 15, 2022

Thanks, @leonardoce!

github-actions bot pushed a commit that referenced this pull request Sep 15, 2022
github-actions bot pushed a commit that referenced this pull request Sep 15, 2022
@ponylang-main ponylang-main added the discuss during sync Should be discussed during an upcoming sync label Sep 15, 2022
@SeanTAllen
Copy link
Member

Thank you very much!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
changelog - fixed Automatically add "Fixed" CHANGELOG entry on merge discuss during sync Should be discussed during an upcoming sync
Projects
None yet
Development

Successfully merging this pull request may close these issues.

No compiler error for "SomeClass.create() is SomeClass.create()"
4 participants