From da1b0289a68c7f3ccfb26494d5f107173fd96892 Mon Sep 17 00:00:00 2001 From: David Hua Date: Wed, 1 Mar 2023 04:55:00 -0500 Subject: [PATCH 1/7] Reword error messages to be more user friendly. --- .../tools/dotc/transform/init/Errors.scala | 8 ++--- .../tools/dotc/transform/init/Semantic.scala | 36 ++++++++++--------- 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/transform/init/Errors.scala b/compiler/src/dotty/tools/dotc/transform/init/Errors.scala index 762e029ba36f..366fd6be96a2 100644 --- a/compiler/src/dotty/tools/dotc/transform/init/Errors.scala +++ b/compiler/src/dotty/tools/dotc/transform/init/Errors.scala @@ -47,11 +47,11 @@ object Errors: case class AccessCold(field: Symbol)(val trace: Trace) extends Error: def show(using Context): String = - "Access field " + field.show + " on a cold object." + stacktrace + "Access field " + field.show + " on an uninitialized (Cold) object." + stacktrace case class CallCold(meth: Symbol)(val trace: Trace) extends Error: def show(using Context): String = - "Call method " + meth.show + " on a cold object." + stacktrace + "Call method " + meth.show + " on an uninitialized (Cold) object." + stacktrace case class CallUnknown(meth: Symbol)(val trace: Trace) extends Error: def show(using Context): String = @@ -62,7 +62,7 @@ object Errors: case class UnsafePromotion(msg: String, error: Error)(val trace: Trace) extends Error: def show(using Context): String = msg + stacktrace + "\n" + - "Promoting the value to hot (transitively initialized) failed due to the following problem:\n" + { + "Promoting the value to transitively initialized (Hot) failed due to the following problem:\n" + { val ctx2 = ctx.withProperty(IsFromPromotion, Some(true)) error.show(using ctx2) } @@ -96,5 +96,5 @@ object Errors: acc + text2 } val verb = if multiple then " are " else " is " - val adjective = "not hot (transitively initialized)." + val adjective = "not transitively initialized (Hot)." subject + verb + adjective diff --git a/compiler/src/dotty/tools/dotc/transform/init/Semantic.scala b/compiler/src/dotty/tools/dotc/transform/init/Semantic.scala index 286e3a124d12..a53a032f9fce 100644 --- a/compiler/src/dotty/tools/dotc/transform/init/Semantic.scala +++ b/compiler/src/dotty/tools/dotc/transform/init/Semantic.scala @@ -64,16 +64,18 @@ object Semantic: sealed abstract class Value: def show(using Context): String = this match case ThisRef(klass) => - "ThisRef[" + klass.show + "]" + "the original object of type " + klass.show + " that started this trace" case Warm(klass, outer, ctor, args) => val argsText = if args.nonEmpty then ", args = " + args.map(_.show).mkString("(", ", ", ")") else "" - "Warm[" + klass.show + "] { outer = " + outer.show + argsText + " }" + "an initialized (Warm) object of type " + klass.show + "{ outer = " + outer.show + argsText + " }" case Fun(expr, thisV, klass) => - "Fun { this = " + thisV.show + ", owner = " + klass.show + " }" + "a function { this = " + thisV.show + ", owner = " + klass.show + " }" case RefSet(values) => values.map(_.show).mkString("Set { ", ", ", " }") - case _ => - this.toString() + case Hot => + "a transitively initialized (Hot) object" + case Cold => + "an uninitialized (Cold) object" def isHot = this == Hot def isCold = this == Cold @@ -470,7 +472,7 @@ object Semantic: def widenArg: Contextual[Value] = a match case _: Ref | _: Fun => - val hasError = Reporter.hasErrors { a.promote("Argument cannot be promoted to hot") } + val hasError = Reporter.hasErrors { a.promote("Argument cannot be promoted to transitively initialized (Hot)") } if hasError then Cold else Hot case RefSet(refs) => @@ -707,7 +709,9 @@ object Semantic: // no source code available promoteArgs() // try promoting the receiver as last resort - val hasErrors = Reporter.hasErrors { ref.promote("try promote value to hot") } + val hasErrors = Reporter.hasErrors { + ref.promote(ref.show + " has no source code and could not be proven to be transitively initialized (Hot).") + } if hasErrors then val error = CallUnknown(target)(trace) reporter.report(error) @@ -992,7 +996,7 @@ object Semantic: eval(body, thisV, klass) } given Trace = Trace.empty.add(body) - res.promote("The function return value is not hot. Found = " + res.show + ".") + res.promote("Only transitively initialized (Hot) values can be returned by functions. The function " + fun.show + " returned " + res.show + ".") } if errors.nonEmpty then reporter.report(UnsafePromotion(msg, errors.head)(trace)) @@ -1036,7 +1040,7 @@ object Semantic: // // This invariant holds because of the Scala/Java/JVM restriction that we cannot use `this` in super constructor calls. if subClassSegmentHot && !isHotSegment then - report.error("[Internal error] Expect current segment to hot in promotion, current klass = " + klass.show + + report.error("[Internal error] Expect current segment to be transitively initialized (hot) in promotion, current klass = " + klass.show + ", subclass = " + subClass.show + Trace.show, Trace.position) // If the outer and parameters of a class are all hot, then accessing fields and methods of the current @@ -1053,12 +1057,12 @@ object Semantic: val args = member.info.paramInfoss.flatten.map(_ => new ArgInfo(Hot: Value, Trace.empty)) val res = warm.call(member, args, receiver = warm.klass.typeRef, superType = NoType) withTrace(trace.add(member.defTree)) { - res.promote("Cannot prove that the return value of " + member.show + " is hot. Found = " + res.show + ".") + res.promote("Could not verify that the return value of " + member.show + " is transitively initialized (Hot). It was found to be " + res.show + ".") } else val res = warm.select(member, receiver = warm.klass.typeRef) withTrace(trace.add(member.defTree)) { - res.promote("Cannot prove that the field " + member.show + " is hot. Found = " + res.show + ".") + res.promote("Could not verify that the field " + member.show + " is transitively initialized (Hot). It was found to be " + res.show + ".") } end for @@ -1144,7 +1148,7 @@ object Semantic: extension (arg: ArgInfo) def promote: Contextual[Unit] = withTrace(arg.trace) { - arg.value.promote("Cannot prove the method argument is hot. Only hot values are safe to leak.\nFound = " + arg.value.show + ".") + arg.value.promote("Could not verify that the method argument is transitively initialized (Hot). It was found to be " + arg.value.show + ". Only transitively initialized arguments may be passed to methods outside the analyzed initialization region.") } /** Evaluate an expression with the given value for `this` in a given class `klass` @@ -1285,12 +1289,12 @@ object Semantic: eval(qual, thisV, klass) val res = eval(rhs, thisV, klass) extendTrace(expr) { - res.ensureHot("The RHS of reassignment must be hot. Found = " + res.show + ". ") + res.ensureHot("The RHS of reassignment must be transitively initialized (Hot). It was found to be " + res.show + ". ") } case id: Ident => val res = eval(rhs, thisV, klass) extendTrace(expr) { - res.ensureHot("The RHS of reassignment must be hot. Found = " + res.show + ". ") + res.ensureHot("The RHS of reassignment must be transitively initialized (Hot). It was found to be " + res.show + ". ") } case closureDef(ddef) => @@ -1313,14 +1317,14 @@ object Semantic: case Match(selector, cases) => val res = eval(selector, thisV, klass) extendTrace(selector) { - res.ensureHot("The value to be matched needs to be hot. Found = " + res.show + ". ") + res.ensureHot("The value to be matched needs to be transitively initialized (Hot). It was found to be " + res.show + ". ") } eval(cases.map(_.body), thisV, klass).join case Return(expr, from) => val res = eval(expr, thisV, klass) extendTrace(expr) { - res.ensureHot("return expression must be hot. Found = " + res.show + ". ") + res.ensureHot("return expression must be transitively initialized (Hot). It was found to be " + res.show + ". ") } case WhileDo(cond, body) => From 585409a4d16aea90e60d2445595fa3c2798cc2c9 Mon Sep 17 00:00:00 2001 From: David Hua Date: Mon, 6 Mar 2023 04:20:17 -0500 Subject: [PATCH 2/7] Update check files, minor wording changes to error messages --- .../tools/dotc/transform/init/Semantic.scala | 8 ++-- tests/init/neg/closureLeak.check | 22 +++++------ tests/init/neg/cycle-structure.check | 8 ++-- tests/init/neg/default-this.check | 21 +++++----- tests/init/neg/i15363.check | 4 +- tests/init/neg/i15459.check | 17 ++++----- tests/init/neg/inherit-non-hot.check | 26 ++++++------- tests/init/neg/inlined-method.check | 17 ++++----- tests/init/neg/inner-first.check | 13 +++---- tests/init/neg/leak-warm.check | 2 +- tests/init/neg/promotion-loop.check | 21 +++++----- tests/init/neg/promotion-segment3.check | 15 ++++---- tests/init/neg/secondary-ctor4.check | 8 ++-- tests/init/neg/t3273.check | 38 +++++++++---------- tests/init/neg/unsound1.check | 2 +- tests/init/neg/unsound2.check | 2 +- tests/init/neg/unsound3.check | 2 +- 17 files changed, 108 insertions(+), 118 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/transform/init/Semantic.scala b/compiler/src/dotty/tools/dotc/transform/init/Semantic.scala index a53a032f9fce..727e54833063 100644 --- a/compiler/src/dotty/tools/dotc/transform/init/Semantic.scala +++ b/compiler/src/dotty/tools/dotc/transform/init/Semantic.scala @@ -64,7 +64,7 @@ object Semantic: sealed abstract class Value: def show(using Context): String = this match case ThisRef(klass) => - "the original object of type " + klass.show + " that started this trace" + "the original object of type \"" + klass.show + "\" that started this trace" case Warm(klass, outer, ctor, args) => val argsText = if args.nonEmpty then ", args = " + args.map(_.show).mkString("(", ", ", ")") else "" "an initialized (Warm) object of type " + klass.show + "{ outer = " + outer.show + argsText + " }" @@ -472,7 +472,7 @@ object Semantic: def widenArg: Contextual[Value] = a match case _: Ref | _: Fun => - val hasError = Reporter.hasErrors { a.promote("Argument cannot be promoted to transitively initialized (Hot)") } + val hasError = Reporter.hasErrors { a.promote("Argument cannot be proven to be transitively initialized (Hot)") } if hasError then Cold else Hot case RefSet(refs) => @@ -996,7 +996,7 @@ object Semantic: eval(body, thisV, klass) } given Trace = Trace.empty.add(body) - res.promote("Only transitively initialized (Hot) values can be returned by functions. The function " + fun.show + " returned " + res.show + ".") + res.promote("Only transitively initialized (Hot) values can be returned by functions. The function " + fun.show + " returns " + res.show + ".") } if errors.nonEmpty then reporter.report(UnsafePromotion(msg, errors.head)(trace)) @@ -1040,7 +1040,7 @@ object Semantic: // // This invariant holds because of the Scala/Java/JVM restriction that we cannot use `this` in super constructor calls. if subClassSegmentHot && !isHotSegment then - report.error("[Internal error] Expect current segment to be transitively initialized (hot) in promotion, current klass = " + klass.show + + report.error("[Internal error] Expect current segment to be transitively initialized (Hot) in promotion, current klass = " + klass.show + ", subclass = " + subClass.show + Trace.show, Trace.position) // If the outer and parameters of a class are all hot, then accessing fields and methods of the current diff --git a/tests/init/neg/closureLeak.check b/tests/init/neg/closureLeak.check index 7019f2274ab6..c4e85d7db4b0 100644 --- a/tests/init/neg/closureLeak.check +++ b/tests/init/neg/closureLeak.check @@ -1,16 +1,14 @@ -- Error: tests/init/neg/closureLeak.scala:11:14 ----------------------------------------------------------------------- 11 | l.foreach(a => a.addX(this)) // error | ^^^^^^^^^^^^^^^^^ - | Cannot prove the method argument is hot. Only hot values are safe to leak. - | Found = Fun { this = ThisRef[class Outer], owner = class Outer }. Calling trace: - | -> class Outer { [ closureLeak.scala:1 ] - | ^ - | -> l.foreach(a => a.addX(this)) // error [ closureLeak.scala:11 ] - | ^^^^^^^^^^^^^^^^^ + |Could not verify that the method argument is transitively initialized (Hot). It was found to be a function { this = the original object of type "class Outer" that started this trace, owner = class Outer }. Only transitively initialized arguments may be passed to methods outside the analyzed initialization region. Calling trace: + |-> class Outer { [ closureLeak.scala:1 ] + | ^ + |-> l.foreach(a => a.addX(this)) // error [ closureLeak.scala:11 ] + | ^^^^^^^^^^^^^^^^^ | - | Promoting the value to hot (transitively initialized) failed due to the following problem: - | Cannot prove the method argument is hot. Only hot values are safe to leak. - | Found = ThisRef[class Outer]. - | Non initialized field(s): value p. Promotion trace: - | -> l.foreach(a => a.addX(this)) // error [ closureLeak.scala:11 ] - | ^^^^ + |Promoting the value to transitively initialized (Hot) failed due to the following problem: + |Could not verify that the method argument is transitively initialized (Hot). It was found to be the original object of type "class Outer" that started this trace. Only transitively initialized arguments may be passed to methods outside the analyzed initialization region. + |Non initialized field(s): value p. Promotion trace: + |-> l.foreach(a => a.addX(this)) // error [ closureLeak.scala:11 ] + | ^^^^ diff --git a/tests/init/neg/cycle-structure.check b/tests/init/neg/cycle-structure.check index fb7b54c7cac2..dfe7c9b85e2f 100644 --- a/tests/init/neg/cycle-structure.check +++ b/tests/init/neg/cycle-structure.check @@ -1,14 +1,14 @@ -- Error: tests/init/neg/cycle-structure.scala:3:13 -------------------------------------------------------------------- 3 | val x = B(this) // error | ^^^^^^^ - | Problematic object instantiation: arg 1 is not hot (transitively initialized). Calling trace: + | Problematic object instantiation: arg 1 is not transitively initialized (Hot). Calling trace: | -> case class A(b: B) { [ cycle-structure.scala:1 ] | ^ | -> val x = B(this) // error [ cycle-structure.scala:3 ] | ^^^^^^^ | | It leads to the following error during object initialization: - | Access field value x on a cold object. Calling trace: + | Access field value x on an uninitialized (Cold) object. Calling trace: | -> case class B(a: A) { [ cycle-structure.scala:7 ] | ^ | -> val x1 = a.x [ cycle-structure.scala:8 ] @@ -16,14 +16,14 @@ -- Error: tests/init/neg/cycle-structure.scala:9:13 -------------------------------------------------------------------- 9 | val x = A(this) // error | ^^^^^^^ - | Problematic object instantiation: arg 1 is not hot (transitively initialized). Calling trace: + | Problematic object instantiation: arg 1 is not transitively initialized (Hot). Calling trace: | -> case class B(a: A) { [ cycle-structure.scala:7 ] | ^ | -> val x = A(this) // error [ cycle-structure.scala:9 ] | ^^^^^^^ | | It leads to the following error during object initialization: - | Access field value x on a cold object. Calling trace: + | Access field value x on an uninitialized (Cold) object. Calling trace: | -> case class A(b: B) { [ cycle-structure.scala:1 ] | ^ | -> val x1 = b.x [ cycle-structure.scala:2 ] diff --git a/tests/init/neg/default-this.check b/tests/init/neg/default-this.check index 6d08a64450d4..873a83427aed 100644 --- a/tests/init/neg/default-this.check +++ b/tests/init/neg/default-this.check @@ -1,14 +1,13 @@ -- Error: tests/init/neg/default-this.scala:9:8 ------------------------------------------------------------------------ 9 | compare() // error | ^^^^^^^ - | Cannot prove the method argument is hot. Only hot values are safe to leak. - | Found = ThisRef[class B]. - | Non initialized field(s): value result. Calling trace: - | -> class B extends A { [ default-this.scala:6 ] - | ^ - | -> val result = updateThenCompare(5) [ default-this.scala:11 ] - | ^^^^^^^^^^^^^^^^^^^^ - | -> def updateThenCompare(c: Int): Boolean = { [ default-this.scala:7 ] - | ^ - | -> compare() // error [ default-this.scala:9 ] - | ^^^^^^^ + |Could not verify that the method argument is transitively initialized (Hot). It was found to be the original object of type "class B" that started this trace. Only transitively initialized arguments may be passed to methods outside the analyzed initialization region. + |Non initialized field(s): value result. Calling trace: + |-> class B extends A { [ default-this.scala:6 ] + | ^ + |-> val result = updateThenCompare(5) [ default-this.scala:11 ] + | ^^^^^^^^^^^^^^^^^^^^ + |-> def updateThenCompare(c: Int): Boolean = { [ default-this.scala:7 ] + | ^ + |-> compare() // error [ default-this.scala:9 ] + | ^^^^^^^ diff --git a/tests/init/neg/i15363.check b/tests/init/neg/i15363.check index 84cf268ef8a1..9912aa186a5b 100644 --- a/tests/init/neg/i15363.check +++ b/tests/init/neg/i15363.check @@ -1,14 +1,14 @@ -- Error: tests/init/neg/i15363.scala:3:10 ----------------------------------------------------------------------------- 3 | val b = new B(this) // error | ^^^^^^^^^^^ - | Problematic object instantiation: arg 1 is not hot (transitively initialized). Calling trace: + | Problematic object instantiation: arg 1 is not transitively initialized (Hot). Calling trace: | -> class A: [ i15363.scala:1 ] | ^ | -> val b = new B(this) // error [ i15363.scala:3 ] | ^^^^^^^^^^^ | | It leads to the following error during object initialization: - | Access field value m on a cold object. Calling trace: + | Access field value m on an uninitialized (Cold) object. Calling trace: | -> class B(a: A): [ i15363.scala:7 ] | ^ | -> val x = a.m [ i15363.scala:8 ] diff --git a/tests/init/neg/i15459.check b/tests/init/neg/i15459.check index 93ba28554895..a4ba1bacf3a2 100644 --- a/tests/init/neg/i15459.check +++ b/tests/init/neg/i15459.check @@ -1,12 +1,11 @@ -- Error: tests/init/neg/i15459.scala:3:10 ----------------------------------------------------------------------------- 3 | println(this) // error | ^^^^ - | Cannot prove the method argument is hot. Only hot values are safe to leak. - | Found = ThisRef[class Sub]. - | Non initialized field(s): value b. Calling trace: - | -> class Sub extends Sup: [ i15459.scala:5 ] - | ^ - | -> class Sup: [ i15459.scala:1 ] - | ^ - | -> println(this) // error [ i15459.scala:3 ] - | ^^^^ + |Could not verify that the method argument is transitively initialized (Hot). It was found to be the original object of type "class Sub" that started this trace. Only transitively initialized arguments may be passed to methods outside the analyzed initialization region. + |Non initialized field(s): value b. Calling trace: + |-> class Sub extends Sup: [ i15459.scala:5 ] + | ^ + |-> class Sup: [ i15459.scala:1 ] + | ^ + |-> println(this) // error [ i15459.scala:3 ] + | ^^^^ diff --git a/tests/init/neg/inherit-non-hot.check b/tests/init/neg/inherit-non-hot.check index 408196333a27..a62641473ab2 100644 --- a/tests/init/neg/inherit-non-hot.check +++ b/tests/init/neg/inherit-non-hot.check @@ -1,17 +1,17 @@ -- Error: tests/init/neg/inherit-non-hot.scala:6:32 -------------------------------------------------------------------- 6 | if b == null then b = new B(this) // error | ^^^^^^^^^^^^^^^ - | The RHS of reassignment must be hot. Found = Warm[class B] { outer = Hot, args = (Cold) }. Calling trace: - | -> class C extends A { [ inherit-non-hot.scala:15 ] - | ^ - | -> val bAgain = toB.getBAgain [ inherit-non-hot.scala:16 ] - | ^^^ - | -> def toB: B = [ inherit-non-hot.scala:5 ] - | ^ - | -> if b == null then b = new B(this) // error [ inherit-non-hot.scala:6 ] - | ^^^^^^^^^^^^^^^ + |The RHS of reassignment must be transitively initialized (Hot). It was found to be an initialized (Warm) object of type class B{ outer = a transitively initialized (Hot) object, args = (an uninitialized (Cold) object) }. Calling trace: + |-> class C extends A { [ inherit-non-hot.scala:15 ] + | ^ + |-> val bAgain = toB.getBAgain [ inherit-non-hot.scala:16 ] + | ^^^ + |-> def toB: B = [ inherit-non-hot.scala:5 ] + | ^ + |-> if b == null then b = new B(this) // error [ inherit-non-hot.scala:6 ] + | ^^^^^^^^^^^^^^^ | - | Promoting the value to hot (transitively initialized) failed due to the following problem: - | Cannot prove that the field value a is hot. Found = Cold. Promotion trace: - | -> class B(a: A) { [ inherit-non-hot.scala:10 ] - | ^^^^ + |Promoting the value to transitively initialized (Hot) failed due to the following problem: + |Could not verify that the field value a is transitively initialized (Hot). It was found to be an uninitialized (Cold) object. Promotion trace: + |-> class B(a: A) { [ inherit-non-hot.scala:10 ] + | ^^^^ diff --git a/tests/init/neg/inlined-method.check b/tests/init/neg/inlined-method.check index 62bec184b825..d202c668b9b4 100644 --- a/tests/init/neg/inlined-method.check +++ b/tests/init/neg/inlined-method.check @@ -1,12 +1,11 @@ -- Error: tests/init/neg/inlined-method.scala:8:45 --------------------------------------------------------------------- 8 | scala.runtime.Scala3RunTime.assertFailed(message) // error | ^^^^^^^ - | Cannot prove the method argument is hot. Only hot values are safe to leak. - | Found = ThisRef[class InlineError]. - | Non initialized field(s): value v. Calling trace: - | -> class InlineError { [ inlined-method.scala:1 ] - | ^ - | -> Assertion.failAssert(this) [ inlined-method.scala:2 ] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -> scala.runtime.Scala3RunTime.assertFailed(message) // error [ inlined-method.scala:8 ] - | ^^^^^^^ + |Could not verify that the method argument is transitively initialized (Hot). It was found to be the original object of type "class InlineError" that started this trace. Only transitively initialized arguments may be passed to methods outside the analyzed initialization region. + |Non initialized field(s): value v. Calling trace: + |-> class InlineError { [ inlined-method.scala:1 ] + | ^ + |-> Assertion.failAssert(this) [ inlined-method.scala:2 ] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + |-> scala.runtime.Scala3RunTime.assertFailed(message) // error [ inlined-method.scala:8 ] + | ^^^^^^^ diff --git a/tests/init/neg/inner-first.check b/tests/init/neg/inner-first.check index e1df69fbd4a2..5719cf56d9aa 100644 --- a/tests/init/neg/inner-first.check +++ b/tests/init/neg/inner-first.check @@ -1,10 +1,9 @@ -- Error: tests/init/neg/inner-first.scala:3:12 ------------------------------------------------------------------------ 3 | println(this) // error | ^^^^ - | Cannot prove the method argument is hot. Only hot values are safe to leak. - | Found = ThisRef[class B]. - | Non initialized field(s): value n. Calling trace: - | -> class B: [ inner-first.scala:2 ] - | ^ - | -> println(this) // error [ inner-first.scala:3 ] - | ^^^^ + |Could not verify that the method argument is transitively initialized (Hot). It was found to be the original object of type "class B" that started this trace. Only transitively initialized arguments may be passed to methods outside the analyzed initialization region. + |Non initialized field(s): value n. Calling trace: + |-> class B: [ inner-first.scala:2 ] + | ^ + |-> println(this) // error [ inner-first.scala:3 ] + | ^^^^ diff --git a/tests/init/neg/leak-warm.check b/tests/init/neg/leak-warm.check index d4d563fc456e..c2fc561a3668 100644 --- a/tests/init/neg/leak-warm.check +++ b/tests/init/neg/leak-warm.check @@ -1,7 +1,7 @@ -- Error: tests/init/neg/leak-warm.scala:19:18 ------------------------------------------------------------------------- 19 | val l2 = l.map(_.m()) // error | ^^^^^^^^^^^^ - | Call method method map on a cold object. Calling trace: + | Call method method map on an uninitialized (Cold) object. Calling trace: | -> object leakWarm { [ leak-warm.scala:1 ] | ^ | -> val l2 = l.map(_.m()) // error [ leak-warm.scala:19 ] diff --git a/tests/init/neg/promotion-loop.check b/tests/init/neg/promotion-loop.check index 3d1eb7e74aec..9f67434be26a 100644 --- a/tests/init/neg/promotion-loop.check +++ b/tests/init/neg/promotion-loop.check @@ -1,15 +1,14 @@ -- Error: tests/init/neg/promotion-loop.scala:16:10 -------------------------------------------------------------------- 16 | println(b) // error | ^ - | Cannot prove the method argument is hot. Only hot values are safe to leak. - | Found = Warm[class B] { outer = ThisRef[class Test] }. Calling trace: - | -> class Test { test => [ promotion-loop.scala:1 ] - | ^ - | -> println(b) // error [ promotion-loop.scala:16 ] - | ^ + |Could not verify that the method argument is transitively initialized (Hot). It was found to be an initialized (Warm) object of type class B{ outer = the original object of type "class Test" that started this trace }. Only transitively initialized arguments may be passed to methods outside the analyzed initialization region. Calling trace: + |-> class Test { test => [ promotion-loop.scala:1 ] + | ^ + |-> println(b) // error [ promotion-loop.scala:16 ] + | ^ | - | Promoting the value to hot (transitively initialized) failed due to the following problem: - | Cannot prove that the field value outer is hot. Found = ThisRef[class Test]. - | Non initialized field(s): value n. Promotion trace: - | -> val outer = test [ promotion-loop.scala:12 ] - | ^^^^^^^^^^^^^^^^ + |Promoting the value to transitively initialized (Hot) failed due to the following problem: + |Could not verify that the field value outer is transitively initialized (Hot). It was found to be the original object of type "class Test" that started this trace. + |Non initialized field(s): value n. Promotion trace: + |-> val outer = test [ promotion-loop.scala:12 ] + | ^^^^^^^^^^^^^^^^ diff --git a/tests/init/neg/promotion-segment3.check b/tests/init/neg/promotion-segment3.check index 220af18bd29a..b334439b4168 100644 --- a/tests/init/neg/promotion-segment3.check +++ b/tests/init/neg/promotion-segment3.check @@ -1,12 +1,11 @@ -- Error: tests/init/neg/promotion-segment3.scala:9:6 ------------------------------------------------------------------ 9 | bar(new B) // error | ^^^^^ - | Cannot prove the method argument is hot. Only hot values are safe to leak. - | Found = Warm[class B] { outer = ThisRef[class A] }. Calling trace: - | -> class A: [ promotion-segment3.scala:2 ] - | ^ - | -> bar(new B) // error [ promotion-segment3.scala:9 ] - | ^^^^^ + |Could not verify that the method argument is transitively initialized (Hot). It was found to be an initialized (Warm) object of type class B{ outer = the original object of type "class A" that started this trace }. Only transitively initialized arguments may be passed to methods outside the analyzed initialization region. Calling trace: + |-> class A: [ promotion-segment3.scala:2 ] + | ^ + |-> bar(new B) // error [ promotion-segment3.scala:9 ] + | ^^^^^ | - | Promoting the value to hot (transitively initialized) failed due to the following problem: - | Promotion cancelled as the value contains inner class C. + |Promoting the value to transitively initialized (Hot) failed due to the following problem: + |Promotion cancelled as the value contains inner class C. diff --git a/tests/init/neg/secondary-ctor4.check b/tests/init/neg/secondary-ctor4.check index 1bf1a7286357..e867ba65ded5 100644 --- a/tests/init/neg/secondary-ctor4.check +++ b/tests/init/neg/secondary-ctor4.check @@ -1,14 +1,14 @@ -- Error: tests/init/neg/secondary-ctor4.scala:54:14 ------------------------------------------------------------------- 54 | val c = new C(b, 5) // error | ^^^^^^^^^^^ - | Problematic object instantiation: arg 1 is not hot (transitively initialized). Calling trace: + | Problematic object instantiation: arg 1 is not transitively initialized (Hot). Calling trace: | -> class D { [ secondary-ctor4.scala:52 ] | ^ | -> val c = new C(b, 5) // error [ secondary-ctor4.scala:54 ] | ^^^^^^^^^^^ | | It leads to the following error during object initialization: - | Access field value n on a cold object. Calling trace: + | Access field value n on an uninitialized (Cold) object. Calling trace: | -> def this(b: B, x: Int) = this(b) [ secondary-ctor4.scala:49 ] | ^^^^^^^ | -> class C(b: B) extends A(b) with T { [ secondary-ctor4.scala:48 ] @@ -24,7 +24,7 @@ -- Error: tests/init/neg/secondary-ctor4.scala:42:4 -------------------------------------------------------------------- 42 | new A(new B(new D)) // error | ^^^^^^^^^^^^^^^^^^^ - |Problematic object instantiation: the outer M.this and arg 1 are not hot (transitively initialized). Calling trace: + |Problematic object instantiation: the outer M.this and arg 1 are not transitively initialized (Hot). Calling trace: |-> class N(d: D) extends M(d) { [ secondary-ctor4.scala:59 ] | ^ |-> def this(d: D) = { [ secondary-ctor4.scala:7 ] @@ -33,7 +33,7 @@ | ^^^^^^^^^^^^^^^^^^^ | |It leads to the following error during object initialization: - |Access field value n on a cold object. Calling trace: + |Access field value n on an uninitialized (Cold) object. Calling trace: |-> def this(b: B) = { [ secondary-ctor4.scala:17 ] | ^ |-> Inner().foo() [ secondary-ctor4.scala:26 ] diff --git a/tests/init/neg/t3273.check b/tests/init/neg/t3273.check index e548a5964cac..b5d4c30822a7 100644 --- a/tests/init/neg/t3273.check +++ b/tests/init/neg/t3273.check @@ -1,28 +1,26 @@ -- Error: tests/init/neg/t3273.scala:4:42 ------------------------------------------------------------------------------ 4 | val num1: LazyList[Int] = 1 #:: num1.map(_ + 1) // error | ^^^^^^^^^^^^^^^ - | Cannot prove the method argument is hot. Only hot values are safe to leak. - | Found = Fun { this = ThisRef[object Test], owner = object Test }. Calling trace: - | -> object Test { [ t3273.scala:3 ] - | ^ - | -> val num1: LazyList[Int] = 1 #:: num1.map(_ + 1) // error [ t3273.scala:4 ] - | ^^^^^^^^^^^^^^^ + |Could not verify that the method argument is transitively initialized (Hot). It was found to be a function { this = the original object of type "object Test" that started this trace, owner = object Test }. Only transitively initialized arguments may be passed to methods outside the analyzed initialization region. Calling trace: + |-> object Test { [ t3273.scala:3 ] + | ^ + |-> val num1: LazyList[Int] = 1 #:: num1.map(_ + 1) // error [ t3273.scala:4 ] + | ^^^^^^^^^^^^^^^ | - | Promoting the value to hot (transitively initialized) failed due to the following problem: - | Access non-initialized value num1. Promotion trace: - | -> val num1: LazyList[Int] = 1 #:: num1.map(_ + 1) // error [ t3273.scala:4 ] - | ^^^^ + |Promoting the value to transitively initialized (Hot) failed due to the following problem: + |Access non-initialized value num1. Promotion trace: + |-> val num1: LazyList[Int] = 1 #:: num1.map(_ + 1) // error [ t3273.scala:4 ] + | ^^^^ -- Error: tests/init/neg/t3273.scala:5:61 ------------------------------------------------------------------------------ 5 | val num2: LazyList[Int] = 1 #:: num2.iterator.map(_ + 1).to(LazyList) // error | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | Cannot prove the method argument is hot. Only hot values are safe to leak. - | Found = Fun { this = ThisRef[object Test], owner = object Test }. Calling trace: - | -> object Test { [ t3273.scala:3 ] - | ^ - | -> val num2: LazyList[Int] = 1 #:: num2.iterator.map(_ + 1).to(LazyList) // error [ t3273.scala:5 ] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + |Could not verify that the method argument is transitively initialized (Hot). It was found to be a function { this = the original object of type "object Test" that started this trace, owner = object Test }. Only transitively initialized arguments may be passed to methods outside the analyzed initialization region. Calling trace: + |-> object Test { [ t3273.scala:3 ] + | ^ + |-> val num2: LazyList[Int] = 1 #:: num2.iterator.map(_ + 1).to(LazyList) // error [ t3273.scala:5 ] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - | Promoting the value to hot (transitively initialized) failed due to the following problem: - | Access non-initialized value num2. Promotion trace: - | -> val num2: LazyList[Int] = 1 #:: num2.iterator.map(_ + 1).to(LazyList) // error [ t3273.scala:5 ] - | ^^^^ + |Promoting the value to transitively initialized (Hot) failed due to the following problem: + |Access non-initialized value num2. Promotion trace: + |-> val num2: LazyList[Int] = 1 #:: num2.iterator.map(_ + 1).to(LazyList) // error [ t3273.scala:5 ] + | ^^^^ diff --git a/tests/init/neg/unsound1.check b/tests/init/neg/unsound1.check index c3057a6a6067..d114ba072db6 100644 --- a/tests/init/neg/unsound1.check +++ b/tests/init/neg/unsound1.check @@ -1,7 +1,7 @@ -- Error: tests/init/neg/unsound1.scala:2:35 --------------------------------------------------------------------------- 2 | if (m > 0) println(foo(m - 1).a2.n) // error | ^^^^^^^^^^^^^^^ - | Access field variable n on a cold object. Calling trace: + | Access field variable n on an uninitialized (Cold) object. Calling trace: | -> class A(m: Int) { [ unsound1.scala:1 ] | ^ | -> if (m > 0) println(foo(m - 1).a2.n) // error [ unsound1.scala:2 ] diff --git a/tests/init/neg/unsound2.check b/tests/init/neg/unsound2.check index a90b16c8bf71..69d1278e94df 100644 --- a/tests/init/neg/unsound2.check +++ b/tests/init/neg/unsound2.check @@ -1,7 +1,7 @@ -- Error: tests/init/neg/unsound2.scala:5:26 --------------------------------------------------------------------------- 5 | def getN: Int = a.n // error | ^^^ - | Access field value n on a cold object. Calling trace: + | Access field value n on an uninitialized (Cold) object. Calling trace: | -> case class A(x: Int) { [ unsound2.scala:1 ] | ^ | -> println(foo(x).getB) [ unsound2.scala:8 ] diff --git a/tests/init/neg/unsound3.check b/tests/init/neg/unsound3.check index d62b97e1abaf..c32e66272d1a 100644 --- a/tests/init/neg/unsound3.check +++ b/tests/init/neg/unsound3.check @@ -1,7 +1,7 @@ -- Error: tests/init/neg/unsound3.scala:10:38 -------------------------------------------------------------------------- 10 | if (x < 12) then foo().getC().b else newB // error | ^^^^^^^^^^^^^^ - | Access field value b on a cold object. Calling trace: + | Access field value b on an uninitialized (Cold) object. Calling trace: | -> class C { [ unsound3.scala:5 ] | ^ | -> val b = foo() [ unsound3.scala:12 ] From 4cc629ec06ea6bbd678bd06294eae16ce86a6186 Mon Sep 17 00:00:00 2001 From: David Hua Date: Mon, 6 Mar 2023 23:00:09 -0500 Subject: [PATCH 3/7] Reword the stringified versions of some objects --- compiler/src/dotty/tools/dotc/transform/init/Semantic.scala | 4 ++-- tests/init/neg/closureLeak.check | 4 ++-- tests/init/neg/default-this.check | 2 +- tests/init/neg/i15459.check | 2 +- tests/init/neg/inlined-method.check | 2 +- tests/init/neg/inner-first.check | 2 +- tests/init/neg/promotion-loop.check | 4 ++-- tests/init/neg/promotion-segment3.check | 2 +- tests/init/neg/t3273.check | 4 ++-- 9 files changed, 13 insertions(+), 13 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/transform/init/Semantic.scala b/compiler/src/dotty/tools/dotc/transform/init/Semantic.scala index 727e54833063..60f0266d7ede 100644 --- a/compiler/src/dotty/tools/dotc/transform/init/Semantic.scala +++ b/compiler/src/dotty/tools/dotc/transform/init/Semantic.scala @@ -64,12 +64,12 @@ object Semantic: sealed abstract class Value: def show(using Context): String = this match case ThisRef(klass) => - "the original object of type \"" + klass.show + "\" that started this trace" + "the original object of type \"" + klass.show + "\" where initialization checking started" case Warm(klass, outer, ctor, args) => val argsText = if args.nonEmpty then ", args = " + args.map(_.show).mkString("(", ", ", ")") else "" "an initialized (Warm) object of type " + klass.show + "{ outer = " + outer.show + argsText + " }" case Fun(expr, thisV, klass) => - "a function { this = " + thisV.show + ", owner = " + klass.show + " }" + "a function where \"this\" is " + thisV.show + " and the function owner is an object of type " + klass.show case RefSet(values) => values.map(_.show).mkString("Set { ", ", ", " }") case Hot => diff --git a/tests/init/neg/closureLeak.check b/tests/init/neg/closureLeak.check index c4e85d7db4b0..19292f535fd1 100644 --- a/tests/init/neg/closureLeak.check +++ b/tests/init/neg/closureLeak.check @@ -1,14 +1,14 @@ -- Error: tests/init/neg/closureLeak.scala:11:14 ----------------------------------------------------------------------- 11 | l.foreach(a => a.addX(this)) // error | ^^^^^^^^^^^^^^^^^ - |Could not verify that the method argument is transitively initialized (Hot). It was found to be a function { this = the original object of type "class Outer" that started this trace, owner = class Outer }. Only transitively initialized arguments may be passed to methods outside the analyzed initialization region. Calling trace: + |Could not verify that the method argument is transitively initialized (Hot). It was found to be a function where "this" is the original object of type "class Outer" where initialization checking started and the function owner is an object of type class Outer. Only transitively initialized arguments may be passed to methods outside the analyzed initialization region. Calling trace: |-> class Outer { [ closureLeak.scala:1 ] | ^ |-> l.foreach(a => a.addX(this)) // error [ closureLeak.scala:11 ] | ^^^^^^^^^^^^^^^^^ | |Promoting the value to transitively initialized (Hot) failed due to the following problem: - |Could not verify that the method argument is transitively initialized (Hot). It was found to be the original object of type "class Outer" that started this trace. Only transitively initialized arguments may be passed to methods outside the analyzed initialization region. + |Could not verify that the method argument is transitively initialized (Hot). It was found to be the original object of type "class Outer" where initialization checking started. Only transitively initialized arguments may be passed to methods outside the analyzed initialization region. |Non initialized field(s): value p. Promotion trace: |-> l.foreach(a => a.addX(this)) // error [ closureLeak.scala:11 ] | ^^^^ diff --git a/tests/init/neg/default-this.check b/tests/init/neg/default-this.check index 873a83427aed..384efdf5414e 100644 --- a/tests/init/neg/default-this.check +++ b/tests/init/neg/default-this.check @@ -1,7 +1,7 @@ -- Error: tests/init/neg/default-this.scala:9:8 ------------------------------------------------------------------------ 9 | compare() // error | ^^^^^^^ - |Could not verify that the method argument is transitively initialized (Hot). It was found to be the original object of type "class B" that started this trace. Only transitively initialized arguments may be passed to methods outside the analyzed initialization region. + |Could not verify that the method argument is transitively initialized (Hot). It was found to be the original object of type "class B" where initialization checking started. Only transitively initialized arguments may be passed to methods outside the analyzed initialization region. |Non initialized field(s): value result. Calling trace: |-> class B extends A { [ default-this.scala:6 ] | ^ diff --git a/tests/init/neg/i15459.check b/tests/init/neg/i15459.check index a4ba1bacf3a2..e25d7efadda2 100644 --- a/tests/init/neg/i15459.check +++ b/tests/init/neg/i15459.check @@ -1,7 +1,7 @@ -- Error: tests/init/neg/i15459.scala:3:10 ----------------------------------------------------------------------------- 3 | println(this) // error | ^^^^ - |Could not verify that the method argument is transitively initialized (Hot). It was found to be the original object of type "class Sub" that started this trace. Only transitively initialized arguments may be passed to methods outside the analyzed initialization region. + |Could not verify that the method argument is transitively initialized (Hot). It was found to be the original object of type "class Sub" where initialization checking started. Only transitively initialized arguments may be passed to methods outside the analyzed initialization region. |Non initialized field(s): value b. Calling trace: |-> class Sub extends Sup: [ i15459.scala:5 ] | ^ diff --git a/tests/init/neg/inlined-method.check b/tests/init/neg/inlined-method.check index d202c668b9b4..dce46d3d7b5a 100644 --- a/tests/init/neg/inlined-method.check +++ b/tests/init/neg/inlined-method.check @@ -1,7 +1,7 @@ -- Error: tests/init/neg/inlined-method.scala:8:45 --------------------------------------------------------------------- 8 | scala.runtime.Scala3RunTime.assertFailed(message) // error | ^^^^^^^ - |Could not verify that the method argument is transitively initialized (Hot). It was found to be the original object of type "class InlineError" that started this trace. Only transitively initialized arguments may be passed to methods outside the analyzed initialization region. + |Could not verify that the method argument is transitively initialized (Hot). It was found to be the original object of type "class InlineError" where initialization checking started. Only transitively initialized arguments may be passed to methods outside the analyzed initialization region. |Non initialized field(s): value v. Calling trace: |-> class InlineError { [ inlined-method.scala:1 ] | ^ diff --git a/tests/init/neg/inner-first.check b/tests/init/neg/inner-first.check index 5719cf56d9aa..62bc8c3c4668 100644 --- a/tests/init/neg/inner-first.check +++ b/tests/init/neg/inner-first.check @@ -1,7 +1,7 @@ -- Error: tests/init/neg/inner-first.scala:3:12 ------------------------------------------------------------------------ 3 | println(this) // error | ^^^^ - |Could not verify that the method argument is transitively initialized (Hot). It was found to be the original object of type "class B" that started this trace. Only transitively initialized arguments may be passed to methods outside the analyzed initialization region. + |Could not verify that the method argument is transitively initialized (Hot). It was found to be the original object of type "class B" where initialization checking started. Only transitively initialized arguments may be passed to methods outside the analyzed initialization region. |Non initialized field(s): value n. Calling trace: |-> class B: [ inner-first.scala:2 ] | ^ diff --git a/tests/init/neg/promotion-loop.check b/tests/init/neg/promotion-loop.check index 9f67434be26a..73adb08e282c 100644 --- a/tests/init/neg/promotion-loop.check +++ b/tests/init/neg/promotion-loop.check @@ -1,14 +1,14 @@ -- Error: tests/init/neg/promotion-loop.scala:16:10 -------------------------------------------------------------------- 16 | println(b) // error | ^ - |Could not verify that the method argument is transitively initialized (Hot). It was found to be an initialized (Warm) object of type class B{ outer = the original object of type "class Test" that started this trace }. Only transitively initialized arguments may be passed to methods outside the analyzed initialization region. Calling trace: + |Could not verify that the method argument is transitively initialized (Hot). It was found to be an initialized (Warm) object of type class B{ outer = the original object of type "class Test" where initialization checking started }. Only transitively initialized arguments may be passed to methods outside the analyzed initialization region. Calling trace: |-> class Test { test => [ promotion-loop.scala:1 ] | ^ |-> println(b) // error [ promotion-loop.scala:16 ] | ^ | |Promoting the value to transitively initialized (Hot) failed due to the following problem: - |Could not verify that the field value outer is transitively initialized (Hot). It was found to be the original object of type "class Test" that started this trace. + |Could not verify that the field value outer is transitively initialized (Hot). It was found to be the original object of type "class Test" where initialization checking started. |Non initialized field(s): value n. Promotion trace: |-> val outer = test [ promotion-loop.scala:12 ] | ^^^^^^^^^^^^^^^^ diff --git a/tests/init/neg/promotion-segment3.check b/tests/init/neg/promotion-segment3.check index b334439b4168..40747b94f41d 100644 --- a/tests/init/neg/promotion-segment3.check +++ b/tests/init/neg/promotion-segment3.check @@ -1,7 +1,7 @@ -- Error: tests/init/neg/promotion-segment3.scala:9:6 ------------------------------------------------------------------ 9 | bar(new B) // error | ^^^^^ - |Could not verify that the method argument is transitively initialized (Hot). It was found to be an initialized (Warm) object of type class B{ outer = the original object of type "class A" that started this trace }. Only transitively initialized arguments may be passed to methods outside the analyzed initialization region. Calling trace: + |Could not verify that the method argument is transitively initialized (Hot). It was found to be an initialized (Warm) object of type class B{ outer = the original object of type "class A" where initialization checking started }. Only transitively initialized arguments may be passed to methods outside the analyzed initialization region. Calling trace: |-> class A: [ promotion-segment3.scala:2 ] | ^ |-> bar(new B) // error [ promotion-segment3.scala:9 ] diff --git a/tests/init/neg/t3273.check b/tests/init/neg/t3273.check index b5d4c30822a7..4b8d3e2521e0 100644 --- a/tests/init/neg/t3273.check +++ b/tests/init/neg/t3273.check @@ -1,7 +1,7 @@ -- Error: tests/init/neg/t3273.scala:4:42 ------------------------------------------------------------------------------ 4 | val num1: LazyList[Int] = 1 #:: num1.map(_ + 1) // error | ^^^^^^^^^^^^^^^ - |Could not verify that the method argument is transitively initialized (Hot). It was found to be a function { this = the original object of type "object Test" that started this trace, owner = object Test }. Only transitively initialized arguments may be passed to methods outside the analyzed initialization region. Calling trace: + |Could not verify that the method argument is transitively initialized (Hot). It was found to be a function where "this" is the original object of type "object Test" where initialization checking started and the function owner is an object of type object Test. Only transitively initialized arguments may be passed to methods outside the analyzed initialization region. Calling trace: |-> object Test { [ t3273.scala:3 ] | ^ |-> val num1: LazyList[Int] = 1 #:: num1.map(_ + 1) // error [ t3273.scala:4 ] @@ -14,7 +14,7 @@ -- Error: tests/init/neg/t3273.scala:5:61 ------------------------------------------------------------------------------ 5 | val num2: LazyList[Int] = 1 #:: num2.iterator.map(_ + 1).to(LazyList) // error | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - |Could not verify that the method argument is transitively initialized (Hot). It was found to be a function { this = the original object of type "object Test" that started this trace, owner = object Test }. Only transitively initialized arguments may be passed to methods outside the analyzed initialization region. Calling trace: + |Could not verify that the method argument is transitively initialized (Hot). It was found to be a function where "this" is the original object of type "object Test" where initialization checking started and the function owner is an object of type object Test. Only transitively initialized arguments may be passed to methods outside the analyzed initialization region. Calling trace: |-> object Test { [ t3273.scala:3 ] | ^ |-> val num2: LazyList[Int] = 1 #:: num2.iterator.map(_ + 1).to(LazyList) // error [ t3273.scala:5 ] From 6f229802cf1eb128c0128c5bf5e59c5422739634 Mon Sep 17 00:00:00 2001 From: David Hua Date: Mon, 6 Mar 2023 23:08:19 -0500 Subject: [PATCH 4/7] Add parentheses to make warnings more clear --- compiler/src/dotty/tools/dotc/transform/init/Semantic.scala | 6 +++--- tests/init/neg/closureLeak.check | 4 ++-- tests/init/neg/default-this.check | 2 +- tests/init/neg/i15459.check | 2 +- tests/init/neg/inherit-non-hot.check | 2 +- tests/init/neg/inlined-method.check | 2 +- tests/init/neg/inner-first.check | 2 +- tests/init/neg/promotion-loop.check | 4 ++-- tests/init/neg/promotion-segment3.check | 2 +- tests/init/neg/t3273.check | 4 ++-- 10 files changed, 15 insertions(+), 15 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/transform/init/Semantic.scala b/compiler/src/dotty/tools/dotc/transform/init/Semantic.scala index 60f0266d7ede..7981153f46a7 100644 --- a/compiler/src/dotty/tools/dotc/transform/init/Semantic.scala +++ b/compiler/src/dotty/tools/dotc/transform/init/Semantic.scala @@ -64,12 +64,12 @@ object Semantic: sealed abstract class Value: def show(using Context): String = this match case ThisRef(klass) => - "the original object of type \"" + klass.show + "\" where initialization checking started" + "the original object of type (" + klass.show + ") where initialization checking started" case Warm(klass, outer, ctor, args) => val argsText = if args.nonEmpty then ", args = " + args.map(_.show).mkString("(", ", ", ")") else "" - "an initialized (Warm) object of type " + klass.show + "{ outer = " + outer.show + argsText + " }" + "an initialized (Warm) object of type (" + klass.show + ") { outer = " + outer.show + argsText + " }" case Fun(expr, thisV, klass) => - "a function where \"this\" is " + thisV.show + " and the function owner is an object of type " + klass.show + "a function where \"this\" is (" + thisV.show + ") and the function owner is an object of type (" + klass.show + ")" case RefSet(values) => values.map(_.show).mkString("Set { ", ", ", " }") case Hot => diff --git a/tests/init/neg/closureLeak.check b/tests/init/neg/closureLeak.check index 19292f535fd1..d4ea2ec8ef47 100644 --- a/tests/init/neg/closureLeak.check +++ b/tests/init/neg/closureLeak.check @@ -1,14 +1,14 @@ -- Error: tests/init/neg/closureLeak.scala:11:14 ----------------------------------------------------------------------- 11 | l.foreach(a => a.addX(this)) // error | ^^^^^^^^^^^^^^^^^ - |Could not verify that the method argument is transitively initialized (Hot). It was found to be a function where "this" is the original object of type "class Outer" where initialization checking started and the function owner is an object of type class Outer. Only transitively initialized arguments may be passed to methods outside the analyzed initialization region. Calling trace: + |Could not verify that the method argument is transitively initialized (Hot). It was found to be a function where "this" is (the original object of type (class Outer) where initialization checking started) and the function owner is an object of type (class Outer). Only transitively initialized arguments may be passed to methods outside the analyzed initialization region. Calling trace: |-> class Outer { [ closureLeak.scala:1 ] | ^ |-> l.foreach(a => a.addX(this)) // error [ closureLeak.scala:11 ] | ^^^^^^^^^^^^^^^^^ | |Promoting the value to transitively initialized (Hot) failed due to the following problem: - |Could not verify that the method argument is transitively initialized (Hot). It was found to be the original object of type "class Outer" where initialization checking started. Only transitively initialized arguments may be passed to methods outside the analyzed initialization region. + |Could not verify that the method argument is transitively initialized (Hot). It was found to be the original object of type (class Outer) where initialization checking started. Only transitively initialized arguments may be passed to methods outside the analyzed initialization region. |Non initialized field(s): value p. Promotion trace: |-> l.foreach(a => a.addX(this)) // error [ closureLeak.scala:11 ] | ^^^^ diff --git a/tests/init/neg/default-this.check b/tests/init/neg/default-this.check index 384efdf5414e..84556f0a9d82 100644 --- a/tests/init/neg/default-this.check +++ b/tests/init/neg/default-this.check @@ -1,7 +1,7 @@ -- Error: tests/init/neg/default-this.scala:9:8 ------------------------------------------------------------------------ 9 | compare() // error | ^^^^^^^ - |Could not verify that the method argument is transitively initialized (Hot). It was found to be the original object of type "class B" where initialization checking started. Only transitively initialized arguments may be passed to methods outside the analyzed initialization region. + |Could not verify that the method argument is transitively initialized (Hot). It was found to be the original object of type (class B) where initialization checking started. Only transitively initialized arguments may be passed to methods outside the analyzed initialization region. |Non initialized field(s): value result. Calling trace: |-> class B extends A { [ default-this.scala:6 ] | ^ diff --git a/tests/init/neg/i15459.check b/tests/init/neg/i15459.check index e25d7efadda2..fffeabd560e1 100644 --- a/tests/init/neg/i15459.check +++ b/tests/init/neg/i15459.check @@ -1,7 +1,7 @@ -- Error: tests/init/neg/i15459.scala:3:10 ----------------------------------------------------------------------------- 3 | println(this) // error | ^^^^ - |Could not verify that the method argument is transitively initialized (Hot). It was found to be the original object of type "class Sub" where initialization checking started. Only transitively initialized arguments may be passed to methods outside the analyzed initialization region. + |Could not verify that the method argument is transitively initialized (Hot). It was found to be the original object of type (class Sub) where initialization checking started. Only transitively initialized arguments may be passed to methods outside the analyzed initialization region. |Non initialized field(s): value b. Calling trace: |-> class Sub extends Sup: [ i15459.scala:5 ] | ^ diff --git a/tests/init/neg/inherit-non-hot.check b/tests/init/neg/inherit-non-hot.check index a62641473ab2..2c195bcacf1d 100644 --- a/tests/init/neg/inherit-non-hot.check +++ b/tests/init/neg/inherit-non-hot.check @@ -1,7 +1,7 @@ -- Error: tests/init/neg/inherit-non-hot.scala:6:32 -------------------------------------------------------------------- 6 | if b == null then b = new B(this) // error | ^^^^^^^^^^^^^^^ - |The RHS of reassignment must be transitively initialized (Hot). It was found to be an initialized (Warm) object of type class B{ outer = a transitively initialized (Hot) object, args = (an uninitialized (Cold) object) }. Calling trace: + |The RHS of reassignment must be transitively initialized (Hot). It was found to be an initialized (Warm) object of type (class B) { outer = a transitively initialized (Hot) object, args = (an uninitialized (Cold) object) }. Calling trace: |-> class C extends A { [ inherit-non-hot.scala:15 ] | ^ |-> val bAgain = toB.getBAgain [ inherit-non-hot.scala:16 ] diff --git a/tests/init/neg/inlined-method.check b/tests/init/neg/inlined-method.check index dce46d3d7b5a..9751ef09b0c1 100644 --- a/tests/init/neg/inlined-method.check +++ b/tests/init/neg/inlined-method.check @@ -1,7 +1,7 @@ -- Error: tests/init/neg/inlined-method.scala:8:45 --------------------------------------------------------------------- 8 | scala.runtime.Scala3RunTime.assertFailed(message) // error | ^^^^^^^ - |Could not verify that the method argument is transitively initialized (Hot). It was found to be the original object of type "class InlineError" where initialization checking started. Only transitively initialized arguments may be passed to methods outside the analyzed initialization region. + |Could not verify that the method argument is transitively initialized (Hot). It was found to be the original object of type (class InlineError) where initialization checking started. Only transitively initialized arguments may be passed to methods outside the analyzed initialization region. |Non initialized field(s): value v. Calling trace: |-> class InlineError { [ inlined-method.scala:1 ] | ^ diff --git a/tests/init/neg/inner-first.check b/tests/init/neg/inner-first.check index 62bc8c3c4668..9340479f79a9 100644 --- a/tests/init/neg/inner-first.check +++ b/tests/init/neg/inner-first.check @@ -1,7 +1,7 @@ -- Error: tests/init/neg/inner-first.scala:3:12 ------------------------------------------------------------------------ 3 | println(this) // error | ^^^^ - |Could not verify that the method argument is transitively initialized (Hot). It was found to be the original object of type "class B" where initialization checking started. Only transitively initialized arguments may be passed to methods outside the analyzed initialization region. + |Could not verify that the method argument is transitively initialized (Hot). It was found to be the original object of type (class B) where initialization checking started. Only transitively initialized arguments may be passed to methods outside the analyzed initialization region. |Non initialized field(s): value n. Calling trace: |-> class B: [ inner-first.scala:2 ] | ^ diff --git a/tests/init/neg/promotion-loop.check b/tests/init/neg/promotion-loop.check index 73adb08e282c..28562aa0effb 100644 --- a/tests/init/neg/promotion-loop.check +++ b/tests/init/neg/promotion-loop.check @@ -1,14 +1,14 @@ -- Error: tests/init/neg/promotion-loop.scala:16:10 -------------------------------------------------------------------- 16 | println(b) // error | ^ - |Could not verify that the method argument is transitively initialized (Hot). It was found to be an initialized (Warm) object of type class B{ outer = the original object of type "class Test" where initialization checking started }. Only transitively initialized arguments may be passed to methods outside the analyzed initialization region. Calling trace: + |Could not verify that the method argument is transitively initialized (Hot). It was found to be an initialized (Warm) object of type (class B) { outer = the original object of type (class Test) where initialization checking started }. Only transitively initialized arguments may be passed to methods outside the analyzed initialization region. Calling trace: |-> class Test { test => [ promotion-loop.scala:1 ] | ^ |-> println(b) // error [ promotion-loop.scala:16 ] | ^ | |Promoting the value to transitively initialized (Hot) failed due to the following problem: - |Could not verify that the field value outer is transitively initialized (Hot). It was found to be the original object of type "class Test" where initialization checking started. + |Could not verify that the field value outer is transitively initialized (Hot). It was found to be the original object of type (class Test) where initialization checking started. |Non initialized field(s): value n. Promotion trace: |-> val outer = test [ promotion-loop.scala:12 ] | ^^^^^^^^^^^^^^^^ diff --git a/tests/init/neg/promotion-segment3.check b/tests/init/neg/promotion-segment3.check index 40747b94f41d..1765f08d872a 100644 --- a/tests/init/neg/promotion-segment3.check +++ b/tests/init/neg/promotion-segment3.check @@ -1,7 +1,7 @@ -- Error: tests/init/neg/promotion-segment3.scala:9:6 ------------------------------------------------------------------ 9 | bar(new B) // error | ^^^^^ - |Could not verify that the method argument is transitively initialized (Hot). It was found to be an initialized (Warm) object of type class B{ outer = the original object of type "class A" where initialization checking started }. Only transitively initialized arguments may be passed to methods outside the analyzed initialization region. Calling trace: + |Could not verify that the method argument is transitively initialized (Hot). It was found to be an initialized (Warm) object of type (class B) { outer = the original object of type (class A) where initialization checking started }. Only transitively initialized arguments may be passed to methods outside the analyzed initialization region. Calling trace: |-> class A: [ promotion-segment3.scala:2 ] | ^ |-> bar(new B) // error [ promotion-segment3.scala:9 ] diff --git a/tests/init/neg/t3273.check b/tests/init/neg/t3273.check index 4b8d3e2521e0..a63f7bc7a5ea 100644 --- a/tests/init/neg/t3273.check +++ b/tests/init/neg/t3273.check @@ -1,7 +1,7 @@ -- Error: tests/init/neg/t3273.scala:4:42 ------------------------------------------------------------------------------ 4 | val num1: LazyList[Int] = 1 #:: num1.map(_ + 1) // error | ^^^^^^^^^^^^^^^ - |Could not verify that the method argument is transitively initialized (Hot). It was found to be a function where "this" is the original object of type "object Test" where initialization checking started and the function owner is an object of type object Test. Only transitively initialized arguments may be passed to methods outside the analyzed initialization region. Calling trace: + |Could not verify that the method argument is transitively initialized (Hot). It was found to be a function where "this" is (the original object of type (object Test) where initialization checking started) and the function owner is an object of type (object Test). Only transitively initialized arguments may be passed to methods outside the analyzed initialization region. Calling trace: |-> object Test { [ t3273.scala:3 ] | ^ |-> val num1: LazyList[Int] = 1 #:: num1.map(_ + 1) // error [ t3273.scala:4 ] @@ -14,7 +14,7 @@ -- Error: tests/init/neg/t3273.scala:5:61 ------------------------------------------------------------------------------ 5 | val num2: LazyList[Int] = 1 #:: num2.iterator.map(_ + 1).to(LazyList) // error | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - |Could not verify that the method argument is transitively initialized (Hot). It was found to be a function where "this" is the original object of type "object Test" where initialization checking started and the function owner is an object of type object Test. Only transitively initialized arguments may be passed to methods outside the analyzed initialization region. Calling trace: + |Could not verify that the method argument is transitively initialized (Hot). It was found to be a function where "this" is (the original object of type (object Test) where initialization checking started) and the function owner is an object of type (object Test). Only transitively initialized arguments may be passed to methods outside the analyzed initialization region. Calling trace: |-> object Test { [ t3273.scala:3 ] | ^ |-> val num2: LazyList[Int] = 1 #:: num2.iterator.map(_ + 1).to(LazyList) // error [ t3273.scala:5 ] From 36298a2dd4c988771c8e4093113da3edca5137de Mon Sep 17 00:00:00 2001 From: David Hua Date: Wed, 8 Mar 2023 20:43:20 -0500 Subject: [PATCH 5/7] Address feedback. --- compiler/src/dotty/tools/dotc/transform/init/Semantic.scala | 6 +++--- tests/init/neg/inherit-non-hot.check | 2 +- tests/init/neg/promotion-loop.check | 2 +- tests/init/neg/promotion-segment3.check | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/transform/init/Semantic.scala b/compiler/src/dotty/tools/dotc/transform/init/Semantic.scala index 7981153f46a7..1b7e1266ac13 100644 --- a/compiler/src/dotty/tools/dotc/transform/init/Semantic.scala +++ b/compiler/src/dotty/tools/dotc/transform/init/Semantic.scala @@ -67,7 +67,7 @@ object Semantic: "the original object of type (" + klass.show + ") where initialization checking started" case Warm(klass, outer, ctor, args) => val argsText = if args.nonEmpty then ", args = " + args.map(_.show).mkString("(", ", ", ")") else "" - "an initialized (Warm) object of type (" + klass.show + ") { outer = " + outer.show + argsText + " }" + "a non-transitively initialized (Warm) object of type (" + klass.show + ") { outer = " + outer.show + argsText + " }" case Fun(expr, thisV, klass) => "a function where \"this\" is (" + thisV.show + ") and the function owner is an object of type (" + klass.show + ")" case RefSet(values) => @@ -472,7 +472,7 @@ object Semantic: def widenArg: Contextual[Value] = a match case _: Ref | _: Fun => - val hasError = Reporter.hasErrors { a.promote("Argument cannot be proven to be transitively initialized (Hot)") } + val hasError = Reporter.hasErrors { a.promote("Argument is not provably transitively initialized (Hot)") } if hasError then Cold else Hot case RefSet(refs) => @@ -710,7 +710,7 @@ object Semantic: promoteArgs() // try promoting the receiver as last resort val hasErrors = Reporter.hasErrors { - ref.promote(ref.show + " has no source code and could not be proven to be transitively initialized (Hot).") + ref.promote(ref.show + " has no source code and is not provably transitively initialized (Hot).") } if hasErrors then val error = CallUnknown(target)(trace) diff --git a/tests/init/neg/inherit-non-hot.check b/tests/init/neg/inherit-non-hot.check index 2c195bcacf1d..068ba9662fd1 100644 --- a/tests/init/neg/inherit-non-hot.check +++ b/tests/init/neg/inherit-non-hot.check @@ -1,7 +1,7 @@ -- Error: tests/init/neg/inherit-non-hot.scala:6:32 -------------------------------------------------------------------- 6 | if b == null then b = new B(this) // error | ^^^^^^^^^^^^^^^ - |The RHS of reassignment must be transitively initialized (Hot). It was found to be an initialized (Warm) object of type (class B) { outer = a transitively initialized (Hot) object, args = (an uninitialized (Cold) object) }. Calling trace: + |The RHS of reassignment must be transitively initialized (Hot). It was found to be a non-transitively initialized (Warm) object of type (class B) { outer = a transitively initialized (Hot) object, args = (an uninitialized (Cold) object) }. Calling trace: |-> class C extends A { [ inherit-non-hot.scala:15 ] | ^ |-> val bAgain = toB.getBAgain [ inherit-non-hot.scala:16 ] diff --git a/tests/init/neg/promotion-loop.check b/tests/init/neg/promotion-loop.check index 28562aa0effb..ec0a6854bbac 100644 --- a/tests/init/neg/promotion-loop.check +++ b/tests/init/neg/promotion-loop.check @@ -1,7 +1,7 @@ -- Error: tests/init/neg/promotion-loop.scala:16:10 -------------------------------------------------------------------- 16 | println(b) // error | ^ - |Could not verify that the method argument is transitively initialized (Hot). It was found to be an initialized (Warm) object of type (class B) { outer = the original object of type (class Test) where initialization checking started }. Only transitively initialized arguments may be passed to methods outside the analyzed initialization region. Calling trace: + |Could not verify that the method argument is transitively initialized (Hot). It was found to be a non-transitively initialized (Warm) object of type (class B) { outer = the original object of type (class Test) where initialization checking started }. Only transitively initialized arguments may be passed to methods outside the analyzed initialization region. Calling trace: |-> class Test { test => [ promotion-loop.scala:1 ] | ^ |-> println(b) // error [ promotion-loop.scala:16 ] diff --git a/tests/init/neg/promotion-segment3.check b/tests/init/neg/promotion-segment3.check index 1765f08d872a..bc7a076d7d72 100644 --- a/tests/init/neg/promotion-segment3.check +++ b/tests/init/neg/promotion-segment3.check @@ -1,7 +1,7 @@ -- Error: tests/init/neg/promotion-segment3.scala:9:6 ------------------------------------------------------------------ 9 | bar(new B) // error | ^^^^^ - |Could not verify that the method argument is transitively initialized (Hot). It was found to be an initialized (Warm) object of type (class B) { outer = the original object of type (class A) where initialization checking started }. Only transitively initialized arguments may be passed to methods outside the analyzed initialization region. Calling trace: + |Could not verify that the method argument is transitively initialized (Hot). It was found to be a non-transitively initialized (Warm) object of type (class B) { outer = the original object of type (class A) where initialization checking started }. Only transitively initialized arguments may be passed to methods outside the analyzed initialization region. Calling trace: |-> class A: [ promotion-segment3.scala:2 ] | ^ |-> bar(new B) // error [ promotion-segment3.scala:9 ] From 603822ec7e80b524033d10b05cb326bb9e347adc Mon Sep 17 00:00:00 2001 From: David Hua Date: Mon, 13 Mar 2023 02:18:43 -0400 Subject: [PATCH 6/7] Make warning message more accurate. --- compiler/src/dotty/tools/dotc/transform/init/Semantic.scala | 2 +- tests/init/neg/closureLeak.check | 4 ++-- tests/init/neg/default-this.check | 2 +- tests/init/neg/i15459.check | 2 +- tests/init/neg/inlined-method.check | 2 +- tests/init/neg/inner-first.check | 2 +- tests/init/neg/promotion-loop.check | 2 +- tests/init/neg/promotion-segment3.check | 2 +- tests/init/neg/t3273.check | 4 ++-- 9 files changed, 11 insertions(+), 11 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/transform/init/Semantic.scala b/compiler/src/dotty/tools/dotc/transform/init/Semantic.scala index 1b7e1266ac13..b8d867e96a7e 100644 --- a/compiler/src/dotty/tools/dotc/transform/init/Semantic.scala +++ b/compiler/src/dotty/tools/dotc/transform/init/Semantic.scala @@ -1148,7 +1148,7 @@ object Semantic: extension (arg: ArgInfo) def promote: Contextual[Unit] = withTrace(arg.trace) { - arg.value.promote("Could not verify that the method argument is transitively initialized (Hot). It was found to be " + arg.value.show + ". Only transitively initialized arguments may be passed to methods outside the analyzed initialization region.") + arg.value.promote("Could not verify that the method argument is transitively initialized (Hot). It was found to be " + arg.value.show + ". Only transitively initialized arguments may be passed to methods (except constructors).") } /** Evaluate an expression with the given value for `this` in a given class `klass` diff --git a/tests/init/neg/closureLeak.check b/tests/init/neg/closureLeak.check index d4ea2ec8ef47..2437509faa73 100644 --- a/tests/init/neg/closureLeak.check +++ b/tests/init/neg/closureLeak.check @@ -1,14 +1,14 @@ -- Error: tests/init/neg/closureLeak.scala:11:14 ----------------------------------------------------------------------- 11 | l.foreach(a => a.addX(this)) // error | ^^^^^^^^^^^^^^^^^ - |Could not verify that the method argument is transitively initialized (Hot). It was found to be a function where "this" is (the original object of type (class Outer) where initialization checking started) and the function owner is an object of type (class Outer). Only transitively initialized arguments may be passed to methods outside the analyzed initialization region. Calling trace: + |Could not verify that the method argument is transitively initialized (Hot). It was found to be a function where "this" is (the original object of type (class Outer) where initialization checking started) and the function owner is an object of type (class Outer). Only transitively initialized arguments may be passed to methods (except constructors). Calling trace: |-> class Outer { [ closureLeak.scala:1 ] | ^ |-> l.foreach(a => a.addX(this)) // error [ closureLeak.scala:11 ] | ^^^^^^^^^^^^^^^^^ | |Promoting the value to transitively initialized (Hot) failed due to the following problem: - |Could not verify that the method argument is transitively initialized (Hot). It was found to be the original object of type (class Outer) where initialization checking started. Only transitively initialized arguments may be passed to methods outside the analyzed initialization region. + |Could not verify that the method argument is transitively initialized (Hot). It was found to be the original object of type (class Outer) where initialization checking started. Only transitively initialized arguments may be passed to methods (except constructors). |Non initialized field(s): value p. Promotion trace: |-> l.foreach(a => a.addX(this)) // error [ closureLeak.scala:11 ] | ^^^^ diff --git a/tests/init/neg/default-this.check b/tests/init/neg/default-this.check index 84556f0a9d82..f64f36304e9b 100644 --- a/tests/init/neg/default-this.check +++ b/tests/init/neg/default-this.check @@ -1,7 +1,7 @@ -- Error: tests/init/neg/default-this.scala:9:8 ------------------------------------------------------------------------ 9 | compare() // error | ^^^^^^^ - |Could not verify that the method argument is transitively initialized (Hot). It was found to be the original object of type (class B) where initialization checking started. Only transitively initialized arguments may be passed to methods outside the analyzed initialization region. + |Could not verify that the method argument is transitively initialized (Hot). It was found to be the original object of type (class B) where initialization checking started. Only transitively initialized arguments may be passed to methods (except constructors). |Non initialized field(s): value result. Calling trace: |-> class B extends A { [ default-this.scala:6 ] | ^ diff --git a/tests/init/neg/i15459.check b/tests/init/neg/i15459.check index fffeabd560e1..a8c9972276db 100644 --- a/tests/init/neg/i15459.check +++ b/tests/init/neg/i15459.check @@ -1,7 +1,7 @@ -- Error: tests/init/neg/i15459.scala:3:10 ----------------------------------------------------------------------------- 3 | println(this) // error | ^^^^ - |Could not verify that the method argument is transitively initialized (Hot). It was found to be the original object of type (class Sub) where initialization checking started. Only transitively initialized arguments may be passed to methods outside the analyzed initialization region. + |Could not verify that the method argument is transitively initialized (Hot). It was found to be the original object of type (class Sub) where initialization checking started. Only transitively initialized arguments may be passed to methods (except constructors). |Non initialized field(s): value b. Calling trace: |-> class Sub extends Sup: [ i15459.scala:5 ] | ^ diff --git a/tests/init/neg/inlined-method.check b/tests/init/neg/inlined-method.check index 9751ef09b0c1..f3061bcb63ed 100644 --- a/tests/init/neg/inlined-method.check +++ b/tests/init/neg/inlined-method.check @@ -1,7 +1,7 @@ -- Error: tests/init/neg/inlined-method.scala:8:45 --------------------------------------------------------------------- 8 | scala.runtime.Scala3RunTime.assertFailed(message) // error | ^^^^^^^ - |Could not verify that the method argument is transitively initialized (Hot). It was found to be the original object of type (class InlineError) where initialization checking started. Only transitively initialized arguments may be passed to methods outside the analyzed initialization region. + |Could not verify that the method argument is transitively initialized (Hot). It was found to be the original object of type (class InlineError) where initialization checking started. Only transitively initialized arguments may be passed to methods (except constructors). |Non initialized field(s): value v. Calling trace: |-> class InlineError { [ inlined-method.scala:1 ] | ^ diff --git a/tests/init/neg/inner-first.check b/tests/init/neg/inner-first.check index 9340479f79a9..fe90423c828f 100644 --- a/tests/init/neg/inner-first.check +++ b/tests/init/neg/inner-first.check @@ -1,7 +1,7 @@ -- Error: tests/init/neg/inner-first.scala:3:12 ------------------------------------------------------------------------ 3 | println(this) // error | ^^^^ - |Could not verify that the method argument is transitively initialized (Hot). It was found to be the original object of type (class B) where initialization checking started. Only transitively initialized arguments may be passed to methods outside the analyzed initialization region. + |Could not verify that the method argument is transitively initialized (Hot). It was found to be the original object of type (class B) where initialization checking started. Only transitively initialized arguments may be passed to methods (except constructors). |Non initialized field(s): value n. Calling trace: |-> class B: [ inner-first.scala:2 ] | ^ diff --git a/tests/init/neg/promotion-loop.check b/tests/init/neg/promotion-loop.check index ec0a6854bbac..bc05640d10d2 100644 --- a/tests/init/neg/promotion-loop.check +++ b/tests/init/neg/promotion-loop.check @@ -1,7 +1,7 @@ -- Error: tests/init/neg/promotion-loop.scala:16:10 -------------------------------------------------------------------- 16 | println(b) // error | ^ - |Could not verify that the method argument is transitively initialized (Hot). It was found to be a non-transitively initialized (Warm) object of type (class B) { outer = the original object of type (class Test) where initialization checking started }. Only transitively initialized arguments may be passed to methods outside the analyzed initialization region. Calling trace: + |Could not verify that the method argument is transitively initialized (Hot). It was found to be a non-transitively initialized (Warm) object of type (class B) { outer = the original object of type (class Test) where initialization checking started }. Only transitively initialized arguments may be passed to methods (except constructors). Calling trace: |-> class Test { test => [ promotion-loop.scala:1 ] | ^ |-> println(b) // error [ promotion-loop.scala:16 ] diff --git a/tests/init/neg/promotion-segment3.check b/tests/init/neg/promotion-segment3.check index bc7a076d7d72..a7320b5c3ed3 100644 --- a/tests/init/neg/promotion-segment3.check +++ b/tests/init/neg/promotion-segment3.check @@ -1,7 +1,7 @@ -- Error: tests/init/neg/promotion-segment3.scala:9:6 ------------------------------------------------------------------ 9 | bar(new B) // error | ^^^^^ - |Could not verify that the method argument is transitively initialized (Hot). It was found to be a non-transitively initialized (Warm) object of type (class B) { outer = the original object of type (class A) where initialization checking started }. Only transitively initialized arguments may be passed to methods outside the analyzed initialization region. Calling trace: + |Could not verify that the method argument is transitively initialized (Hot). It was found to be a non-transitively initialized (Warm) object of type (class B) { outer = the original object of type (class A) where initialization checking started }. Only transitively initialized arguments may be passed to methods (except constructors). Calling trace: |-> class A: [ promotion-segment3.scala:2 ] | ^ |-> bar(new B) // error [ promotion-segment3.scala:9 ] diff --git a/tests/init/neg/t3273.check b/tests/init/neg/t3273.check index a63f7bc7a5ea..2e4d8db50ebb 100644 --- a/tests/init/neg/t3273.check +++ b/tests/init/neg/t3273.check @@ -1,7 +1,7 @@ -- Error: tests/init/neg/t3273.scala:4:42 ------------------------------------------------------------------------------ 4 | val num1: LazyList[Int] = 1 #:: num1.map(_ + 1) // error | ^^^^^^^^^^^^^^^ - |Could not verify that the method argument is transitively initialized (Hot). It was found to be a function where "this" is (the original object of type (object Test) where initialization checking started) and the function owner is an object of type (object Test). Only transitively initialized arguments may be passed to methods outside the analyzed initialization region. Calling trace: + |Could not verify that the method argument is transitively initialized (Hot). It was found to be a function where "this" is (the original object of type (object Test) where initialization checking started) and the function owner is an object of type (object Test). Only transitively initialized arguments may be passed to methods (except constructors). Calling trace: |-> object Test { [ t3273.scala:3 ] | ^ |-> val num1: LazyList[Int] = 1 #:: num1.map(_ + 1) // error [ t3273.scala:4 ] @@ -14,7 +14,7 @@ -- Error: tests/init/neg/t3273.scala:5:61 ------------------------------------------------------------------------------ 5 | val num2: LazyList[Int] = 1 #:: num2.iterator.map(_ + 1).to(LazyList) // error | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - |Could not verify that the method argument is transitively initialized (Hot). It was found to be a function where "this" is (the original object of type (object Test) where initialization checking started) and the function owner is an object of type (object Test). Only transitively initialized arguments may be passed to methods outside the analyzed initialization region. Calling trace: + |Could not verify that the method argument is transitively initialized (Hot). It was found to be a function where "this" is (the original object of type (object Test) where initialization checking started) and the function owner is an object of type (object Test). Only transitively initialized arguments may be passed to methods (except constructors). Calling trace: |-> object Test { [ t3273.scala:3 ] | ^ |-> val num2: LazyList[Int] = 1 #:: num2.iterator.map(_ + 1).to(LazyList) // error [ t3273.scala:5 ] From 8af1b29a88ac71e3eea910b206c2b8c165bc35a8 Mon Sep 17 00:00:00 2001 From: David Hua Date: Sun, 26 Mar 2023 01:33:40 -0400 Subject: [PATCH 7/7] Reformat the output when printing a function to console in init checker --- compiler/src/dotty/tools/dotc/transform/init/Semantic.scala | 2 +- tests/init/neg/closureLeak.check | 2 +- tests/init/neg/t3273.check | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/transform/init/Semantic.scala b/compiler/src/dotty/tools/dotc/transform/init/Semantic.scala index b8d867e96a7e..9412cef6efc8 100644 --- a/compiler/src/dotty/tools/dotc/transform/init/Semantic.scala +++ b/compiler/src/dotty/tools/dotc/transform/init/Semantic.scala @@ -69,7 +69,7 @@ object Semantic: val argsText = if args.nonEmpty then ", args = " + args.map(_.show).mkString("(", ", ", ")") else "" "a non-transitively initialized (Warm) object of type (" + klass.show + ") { outer = " + outer.show + argsText + " }" case Fun(expr, thisV, klass) => - "a function where \"this\" is (" + thisV.show + ") and the function owner is an object of type (" + klass.show + ")" + "a function where \"this\" is (" + thisV.show + ")" case RefSet(values) => values.map(_.show).mkString("Set { ", ", ", " }") case Hot => diff --git a/tests/init/neg/closureLeak.check b/tests/init/neg/closureLeak.check index 2437509faa73..a90acaa8ed00 100644 --- a/tests/init/neg/closureLeak.check +++ b/tests/init/neg/closureLeak.check @@ -1,7 +1,7 @@ -- Error: tests/init/neg/closureLeak.scala:11:14 ----------------------------------------------------------------------- 11 | l.foreach(a => a.addX(this)) // error | ^^^^^^^^^^^^^^^^^ - |Could not verify that the method argument is transitively initialized (Hot). It was found to be a function where "this" is (the original object of type (class Outer) where initialization checking started) and the function owner is an object of type (class Outer). Only transitively initialized arguments may be passed to methods (except constructors). Calling trace: + |Could not verify that the method argument is transitively initialized (Hot). It was found to be a function where "this" is (the original object of type (class Outer) where initialization checking started). Only transitively initialized arguments may be passed to methods (except constructors). Calling trace: |-> class Outer { [ closureLeak.scala:1 ] | ^ |-> l.foreach(a => a.addX(this)) // error [ closureLeak.scala:11 ] diff --git a/tests/init/neg/t3273.check b/tests/init/neg/t3273.check index 2e4d8db50ebb..0fe7ea78871c 100644 --- a/tests/init/neg/t3273.check +++ b/tests/init/neg/t3273.check @@ -1,7 +1,7 @@ -- Error: tests/init/neg/t3273.scala:4:42 ------------------------------------------------------------------------------ 4 | val num1: LazyList[Int] = 1 #:: num1.map(_ + 1) // error | ^^^^^^^^^^^^^^^ - |Could not verify that the method argument is transitively initialized (Hot). It was found to be a function where "this" is (the original object of type (object Test) where initialization checking started) and the function owner is an object of type (object Test). Only transitively initialized arguments may be passed to methods (except constructors). Calling trace: + |Could not verify that the method argument is transitively initialized (Hot). It was found to be a function where "this" is (the original object of type (object Test) where initialization checking started). Only transitively initialized arguments may be passed to methods (except constructors). Calling trace: |-> object Test { [ t3273.scala:3 ] | ^ |-> val num1: LazyList[Int] = 1 #:: num1.map(_ + 1) // error [ t3273.scala:4 ] @@ -14,7 +14,7 @@ -- Error: tests/init/neg/t3273.scala:5:61 ------------------------------------------------------------------------------ 5 | val num2: LazyList[Int] = 1 #:: num2.iterator.map(_ + 1).to(LazyList) // error | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - |Could not verify that the method argument is transitively initialized (Hot). It was found to be a function where "this" is (the original object of type (object Test) where initialization checking started) and the function owner is an object of type (object Test). Only transitively initialized arguments may be passed to methods (except constructors). Calling trace: + |Could not verify that the method argument is transitively initialized (Hot). It was found to be a function where "this" is (the original object of type (object Test) where initialization checking started). Only transitively initialized arguments may be passed to methods (except constructors). Calling trace: |-> object Test { [ t3273.scala:3 ] | ^ |-> val num2: LazyList[Int] = 1 #:: num2.iterator.map(_ + 1).to(LazyList) // error [ t3273.scala:5 ]