Error when inferring a self type in a method argument (#1847)

This commit is contained in:
Jen Basch
2026-09-03 23:03:34 +00:00
committed by GitHub
parent 249e563291
commit f284a0560a
5 changed files with 40 additions and 1 deletions
@@ -36,7 +36,7 @@ public abstract class AbstractInferParentNode extends ExpressionNode {
this.language = language;
}
protected final Object getDefaultValue(
protected Object getDefaultValue(
VirtualFrame frame,
@Nullable TypeNode typeNode,
SourceSection headerSection,
@@ -85,4 +85,18 @@ public abstract class InferParentWithinMethodArgumentNode
var typeNode = getTypeNode(frame, method);
return getDefaultValue(frame, typeNode, method.getHeaderSection(), method.getQualifiedName());
}
@Override
protected Object getDefaultValue(
VirtualFrame frame,
@Nullable TypeNode typeNode,
SourceSection headerSection,
String qualifiedName) {
if (typeNode != null && typeNode.isSelfType()) {
CompilerDirectives.transferToInterpreter();
throw exceptionBuilder().evalError("cannotInferParent").build();
}
return super.getDefaultValue(frame, typeNode, headerSection, qualifiedName);
}
}
@@ -155,6 +155,20 @@ public abstract class TypeNode extends PklNode {
return ret.get();
}
public final boolean isSelfType() {
var ret = new MutableBoolean(false);
acceptTypeNode(
true,
typeNode -> {
if (typeNode instanceof NonFinalSelfTypeNode || typeNode instanceof FinalSelfTypeNode) {
ret.set(true);
return false;
}
return true;
});
return ret.get();
}
/** Visit child type nodes of this type. */
protected abstract boolean acceptTypeNode(boolean visitTypeArguments, TypeNodeConsumer consumer);
@@ -16,7 +16,12 @@ class Qux extends Foo {
function bar(baz: Foo): Int = thisBar(new { x = baz.x })
}
class Quux {
function selfType(arg: this): String = arg.getClass().toString()
}
function bar(baz: Foo): Int = baz.x
function selfType(arg: this): String = arg.getClass().toString()
const function outerMethod(a: Int, b: Qux) = a + b.x * 2
@@ -41,6 +46,9 @@ intrinsicConstructor = test.catch(() -> List(new {}))
genericMethod = test.catch(() -> Pair(new {}, new {}))
fnApply = test.catch(() -> quux.apply(new {}))
tooManyParams = test.catch(() -> bar(new {}, new {}))
finalSelfType = test.catch(() -> new Quux {}.selfType(new {}))
nonFinalSelfType1 = test.catch(() -> selfType(new {}))
nonFinalSelfType2 = test.catch(() -> new Qux {}.selfType(new {}))
class Bar1 { x: Int = 1 }
class Bar2 { x: Int = 2 }
@@ -14,5 +14,8 @@ intrinsicConstructor = "Cannot tell which parent to amend."
genericMethod = "Cannot tell which parent to amend."
fnApply = "Cannot tell which parent to amend."
tooManyParams = "Expected 1 function argument but got 2."
finalSelfType = "Cannot tell which parent to amend."
nonFinalSelfType1 = "Cannot tell which parent to amend."
nonFinalSelfType2 = "Cannot tell which parent to amend."
polyCall1 = 1
polyCall2 = 20