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

Make extension method resolution deterministic #9844

Merged
merged 38 commits into from
May 22, 2024

Conversation

Akirathan
Copy link
Member

@Akirathan Akirathan commented May 2, 2024

Fixes #1243

Pull Request Description

Fixes the non-deterministic method resolution in some cases. Normally, method resolution tries to lookup the method in:

  1. In the scope where the type is defined
  2. In the current module scope
  3. In imported module scopes

The third step used to be non-deterministic. I have made it deterministic simply by replacing java.util.HashMap by java.util.LinkedHashMap in ModuleScope.

Important Notes

I have attempted three times to implement this feature:

  • In static compilation in a separate compiler pass
  • Right after static compilation in IrToTruffle, just before execution.
  • At runtime, just before method is executed in UnresolvedSymbol, as an error.
    All these attempts failed. More details in comment below.

At the end, I have decided to fix this bug by making the method resolution deterministic and not throwing any errors.

Checklist

Please ensure that the following checklist has been satisfied before submitting the PR:

  • The documentation has been updated, if necessary.
  • Screenshots/screencasts have been attached, if there are any visual changes. For interactive or animated visual changes, a screencast is preferred.
  • All code follows the
    Scala,
    Java,
    TypeScript,
    and
    Rust
    style guides. In case you are using a language not listed above, follow the Rust style guide.
  • Unit tests have been written where possible.

@Akirathan Akirathan added the CI: No changelog needed Do not require a changelog entry for this PR. label May 2, 2024
@Akirathan Akirathan self-assigned this May 2, 2024
@Akirathan Akirathan marked this pull request as ready for review May 3, 2024 10:20
Copy link
Member

@JaroslavTulach JaroslavTulach left a comment

Choose a reason for hiding this comment

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

Looks like you managed to detect this error during static compilation. Good!

@Akirathan
Copy link
Member Author

Akirathan commented May 21, 2024

All attempts to check extension method conflicts during compilation failed:

At the end, I have resolved to checks at runtime, inside UnresolvedSymbol.

GitHub
Hybrid visual and textual functional programming. Contribute to enso-org/enso development by creating an account on GitHub.

Turns out that current ordering of modules is a "feature" not a "bug". Let's not dig in that.
So that the iteration order of the entries is deterministic.
@Akirathan Akirathan added the CI: Clean build required CI runners will be cleaned before and after this PR is built. label May 22, 2024
@@ -408,12 +407,12 @@ public void reset() {
* @return a copy of this scope modulo the requested types
*/
public ModuleScope withTypes(List<String> typeNames) {
Map<String, Object> polyglotSymbols = new HashMap<>(this.polyglotSymbols);
Map<String, Type> requestedTypes = new HashMap<>(this.types);
Map<Type, Map<String, Supplier<Function>>> methods = new ConcurrentHashMap<>();
Copy link
Member Author

Choose a reason for hiding this comment

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

cc @hubertp. Note that I am getting rid of ConcurrentHashMap here and no tests are failing. This should be a proof that ModuleScope is intended to be single-threaded. Note that it would even not be possible to use it from more threads, as, e.g., in reset method in https://github.com/enso-org/enso/pull/9844/files#diff-c3869665e0ec34703f8e3eea0464924c0e4260eab392dbccdc202ec1f0270379L399, a normal HashMap is reassigned to the methods field instead of ConcurrentHashMap.

@Akirathan Akirathan merged commit 202f7e1 into develop May 22, 2024
37 checks passed
@Akirathan Akirathan deleted the wip/akirathan/1243-ext-methods-conflict branch May 22, 2024 11:49
@Akirathan Akirathan changed the title Conflicting extension methods result in compilation failure Make extension method resolution deterministic May 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CI: Clean build required CI runners will be cleaned before and after this PR is built. CI: No changelog needed Do not require a changelog entry for this PR.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Conflicting Extension Methods Make Resolution Nondeterministic
2 participants