Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 24 additions & 3 deletions pkl-core/src/main/java/org/pkl/core/ast/type/TypeNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -2395,11 +2395,13 @@ protected boolean isParametric() {

public static final class TypeVariableNode extends WriteFrameSlotTypeNode {
private final TypeParameter typeParameter;
private final boolean isInTypeAlias;

public TypeVariableNode(SourceSection sourceSection, TypeParameter typeParameter) {

public TypeVariableNode(
SourceSection sourceSection, TypeParameter typeParameter, boolean isInTypeAlias) {
super(sourceSection);
this.typeParameter = typeParameter;
this.isInTypeAlias = isInTypeAlias;
}

public int getTypeParameterIndex() {
Expand All @@ -2408,7 +2410,10 @@ public int getTypeParameterIndex() {

@Override
public boolean isNoopTypeCheck() {
return true;
// if in a type alias, this node will be replaced by another TypeNode that may not be a noop
// so we return false so that containing TypeNodes don't skip checks erroneously
// this is slightly less efficient if the replacement _is_ a noop, but only inside typealiases
return !isInTypeAlias;

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.

We should never hit the case where isNoopTypeCheck() is called when this is inside a typealias, because these nodes should be replaced before the alias can ever run.

Also: I feel that we should replace the usage of TypeVariableNode in other positions (e.g. function <T>(foo: T)) with TypeNode.Unknown, at least until we have support for type arguments there. Probably would be better if TypeVariableNode never gets fired.

}

@Override
Expand Down Expand Up @@ -2789,6 +2794,22 @@ public Object executeAndSet(VirtualFrame frame, Object value) {
}
}

/** See docstring on {@link TypeAliasTypeNode#executeLazily}. */
@Override
public Object executeEagerly(VirtualFrame frame, Object value) {
var prevOwner = VmUtils.getOwner(frame);
var prevReceiver = VmUtils.getReceiver(frame);
setOwner(frame, VmUtils.getOwner(typeAlias.getEnclosingFrame()));
setReceiver(frame, VmUtils.getReceiver(typeAlias.getEnclosingFrame()));

try {
return aliasedTypeNode.executeEagerly(frame, value);
} finally {
setOwner(frame, prevOwner);
setReceiver(frame, prevReceiver);
}
}

@TruffleBoundary
private VmFunction newMixin(VmLanguage language, String qualifiedName) {
//noinspection ConstantConditions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,14 @@
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.ExplodeLoop;
import com.oracle.truffle.api.nodes.NodeUtil;
import com.oracle.truffle.api.source.SourceSection;
import java.util.Set;
import org.pkl.core.TypeParameter;
import org.pkl.core.ast.ExpressionNode;
import org.pkl.core.ast.PklNode;
import org.pkl.core.ast.expression.primary.GetModuleNode;
import org.pkl.core.ast.member.TypeAliasNode;
import org.pkl.core.ast.type.TypeNode.*;
import org.pkl.core.ast.type.TypeNodeFactory.*;
import org.pkl.core.runtime.*;
Expand Down Expand Up @@ -437,7 +439,9 @@ public int getTypeParameterIndex() {
public TypeNode execute(VirtualFrame frame) {
CompilerDirectives.transferToInterpreter();

return new TypeVariableNode(sourceSection, typeParameter);
//noinspection ConstantValue
return new TypeVariableNode(
sourceSection, typeParameter, NodeUtil.findParent(this, TypeAliasNode.class) != null);
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
typealias MyList<T> = List<T>
res1 = List(new Dynamic {}) is MyList<module>

typealias MyList2<T> = List(any((it) -> it is T))
res1a = List(new Dynamic {}) is MyList<module>
res1b = List(this) is MyList<module>

typealias MySet<T> = Set<T>
res2 = Set(new Dynamic {}) is MySet<module>

typealias MyMap<T> = Map<Any, T>
res3 = Map("foo", new Dynamic {}) is MyMap<module>

typealias MyListing<T> = Listing<T>
res4 = new Listing { new Dynamic {} } is MyListing<module>

typealias MyMapping<K, V> = Mapping<K, V>
res5 = new Mapping { ["foo"] = new Dynamic {} } is MyMapping<String, module>

typealias MyUnion<A, B> = A | B
res6 = new Dynamic {} is MyUnion<module, module>

typealias NestedUnion<A, B> = (A | A) | (B | B)
res7 = new Dynamic {} is NestedUnion<module, module>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
res1 = false
res1a = false
res1b = true
res2 = false
res3 = false
res4 = false
res5 = false
res6 = false
res7 = false
Loading