Skip to content

Add this as a self type - #1708

Open
HT154 wants to merge 3 commits into
apple:mainfrom
HT154:this-type
Open

Add this as a self type#1708
HT154 wants to merge 3 commits into
apple:mainfrom
HT154:this-type

Conversation

@HT154

@HT154 HT154 commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Depends on #1796

This PR:

  • Adds type this, a fully featured self type for use in modules or classes.
    • Forbids use of this in typealias bodies.
  • Deprecates usage of the module type in const scopes (class and typealias bodies, annotations, const properties/methods) with a warning, to be an error in a future release.
  • Adopts this in the standard library:
    • pkl.base#Any.getClass() now returns Class<this>.
    • pkl.base#Any.ifNonNull() now accepts an argument of type (this) -> Result.
    • pkl.ref#Domain.renderReference() now accepts a Reference<this, Any>.
  • This also a corner case with ReferenceTypeNode, module types, and type aliases that caused module types in the referent position to always be resolved to the module where the Reference type annotation is instead of where module is used.
  • Pipes a Logger through to AstBuilder so warnings/traces can be printed from it.

For ease of review, this PR consists of two commits; the first is all implementation changes, the second includes regenerated pkl-doc test output.

Resolves #1612
Resolves #1712

Comment thread pkl-core/src/main/java/org/pkl/core/ast/type/TypeNode.java Outdated
Comment on lines +190 to +194
/**
* If {@code frame} is provided then self types should be resolved to real types, otherwise return
* the self PType
*/
protected PType doExport(@Nullable VirtualFrame frame) {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

ReferenceTypeNode needs to export the real class here, so when a frame is passed NonFinalSelfTypeNode uses it to get the target's class instead of exporting PType.MODULE/PType.THIS.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Do we need the logic around passing a frame in still?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I think so, yeah. Even with the changes from #1796, ReferenceTypeNode still needs to erase self types in referents to their real classes before calling into VmReference. With #1796 and the other changes here, I think that could be done post-export, but it would mean walking/transforming the PType tree, which we have no machinery for. Preserving this mechanism is both more efficient (don't need to walk the type tree twice) and avoids potentially introducing new API to or helper code for PType.

@HT154
HT154 force-pushed the this-type branch 4 times, most recently from 6c21103 to 84c587e Compare July 15, 2026 22:39

@bioball bioball left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Left some comments!

The major ones are:

  • Much of the resolution logic should happen inside AstBuilder; we shouldn't need to traverse the truffle tree
  • Not sure about the realTypeAliasFrame logic added to type node execution; this feels like a workaround to a deeper issue
  • Not sure if TypeNode.export() should be deferencing self types; this feels like the responsibility of the caller, not TypeNode itself

Comment thread pkl-core/src/main/java/org/pkl/core/ast/type/UnresolvedTypeNode.java Outdated
Comment thread pkl-doc/src/main/kotlin/org/pkl/doc/PageGenerator.kt
Comment thread pkl-core/src/main/java/org/pkl/core/ast/type/TypeNode.java Outdated
Comment thread pkl-core/src/main/java/org/pkl/core/ast/type/UnresolvedTypeNode.java Outdated
Comment thread pkl-core/src/main/java/org/pkl/core/ast/type/TypeNode.java Outdated
Comment thread pkl-core/src/main/java/org/pkl/core/runtime/VmReference.java
Comment thread pkl-core/src/main/java/org/pkl/core/PType.java Outdated
Comment thread pkl-core/src/main/resources/org/pkl/core/errorMessages.properties Outdated
Comment thread pkl-core/src/main/java/org/pkl/core/runtime/VmTypeAlias.java
Comment thread pkl-core/src/test/files/LanguageSnippetTests/output/types/thisType2.err Outdated
@HT154
HT154 force-pushed the this-type branch 4 times, most recently from 1dd722f to 528bd4f Compare July 23, 2026 00:06
@HT154
HT154 requested a review from bioball July 23, 2026 00:07
@HT154
HT154 force-pushed the this-type branch 5 times, most recently from 30c1ed4 to 6db4376 Compare July 24, 2026 01:50
Comment thread pkl-core/src/main/java/org/pkl/core/ast/expression/member/ReadClassNode.java Outdated
Comment thread pkl-core/src/main/java/org/pkl/core/ast/expression/member/ReadClassNode.java Outdated
Comment thread pkl-core/src/main/java/org/pkl/core/ast/builder/AstBuilder.java Outdated
Comment thread pkl-core/src/main/java/org/pkl/core/ast/builder/AstBuilder.java
Comment thread pkl-core/src/main/java/org/pkl/core/ast/builder/AstBuilder.java Outdated
Comment thread pkl-core/src/test/files/LanguageSnippetTests/input/types/currentModuleType7.pkl Outdated
Comment thread pkl-core/src/main/java/org/pkl/core/ast/type/TypeNode.java Outdated
Comment on lines +190 to +194
/**
* If {@code frame} is provided then self types should be resolved to real types, otherwise return
* the self PType
*/
protected PType doExport(@Nullable VirtualFrame frame) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Do we need the logic around passing a frame in still?

public MaterializedFrame materialize() {
return this;
}
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I went down the rabbit hole today and I think I have a better solution to this whole thing.

The whole reason we are doing owner/receiver replacements is so that we can resolve variables within constraint expressions.

However, now that we are resolving variables at parse time (yay!), we don't need to be swapping out owner/receiver anymore. Instead, we can just produce ReadProperty/InvokeMethod nodes that are qualified off of the typealias's enclosing module. Then, we shouldn't need to be dealing with this logic around preserving the frame's original owner/reciever.

Since this is all orthogonal to the this type, here's a PR that implements this change!

#1796

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I've rebased this PR on #1796 and fully agree that it is the path forward, reducing a lot of the complexity around resolving the correct receiver for determining the this type. All of the aux frame slot stuff has been removed here now.

@HT154
HT154 force-pushed the this-type branch 3 times, most recently from 4419cd5 to 39c38ca Compare July 28, 2026 20:04
Comment thread pkl-core/src/main/java/org/pkl/core/ast/builder/AstBuilder.java Outdated
@HT154
HT154 force-pushed the this-type branch 3 times, most recently from 00421a9 to 4aa9f97 Compare July 28, 2026 23:52
@HT154
HT154 force-pushed the this-type branch 3 times, most recently from bb5718c to 97dac9c Compare July 30, 2026 18:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Pkl is missing a self-type module types as typelias type args are evaluated in the context of the alias's module, not where module is used

2 participants