From ea23fc975606bd4590cbe63acdecdb2153264af9 Mon Sep 17 00:00:00 2001 From: Jaroslav Tulach Date: Wed, 23 Aug 2023 16:32:45 +0200 Subject: [PATCH] Avoid stackoverflow in Atom.toString by not printing the self argument of to_text function --- .../test/instrument/ReplTest.scala | 2 +- .../runtime/callable/atom/Atom.java | 3 +- .../runtime/callable/function/Function.java | 33 +++++++++++-------- test/Tests/src/Semantic/Error_Spec.enso | 15 ++++++++- 4 files changed, 37 insertions(+), 16 deletions(-) diff --git a/engine/runtime-with-instruments/src/test/scala/org/enso/interpreter/test/instrument/ReplTest.scala b/engine/runtime-with-instruments/src/test/scala/org/enso/interpreter/test/instrument/ReplTest.scala index b885d0f7773b..ab000a724f01 100644 --- a/engine/runtime-with-instruments/src/test/scala/org/enso/interpreter/test/instrument/ReplTest.scala +++ b/engine/runtime-with-instruments/src/test/scala/org/enso/interpreter/test/instrument/ReplTest.scala @@ -102,7 +102,7 @@ class ReplTest result.toString shouldEqual "Error in method `to_text` of [Bar 1]: Expected Text but got 42" } inside(executor.evaluate("C.Baz 1")) { case Right(result) => - result.toString shouldEqual "Error in method `to_text` of [Baz 1]: Expected Text but got C.to_text[Test:18-40]" + result.toString shouldEqual "Error in method `to_text` of [Baz 1]: Expected Text but got C.to_text[Test:18:1-29]" } inside(executor.evaluate("Pattern.compile 'foo'")) { case Right(result) => diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/callable/atom/Atom.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/callable/atom/Atom.java index e851976cddff..fb7d089d6c3e 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/callable/atom/Atom.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/callable/atom/Atom.java @@ -253,7 +253,8 @@ Text toDisplayString( } else if (TypesGen.isText(result)) { return TypesGen.asText(result); } else { - msg = this.toString("Error in method `to_text` of [", 10, "]: Expected Text but got ", result); + var txt = result instanceof Function fn ? fn.toString(false) : result.toString(); + msg = this.toString("Error in method `to_text` of [", 10, "]: Expected Text but got ", txt); } } catch (AbstractTruffleException | UnsupportedMessageException | ArityException | UnknownIdentifierException | UnsupportedTypeException panic) { diff --git a/engine/runtime/src/main/java/org/enso/interpreter/runtime/callable/function/Function.java b/engine/runtime/src/main/java/org/enso/interpreter/runtime/callable/function/Function.java index 15f1a2f6b67c..cfdc4effaebf 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/runtime/callable/function/Function.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/runtime/callable/function/Function.java @@ -402,8 +402,12 @@ String toDisplayString(boolean sideEffects) { } @Override - @CompilerDirectives.TruffleBoundary public String toString() { + return toString(true); + } + + @CompilerDirectives.TruffleBoundary + public final String toString(boolean includeArguments) { var n = callTarget.getRootNode(); var ss = n.getSourceSection(); if (ss == null) { @@ -422,19 +426,22 @@ public String toString() { sb.append("-").append(end); } sb.append("]"); - for (var i = 0; i < schema.getArgumentsCount(); i++) { - sb.append(" ").append(schema.getArgumentInfos()[i].getName()).append("="); - if (preAppliedArguments != null && preAppliedArguments[i] != null) { - sb.append(iop.toDisplayString(preAppliedArguments[i], false)); - } else { - sb.append("_"); + if (includeArguments) { + for (var i = 0; i < schema.getArgumentsCount(); i++) { + var name = schema.getArgumentInfos()[i].getName(); + sb.append(" ").append(name).append("="); + if (preAppliedArguments != null && preAppliedArguments[i] != null) { + sb.append(iop.toDisplayString(preAppliedArguments[i], false)); + } else { + sb.append("_"); + } } - } - if (schema.getOversaturatedArguments() != null) { - for (var i = 0; i < schema.getOversaturatedArguments().length; i++) { - if (oversaturatedArguments != null && oversaturatedArguments[i] != null) { - sb.append(" +").append(schema.getOversaturatedArguments()[i].getName()).append("="); - sb.append(iop.toDisplayString(oversaturatedArguments[i], false)); + if (schema.getOversaturatedArguments() != null) { + for (var i = 0; i < schema.getOversaturatedArguments().length; i++) { + if (oversaturatedArguments != null && oversaturatedArguments[i] != null) { + sb.append(" +").append(schema.getOversaturatedArguments()[i].getName()).append("="); + sb.append(iop.toDisplayString(oversaturatedArguments[i], false)); + } } } } diff --git a/test/Tests/src/Semantic/Error_Spec.enso b/test/Tests/src/Semantic/Error_Spec.enso index d686f8330861..62e0711fd57f 100644 --- a/test/Tests/src/Semantic/Error_Spec.enso +++ b/test/Tests/src/Semantic/Error_Spec.enso @@ -377,6 +377,19 @@ spec = Test.specify "try to apply two arguments with over-saturated" <| r = Panic.recover Type_Error <| neg (my_func z=10) r . should_fail_with Type_Error - r.to_display_text.contains "Try to apply x, y arguments" . should_be_true + r.to_display_text . should_contain "Try to apply x, y arguments" + + Test.specify "types and unapplied arguments" <| + c = C.Baz C.to_text + r = Panic.recover Type_Error <| neg (c.to_num c=3) + r . should_fail_with Type_Error + r.to_display_text . should_contain "Try to apply a, b arguments" + + + +type C + Baz x + +C.to_num self a b c = a+b+c main = Test_Suite.run_main spec