Skip to content

Conversation

@kazcw
Copy link
Contributor

@kazcw kazcw commented Nov 17, 2025

Pull Request Description

Add new Call node at the root of app/named-app calls; the next PR will enable the nodes at the sites of possible no-argument calls (i.e. around Ident and PropertyAccess nodes). For now node is ignored in backend and frontend; the next step is to use it to replace some analysis on both sides.

See: https://github.com/enso-org/design/pull/60

Important Notes

  • Updated all Rust crates to Edition 2024

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.
  • If meaningful changes were made to logic or tests affecting Enso Cloud integration in the libraries,
    or the Snowflake database integration, a run of the Extra Tests has been scheduled.
    • If applicable, it is suggested to paste a link to a successful run of the Extra Tests.

@kazcw kazcw added the CI: No changelog needed Do not require a changelog entry for this PR. label Nov 17, 2025
@kazcw kazcw force-pushed the wip/kw/eval-nodes branch 2 times, most recently from 3de84c1 to 861b902 Compare November 26, 2025 19:41
@kazcw kazcw added the CI: Clean build required CI runners will be cleaned before and after this PR is built. label Nov 27, 2025
@kazcw kazcw force-pushed the wip/kw/eval-nodes branch from ff69db1 to 42096c9 Compare November 27, 2025 13:19
@Test
public void callingExtensionMethodDefinedElsewhere() throws Exception {
final URI uriA = new URI("memory://local.Project1.modA.enso");
final URI uriA = new URI("memory://local.Project1.Mod_A.enso");
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The original was not a valid module name

Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Contributor

@farmaazon farmaazon left a comment

Choose a reason for hiding this comment

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

Approving parser&GUI

Comment on lines 211 to 214
if let Variant::Eval(eval) = &tree.variant
&& matches!(&eval.value.variant, Variant::Ident(_) | Variant::PropertyAccess(_))
{
let Tree { variant: Variant::Eval(mut eval), span, .. } = tree else { unreachable!() };
Copy link
Contributor

Choose a reason for hiding this comment

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

Isn't it possible to make this let inside if condition in place of let Variant::Eval(eval) = &tree.variant? Also, I'm not sure, but perhaps making && matches! in if a where clause in match may look better.

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 think the unsafe borrow-to-owned upgrade pattern is unavoidable in this case, unless we refactor the whole thing to a mutable-borrow solution (but that tends to require allocations that wouldn't be necessary in this approach).
In order to tell if ownership should be taken, we must look inside the variant; sometimes a deep pattern can take ownership while checking the variant simultaneously, but that isn't possible here because the variant is boxed and box patterns aren't available in Rust as of our current version.

I will think about whether I can encapsulate the borrow-inspect-upgrade pattern for tree variant operations, to contain the unsafety to one function.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh, in this case I can take ownership unconditionally, then if the validity check fails I can return an error explicitly rather than falling through to the general error case.

Copy link
Contributor

Choose a reason for hiding this comment

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

All I looked for is code simplification; if it would required "unsafe" operations, then it is not worth it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh, I shouldn't have said unsafe, I meant "requiring an unreachable branch", which could be unsafe but in this case is handled by a panic. Anyway, I've eliminated the panic branch with some ownership wrangling.

Comment on lines 10 to 16
/// Wraps a value, tracking the number of wildcards operands within it.
#[derive(Default, Debug, PartialEq, Eq)]
pub struct Operand<'s> {
pub value: Tree<'s>,
pub wildcards: bool,
pub eval: bool,
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Docs says about tracking number of wildcards, but field has bool only.

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.

the next step is to use it to replace some analysis on both sides.

  • May I get some explanation why this change is needed?
  • I don't see any reason to introduce Tree.Eval from engine perspective
  • I don't understand why it should be needed by the IDE
  • may some documentation be updated to provide some high level perspective
  • and justify the change?

@kazcw kazcw changed the title Eval nodes Call nodes Dec 2, 2025
@kazcw kazcw requested a review from JaroslavTulach December 2, 2025 19:29
@JaroslavTulach
Copy link
Member

JaroslavTulach commented Dec 3, 2025

* I don't see any reason to introduce `Tree.Eval` from engine perspective
  * we already have [EvalNode](https://github.com/enso-org/enso/blob/9a9602fe47dc92a83a1c3cbd76b31a2bb48b9e0a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/debug/EvalNode.java#L30)!

@kazcw
Copy link
Contributor Author

kazcw commented Dec 3, 2025

* I don't see any reason to introduce `Tree.Eval` from engine perspective
  * we already have [EvalNode](https://github.com/enso-org/enso/blob/9a9602fe47dc92a83a1c3cbd76b31a2bb48b9e0a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/debug/EvalNode.java#L30)!
* "Call node" sounds better than "Eval Node"

* there are unexpected API changes https://github.com/enso-org/enso/actions/runs/19870865486/job/56949306648?pr=14303#step:14:1184

* changes in `TreeToIr` seem to loose return type of argument-less methods in the `IR`

Yeah, I'm debugging this. Probably a missed case in TreeToIr, but this result is strange (a few methods have the problem while other syntactically-similar methods are unaffected)

@enso-bot enso-bot bot mentioned this pull request Dec 4, 2025
3 tasks
@kazcw kazcw changed the title Call nodes Call nodes: App tree roots Dec 5, 2025
@kazcw
Copy link
Contributor Author

kazcw commented Dec 5, 2025

Making some changes to the treatment of PropertyAccess (thanks to @JaroslavTulach's feedback in enso-org/design/pull/60#discussion_r2587629509). I'm disabling adding the new nodes to PropertyAccess/Ident to get the bulk of the changes merged while I work on the new PropertyAccess logic.

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.

4 participants