summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan@lightbend.com>2017-03-27 17:11:09 -0700
committerGitHub <noreply@github.com>2017-03-27 17:11:09 -0700
commit03d5f4ee9242f048e86ad9196740b04852c3b738 (patch)
tree2f629f7e8cd6bc22bf839516e36a9d631e9351b9
parent99f41a15d16be6707b6c33b5a16093e016db81eb (diff)
parent9cfa239e776c2ce6bd7447fd9de8436c5fe167ab (diff)
downloadscala-03d5f4ee9242f048e86ad9196740b04852c3b738.tar.gz
scala-03d5f4ee9242f048e86ad9196740b04852c3b738.tar.bz2
scala-03d5f4ee9242f048e86ad9196740b04852c3b738.zip
Merge pull request #5804 from jvican/stub-errors-2.11.8
Backport 2.11.9: Improve stub error messages (SCP-009 proposal)
-rw-r--r--src/compiler/scala/tools/nsc/Global.scala14
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala15
-rw-r--r--src/partest-extras/scala/tools/partest/StubErrorMessageTest.scala47
-rw-r--r--src/reflect/scala/reflect/internal/Symbols.scala19
-rw-r--r--src/reflect/scala/reflect/internal/pickling/UnPickler.scala22
-rw-r--r--test/files/neg/t5148.check18
-rw-r--r--test/files/run/StubErrorBInheritsFromA.check6
-rw-r--r--test/files/run/StubErrorBInheritsFromA.scala22
-rw-r--r--test/files/run/StubErrorComplexInnerClass.check6
-rw-r--r--test/files/run/StubErrorComplexInnerClass.scala42
-rw-r--r--test/files/run/StubErrorHK.check6
-rw-r--r--test/files/run/StubErrorHK.scala22
-rw-r--r--test/files/run/StubErrorReturnTypeFunction.check6
-rw-r--r--test/files/run/StubErrorReturnTypeFunction.scala37
-rw-r--r--test/files/run/StubErrorReturnTypeFunction2.check6
-rw-r--r--test/files/run/StubErrorReturnTypeFunction2.scala37
-rw-r--r--test/files/run/StubErrorReturnTypePolyFunction.check15
-rw-r--r--test/files/run/StubErrorReturnTypePolyFunction.scala37
-rw-r--r--test/files/run/StubErrorSubclasses.check6
-rw-r--r--test/files/run/StubErrorSubclasses.scala21
-rw-r--r--test/files/run/StubErrorTypeDef.check16
-rw-r--r--test/files/run/StubErrorTypeDef.scala26
-rw-r--r--test/files/run/StubErrorTypeclass.check6
-rw-r--r--test/files/run/StubErrorTypeclass.scala21
-rw-r--r--test/files/run/t6440b.check11
-rw-r--r--test/files/run/t6440b.scala6
-rw-r--r--test/files/run/t7439.check2
-rw-r--r--test/files/run/t8442.check2
-rw-r--r--test/files/run/t9268.check3
-rw-r--r--test/files/run/typetags_without_scala_reflect_typetag_lookup.scala2
-rw-r--r--test/files/run/typetags_without_scala_reflect_typetag_manifest_interop.scala2
31 files changed, 465 insertions, 36 deletions
diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala
index 8d72fd76bd..a54b92cef8 100644
--- a/src/compiler/scala/tools/nsc/Global.scala
+++ b/src/compiler/scala/tools/nsc/Global.scala
@@ -96,6 +96,20 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
def erasurePhase: Phase = if (currentRun.isDefined) currentRun.erasurePhase else NoPhase
+ /* Override `newStubSymbol` defined in `SymbolTable` to provide us access
+ * to the last tree to typer, whose position is the trigger of stub errors. */
+ override def newStubSymbol(owner: Symbol,
+ name: Name,
+ missingMessage: String,
+ isPackage: Boolean = false): Symbol = {
+ val stubSymbol = super.newStubSymbol(owner, name, missingMessage, isPackage)
+ val stubErrorPosition = {
+ val lastTreeToTyper = analyzer.lastTreeToTyper
+ if (lastTreeToTyper != EmptyTree) lastTreeToTyper.pos else stubSymbol.pos
+ }
+ stubSymbol.setPos(stubErrorPosition)
+ }
+
// platform specific elements
protected class GlobalPlatform extends {
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
index 9b73f203e0..809effe18b 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
@@ -366,7 +366,7 @@ abstract class ClassfileParser {
// - better owner than `NoSymbol`
// - remove eager warning
val msg = s"Class $name not found - continuing with a stub."
- if (!settings.isScaladoc) warning(msg)
+ if ((!settings.isScaladoc) && (settings.verbose || settings.developer)) warning(msg)
return NoSymbol.newStubSymbol(name.toTypeName, msg)
}
val completer = new loaders.ClassfileLoader(file)
@@ -1030,8 +1030,11 @@ abstract class ClassfileParser {
val sflags = jflags.toScalaFlags
val owner = ownerForFlags(jflags)
val scope = getScope(jflags)
- def newStub(name: Name) =
- owner.newStubSymbol(name, s"Class file for ${entry.externalName} not found").setFlag(JAVA)
+ def newStub(name: Name) = {
+ val stub = owner.newStubSymbol(name, s"Class file for ${entry.externalName} not found")
+ stub.setPos(owner.pos)
+ stub.setFlag(JAVA)
+ }
val (innerClass, innerModule) = if (file == NoAbstractFile) {
(newStub(name.toTypeName), newStub(name.toTermName))
@@ -1152,7 +1155,11 @@ abstract class ClassfileParser {
if (enclosing == clazz) entry.scope lookup name
else lookupMemberAtTyperPhaseIfPossible(enclosing, name)
)
- def newStub = enclosing.newStubSymbol(name, s"Unable to locate class corresponding to inner class entry for $name in owner ${entry.outerName}")
+ def newStub = {
+ enclosing
+ .newStubSymbol(name, s"Unable to locate class corresponding to inner class entry for $name in owner ${entry.outerName}")
+ .setPos(enclosing.pos)
+ }
member.orElse(newStub)
}
}
diff --git a/src/partest-extras/scala/tools/partest/StubErrorMessageTest.scala b/src/partest-extras/scala/tools/partest/StubErrorMessageTest.scala
new file mode 100644
index 0000000000..f713b79e75
--- /dev/null
+++ b/src/partest-extras/scala/tools/partest/StubErrorMessageTest.scala
@@ -0,0 +1,47 @@
+package scala.tools.partest
+
+trait StubErrorMessageTest extends StoreReporterDirectTest {
+ // Stub to feed to partest, unused
+ def code = throw new Error("Use `userCode` instead of `code`.")
+
+ val classpath = List(sys.props("partest.lib"), testOutput.path)
+ .mkString(sys.props("path.separator"))
+
+ def compileCode(codes: String*) = {
+ val global = newCompiler("-cp", classpath, "-d", testOutput.path)
+ val sourceFiles = newSources(codes: _*)
+ withRun(global)(_ compileSources sourceFiles)
+ }
+
+ def removeClasses(inPackage: String, classNames: Seq[String]): Unit = {
+ val pkg = new File(testOutput.path, inPackage)
+ classNames.foreach { className =>
+ val classFile = new File(pkg, s"$className.class")
+ assert(classFile.exists)
+ assert(classFile.delete())
+ }
+ }
+
+ def removeFromClasspath(): Unit
+ def codeA: String
+ def codeB: String
+ def userCode: String
+ def extraUserCode: String = ""
+
+ def show(): Unit = {
+ compileCode(codeA)
+ assert(filteredInfos.isEmpty, filteredInfos)
+
+ compileCode(codeB)
+ assert(filteredInfos.isEmpty, filteredInfos)
+ removeFromClasspath()
+
+ if (extraUserCode == "") compileCode(userCode)
+ else compileCode(userCode, extraUserCode)
+ import scala.reflect.internal.util.Position
+ filteredInfos.map { report =>
+ print(if (report.severity == storeReporter.ERROR) "error: " else "")
+ println(Position.formatMessage(report.pos, report.msg, true))
+ }
+ }
+}
diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala
index 6116952c70..16b2a23c23 100644
--- a/src/reflect/scala/reflect/internal/Symbols.scala
+++ b/src/reflect/scala/reflect/internal/Symbols.scala
@@ -182,6 +182,17 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
private[reflect] case class SymbolKind(accurate: String, sanitized: String, abbreviation: String)
+ protected def newStubSymbol(owner: Symbol,
+ name: Name,
+ missingMessage: String,
+ isPackage: Boolean = false): Symbol = {
+ name match {
+ case n: TypeName => if (isPackage) new StubPackageClassSymbol(owner, n, missingMessage)
+ else new StubClassSymbol(owner, n, missingMessage)
+ case _ => new StubTermSymbol(owner, name.toTermName, missingMessage)
+ }
+ }
+
/** The class for all symbols */
abstract class Symbol protected[Symbols] (initOwner: Symbol, initPos: Position, initName: Name)
extends SymbolContextApiImpl
@@ -505,9 +516,9 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
* failure to the point when that name is used for something, which is
* often to the point of never.
*/
- def newStubSymbol(name: Name, missingMessage: String, isPackage: Boolean = false): Symbol = name match {
- case n: TypeName => if (isPackage) new StubPackageClassSymbol(this, n, missingMessage) else new StubClassSymbol(this, n, missingMessage)
- case _ => new StubTermSymbol(this, name.toTermName, missingMessage)
+ def newStubSymbol(name: Name, missingMessage: String, isPackage: Boolean = false): Symbol = {
+ // Invoke the overriden `newStubSymbol` in Global that gives us access to typer
+ Symbols.this.newStubSymbol(this, name, missingMessage, isPackage)
}
/** Given a field, construct a term symbol that represents the source construct that gave rise the field */
@@ -3491,7 +3502,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
private def fail[T](alt: T): T = {
// Avoid issuing lots of redundant errors
if (!hasFlag(IS_ERROR)) {
- globalError(missingMessage)
+ globalError(pos, missingMessage)
if (settings.debug.value)
(new Throwable).printStackTrace
diff --git a/src/reflect/scala/reflect/internal/pickling/UnPickler.scala b/src/reflect/scala/reflect/internal/pickling/UnPickler.scala
index a9020a3d4c..6a12d44a05 100644
--- a/src/reflect/scala/reflect/internal/pickling/UnPickler.scala
+++ b/src/reflect/scala/reflect/internal/pickling/UnPickler.scala
@@ -266,13 +266,15 @@ abstract class UnPickler {
adjust(mirrorThatLoaded(owner).missingHook(owner, name)) orElse {
// (5) Create a stub symbol to defer hard failure a little longer.
val advice = moduleAdvice(s"${owner.fullName}.$name")
+ val lazyCompletingSymbol = completingStack.headOption.getOrElse(NoSymbol)
val missingMessage =
- s"""|missing or invalid dependency detected while loading class file '$filename'.
- |Could not access ${name.longString} in ${owner.kindString} ${owner.fullName},
- |because it (or its dependencies) are missing. Check your build definition for
- |missing or conflicting dependencies. (Re-run with `-Ylog-classpath` to see the problematic classpath.)
+ s"""|Symbol '${name.nameKind} ${owner.fullName}.$name' is missing from the classpath.
+ |This symbol is required by '${lazyCompletingSymbol.kindString} ${lazyCompletingSymbol.fullName}'.
+ |Make sure that ${name.longString} is in your classpath and check for conflicting dependencies with `-Ylog-classpath`.
|A full rebuild may help if '$filename' was compiled against an incompatible version of ${owner.fullName}.$advice""".stripMargin
- owner.newStubSymbol(name, missingMessage)
+ val stubName = if (tag == EXTref) name else name.toTypeName
+ // The position of the error message is set by `newStubSymbol`
+ NoSymbol.newStubSymbol(stubName, missingMessage)
}
}
}
@@ -717,11 +719,18 @@ abstract class UnPickler {
new TypeError(e.msg)
}
+ /** Keep track of the symbols pending to be initialized.
+ *
+ * Useful for reporting on stub errors and cyclic errors.
+ */
+ private var completingStack = List.empty[Symbol]
+
/** A lazy type which when completed returns type at index `i`. */
private class LazyTypeRef(i: Int) extends LazyType with FlagAgnosticCompleter {
private val definedAtRunId = currentRunId
private val p = phase
protected def completeInternal(sym: Symbol) : Unit = try {
+ completingStack = sym :: completingStack
val tp = at(i, () => readType(sym.isTerm)) // after NMT_TRANSITION, revert `() => readType(sym.isTerm)` to `readType`
// This is a temporary fix allowing to read classes generated by an older, buggy pickler.
@@ -744,7 +753,10 @@ abstract class UnPickler {
}
catch {
case e: MissingRequirementError => throw toTypeError(e)
+ } finally {
+ completingStack = completingStack.tail
}
+
override def complete(sym: Symbol) : Unit = {
completeInternal(sym)
if (!isCompilerUniverse) markAllCompleted(sym)
diff --git a/test/files/neg/t5148.check b/test/files/neg/t5148.check
index 286ed9e04a..da0ef0fc2e 100644
--- a/test/files/neg/t5148.check
+++ b/test/files/neg/t5148.check
@@ -1,11 +1,7 @@
-error: missing or invalid dependency detected while loading class file 'Imports.class'.
-Could not access type Wrapper in class scala.tools.nsc.interpreter.IMain.Request,
-because it (or its dependencies) are missing. Check your build definition for
-missing or conflicting dependencies. (Re-run with `-Ylog-classpath` to see the problematic classpath.)
-A full rebuild may help if 'Imports.class' was compiled against an incompatible version of scala.tools.nsc.interpreter.IMain.Request.
-error: missing or invalid dependency detected while loading class file 'Imports.class'.
-Could not access type Request in class scala.tools.nsc.interpreter.IMain,
-because it (or its dependencies) are missing. Check your build definition for
-missing or conflicting dependencies. (Re-run with `-Ylog-classpath` to see the problematic classpath.)
-A full rebuild may help if 'Imports.class' was compiled against an incompatible version of scala.tools.nsc.interpreter.IMain.
-two errors found
+t5148.scala:4: error: Symbol 'type <none>.Request.Wrapper' is missing from the classpath.
+This symbol is required by 'value scala.tools.nsc.interpreter.Imports.wrapper'.
+Make sure that type Wrapper is in your classpath and check for conflicting dependencies with `-Ylog-classpath`.
+A full rebuild may help if 'Imports.class' was compiled against an incompatible version of <none>.Request.
+class IMain extends Imports
+ ^
+one error found
diff --git a/test/files/run/StubErrorBInheritsFromA.check b/test/files/run/StubErrorBInheritsFromA.check
new file mode 100644
index 0000000000..009f0887d4
--- /dev/null
+++ b/test/files/run/StubErrorBInheritsFromA.check
@@ -0,0 +1,6 @@
+error: newSource1.scala:4: Symbol 'type stuberrors.A' is missing from the classpath.
+This symbol is required by 'class stuberrors.B'.
+Make sure that type A is in your classpath and check for conflicting dependencies with `-Ylog-classpath`.
+A full rebuild may help if 'B.class' was compiled against an incompatible version of stuberrors.
+ new B
+ ^
diff --git a/test/files/run/StubErrorBInheritsFromA.scala b/test/files/run/StubErrorBInheritsFromA.scala
new file mode 100644
index 0000000000..3e02692171
--- /dev/null
+++ b/test/files/run/StubErrorBInheritsFromA.scala
@@ -0,0 +1,22 @@
+object Test extends scala.tools.partest.StubErrorMessageTest {
+ def codeA = """
+ package stuberrors
+ class A
+ """
+
+ def codeB = """
+ package stuberrors
+ class B extends A
+ """
+
+ def userCode = """
+ package stuberrors
+ class C {
+ new B
+ }
+ """
+
+ def removeFromClasspath(): Unit = {
+ removeClasses("stuberrors", List("A"))
+ }
+}
diff --git a/test/files/run/StubErrorComplexInnerClass.check b/test/files/run/StubErrorComplexInnerClass.check
new file mode 100644
index 0000000000..fe089de8ad
--- /dev/null
+++ b/test/files/run/StubErrorComplexInnerClass.check
@@ -0,0 +1,6 @@
+error: newSource1.scala:9: Symbol 'type stuberrors.A' is missing from the classpath.
+This symbol is required by 'class stuberrors.B.BB'.
+Make sure that type A is in your classpath and check for conflicting dependencies with `-Ylog-classpath`.
+A full rebuild may help if 'B.class' was compiled against an incompatible version of stuberrors.
+ new b.BB
+ ^
diff --git a/test/files/run/StubErrorComplexInnerClass.scala b/test/files/run/StubErrorComplexInnerClass.scala
new file mode 100644
index 0000000000..2028644601
--- /dev/null
+++ b/test/files/run/StubErrorComplexInnerClass.scala
@@ -0,0 +1,42 @@
+object Test extends scala.tools.partest.StubErrorMessageTest {
+ def codeA = """
+ package stuberrors
+ class A
+ """
+
+ def codeB = """
+ package stuberrors
+ class B {
+ def foo: String = ???
+
+ // unused and should fail, but not loaded
+ def unsafeFoo: A = ???
+ // used, B.info -> BB.info -> unpickling A -> stub error
+ class BB extends A
+ }
+ """
+
+ def userCode = """
+ package stuberrors
+ class C {
+ def aloha = {
+ val b = new B
+ val d = new extra.D
+ d.foo
+ println(b.foo)
+ new b.BB
+ }
+ }
+ """
+
+ override def extraUserCode = """
+ package extra
+ class D {
+ def foo = "Hello, World"
+ }
+ """.stripMargin
+
+ def removeFromClasspath(): Unit = {
+ removeClasses("stuberrors", List("A"))
+ }
+}
diff --git a/test/files/run/StubErrorHK.check b/test/files/run/StubErrorHK.check
new file mode 100644
index 0000000000..6f37f8ea41
--- /dev/null
+++ b/test/files/run/StubErrorHK.check
@@ -0,0 +1,6 @@
+error: newSource1.scala:4: Symbol 'type stuberrors.A' is missing from the classpath.
+This symbol is required by 'type stuberrors.B.D'.
+Make sure that type A is in your classpath and check for conflicting dependencies with `-Ylog-classpath`.
+A full rebuild may help if 'B.class' was compiled against an incompatible version of stuberrors.
+ println(new B)
+ ^
diff --git a/test/files/run/StubErrorHK.scala b/test/files/run/StubErrorHK.scala
new file mode 100644
index 0000000000..7ee8c6d6a5
--- /dev/null
+++ b/test/files/run/StubErrorHK.scala
@@ -0,0 +1,22 @@
+object Test extends scala.tools.partest.StubErrorMessageTest {
+ def codeA = """
+ package stuberrors
+ class A
+ """
+
+ def codeB = """
+ package stuberrors
+ class B[D <: A]
+ """
+
+ def userCode = """
+ package stuberrors
+ object C extends App {
+ println(new B)
+ }
+ """
+
+ def removeFromClasspath(): Unit = {
+ removeClasses("stuberrors", List("A"))
+ }
+}
diff --git a/test/files/run/StubErrorReturnTypeFunction.check b/test/files/run/StubErrorReturnTypeFunction.check
new file mode 100644
index 0000000000..bd61d5f5fa
--- /dev/null
+++ b/test/files/run/StubErrorReturnTypeFunction.check
@@ -0,0 +1,6 @@
+error: newSource1.scala:13: Symbol 'type stuberrors.A' is missing from the classpath.
+This symbol is required by 'method stuberrors.B.foo'.
+Make sure that type A is in your classpath and check for conflicting dependencies with `-Ylog-classpath`.
+A full rebuild may help if 'B.class' was compiled against an incompatible version of stuberrors.
+ b.foo
+ ^
diff --git a/test/files/run/StubErrorReturnTypeFunction.scala b/test/files/run/StubErrorReturnTypeFunction.scala
new file mode 100644
index 0000000000..75a02cff63
--- /dev/null
+++ b/test/files/run/StubErrorReturnTypeFunction.scala
@@ -0,0 +1,37 @@
+object Test extends scala.tools.partest.StubErrorMessageTest {
+ def codeA = """
+ package stuberrors
+ class A
+ class AA
+ """
+
+ def codeB = """
+ package stuberrors
+
+ abstract class B {
+ def bar: String = ???
+ def foo: A = new A
+ def baz: String = ???
+ }
+ """
+
+ def userCode = """
+ package stuberrors
+
+ abstract class C extends App {
+ val b = new B {}
+
+ // Use other symbols in the meanwhile
+ val aa = new AA
+ val dummy = 1
+ println(dummy)
+
+ // Should blow up
+ b.foo
+ }
+ """
+
+ def removeFromClasspath(): Unit = {
+ removeClasses("stuberrors", List("A"))
+ }
+}
diff --git a/test/files/run/StubErrorReturnTypeFunction2.check b/test/files/run/StubErrorReturnTypeFunction2.check
new file mode 100644
index 0000000000..bd61d5f5fa
--- /dev/null
+++ b/test/files/run/StubErrorReturnTypeFunction2.check
@@ -0,0 +1,6 @@
+error: newSource1.scala:13: Symbol 'type stuberrors.A' is missing from the classpath.
+This symbol is required by 'method stuberrors.B.foo'.
+Make sure that type A is in your classpath and check for conflicting dependencies with `-Ylog-classpath`.
+A full rebuild may help if 'B.class' was compiled against an incompatible version of stuberrors.
+ b.foo
+ ^
diff --git a/test/files/run/StubErrorReturnTypeFunction2.scala b/test/files/run/StubErrorReturnTypeFunction2.scala
new file mode 100644
index 0000000000..efb2f4f190
--- /dev/null
+++ b/test/files/run/StubErrorReturnTypeFunction2.scala
@@ -0,0 +1,37 @@
+object Test extends scala.tools.partest.StubErrorMessageTest {
+ def codeA = """
+ package stuberrors
+ class A
+ class AA
+ """
+
+ def codeB = """
+ package stuberrors
+
+ class B {
+ def bar: String = ???
+ def foo: A = new A
+ def baz: String = ???
+ }
+ """
+
+ def userCode = """
+ package stuberrors
+
+ abstract class C extends App {
+ val b = new B {}
+
+ // Use other symbols in the meanwhile
+ val aa = new AA
+ val dummy = 1
+ println(dummy)
+
+ // Should blow up
+ b.foo
+ }
+ """
+
+ def removeFromClasspath(): Unit = {
+ removeClasses("stuberrors", List("A"))
+ }
+}
diff --git a/test/files/run/StubErrorReturnTypePolyFunction.check b/test/files/run/StubErrorReturnTypePolyFunction.check
new file mode 100644
index 0000000000..78e309668e
--- /dev/null
+++ b/test/files/run/StubErrorReturnTypePolyFunction.check
@@ -0,0 +1,15 @@
+error: newSource1.scala:13: Symbol 'type stuberrors.A' is missing from the classpath.
+This symbol is required by 'class stuberrors.D'.
+Make sure that type A is in your classpath and check for conflicting dependencies with `-Ylog-classpath`.
+A full rebuild may help if 'D.class' was compiled against an incompatible version of stuberrors.
+ b.foo[D]
+ ^
+error: newSource1.scala:13: type arguments [stuberrors.D] do not conform to method foo's type parameter bounds [T <: stuberrors.A]
+ b.foo[D]
+ ^
+error: newSource1.scala:13: Symbol 'type stuberrors.A' is missing from the classpath.
+This symbol is required by 'type stuberrors.B.T'.
+Make sure that type A is in your classpath and check for conflicting dependencies with `-Ylog-classpath`.
+A full rebuild may help if 'B.class' was compiled against an incompatible version of stuberrors.
+ b.foo[D]
+ ^
diff --git a/test/files/run/StubErrorReturnTypePolyFunction.scala b/test/files/run/StubErrorReturnTypePolyFunction.scala
new file mode 100644
index 0000000000..8345aaade0
--- /dev/null
+++ b/test/files/run/StubErrorReturnTypePolyFunction.scala
@@ -0,0 +1,37 @@
+object Test extends scala.tools.partest.StubErrorMessageTest {
+ def codeA = """
+ package stuberrors
+ class A
+ class AA
+ """
+
+ def codeB = """
+ package stuberrors
+
+ class B {
+ def foo[T <: A]: T = ???
+ }
+
+ class D extends A
+ """
+
+ def userCode = """
+ package stuberrors
+
+ abstract class C extends App {
+ val b = new B
+
+ // Use other symbols in the meanwhile
+ val aa = new AA
+ val dummy = 1
+ println(dummy)
+
+ // Should blow up
+ b.foo[D]
+ }
+ """
+
+ def removeFromClasspath(): Unit = {
+ removeClasses("stuberrors", List("A"))
+ }
+}
diff --git a/test/files/run/StubErrorSubclasses.check b/test/files/run/StubErrorSubclasses.check
new file mode 100644
index 0000000000..8ccd781cad
--- /dev/null
+++ b/test/files/run/StubErrorSubclasses.check
@@ -0,0 +1,6 @@
+error: newSource1.scala:3: Symbol 'type stuberrors.A' is missing from the classpath.
+This symbol is required by 'class stuberrors.B'.
+Make sure that type A is in your classpath and check for conflicting dependencies with `-Ylog-classpath`.
+A full rebuild may help if 'B.class' was compiled against an incompatible version of stuberrors.
+ class C extends B
+ ^
diff --git a/test/files/run/StubErrorSubclasses.scala b/test/files/run/StubErrorSubclasses.scala
new file mode 100644
index 0000000000..b19155e20e
--- /dev/null
+++ b/test/files/run/StubErrorSubclasses.scala
@@ -0,0 +1,21 @@
+object Test extends scala.tools.partest.StubErrorMessageTest {
+ def codeA = """
+ package stuberrors
+ class A
+ """
+
+ def codeB = """
+ package stuberrors
+ class B extends A
+ """
+
+ def userCode = """
+ package stuberrors
+ class C extends B
+ """
+
+ def removeFromClasspath(): Unit = {
+ removeClasses("stuberrors", List("A"))
+ }
+}
+
diff --git a/test/files/run/StubErrorTypeDef.check b/test/files/run/StubErrorTypeDef.check
new file mode 100644
index 0000000000..955d9b0880
--- /dev/null
+++ b/test/files/run/StubErrorTypeDef.check
@@ -0,0 +1,16 @@
+error: newSource1.scala:4: overriding type D in class B with bounds <: stuberrors.A;
+ type D has incompatible type
+ new B { type D = E }
+ ^
+error: newSource1.scala:4: Symbol 'type stuberrors.A' is missing from the classpath.
+This symbol is required by 'type stuberrors.B.D'.
+Make sure that type A is in your classpath and check for conflicting dependencies with `-Ylog-classpath`.
+A full rebuild may help if 'B.class' was compiled against an incompatible version of stuberrors.
+ new B { type D = E }
+ ^
+error: newSource1.scala:4: Symbol 'type stuberrors.A' is missing from the classpath.
+This symbol is required by 'class stuberrors.E'.
+Make sure that type A is in your classpath and check for conflicting dependencies with `-Ylog-classpath`.
+A full rebuild may help if 'E.class' was compiled against an incompatible version of stuberrors.
+ new B { type D = E }
+ ^
diff --git a/test/files/run/StubErrorTypeDef.scala b/test/files/run/StubErrorTypeDef.scala
new file mode 100644
index 0000000000..967964d815
--- /dev/null
+++ b/test/files/run/StubErrorTypeDef.scala
@@ -0,0 +1,26 @@
+object Test extends scala.tools.partest.StubErrorMessageTest {
+ def codeA = """
+ package stuberrors
+ class A
+ class NestedB[T]
+ """
+
+ def codeB = """
+ package stuberrors
+ class E extends A
+ abstract class B {
+ type D <: A
+ }
+ """
+
+ def userCode = """
+ package stuberrors
+ class C {
+ new B { type D = E }
+ }
+ """
+
+ def removeFromClasspath(): Unit = {
+ removeClasses("stuberrors", List("A"))
+ }
+}
diff --git a/test/files/run/StubErrorTypeclass.check b/test/files/run/StubErrorTypeclass.check
new file mode 100644
index 0000000000..7ecee64ec9
--- /dev/null
+++ b/test/files/run/StubErrorTypeclass.check
@@ -0,0 +1,6 @@
+error: newSource1.scala:4: Symbol 'type stuberrors.A' is missing from the classpath.
+This symbol is required by 'value stuberrors.B.evidence$1'.
+Make sure that type A is in your classpath and check for conflicting dependencies with `-Ylog-classpath`.
+A full rebuild may help if 'B.class' was compiled against an incompatible version of stuberrors.
+ class C { println(new B(1)) }
+ ^
diff --git a/test/files/run/StubErrorTypeclass.scala b/test/files/run/StubErrorTypeclass.scala
new file mode 100644
index 0000000000..e9a48d5430
--- /dev/null
+++ b/test/files/run/StubErrorTypeclass.scala
@@ -0,0 +1,21 @@
+object Test extends scala.tools.partest.StubErrorMessageTest {
+ def codeA = """
+ package stuberrors
+ class A[T]
+ """
+
+ def codeB = """
+ package stuberrors
+ class B[T: A](val t: T)
+ """
+
+ def userCode = """
+ package stuberrors
+ // Here we want a stub error not an implicit not found error
+ class C { println(new B(1)) }
+ """
+
+ def removeFromClasspath(): Unit = {
+ removeClasses("stuberrors", List("A"))
+ }
+}
diff --git a/test/files/run/t6440b.check b/test/files/run/t6440b.check
index a6100d6d1e..07ec4f2a19 100644
--- a/test/files/run/t6440b.check
+++ b/test/files/run/t6440b.check
@@ -1,5 +1,6 @@
-pos: NoPosition missing or invalid dependency detected while loading class file 'U.class'.
-Could not access type T in package pack1,
-because it (or its dependencies) are missing. Check your build definition for
-missing or conflicting dependencies. (Re-run with `-Ylog-classpath` to see the problematic classpath.)
-A full rebuild may help if 'U.class' was compiled against an incompatible version of pack1. ERROR
+error: newSource1.scala:4: Symbol 'type pack1.T' is missing from the classpath.
+This symbol is required by 'method pack1.U.t'.
+Make sure that type T is in your classpath and check for conflicting dependencies with `-Ylog-classpath`.
+A full rebuild may help if 'U.class' was compiled against an incompatible version of pack1.
+ pack2.V.u.t // we have to fail if T.class is missing
+ ^
diff --git a/test/files/run/t6440b.scala b/test/files/run/t6440b.scala
index 7ab9529ccb..a1ad717162 100644
--- a/test/files/run/t6440b.scala
+++ b/test/files/run/t6440b.scala
@@ -56,6 +56,10 @@ object Test extends StoreReporterDirectTest {
// bad symbolic reference error expected (but no stack trace!)
compileCode(app2)
- println(filteredInfos.mkString("\n"))
+ import scala.reflect.internal.util.Position
+ filteredInfos.map { report =>
+ print(if (report.severity == storeReporter.ERROR) "error: " else "")
+ println(Position.formatMessage(report.pos, report.msg, true))
+ }
}
}
diff --git a/test/files/run/t7439.check b/test/files/run/t7439.check
index 9ea09f9c40..b95884311a 100644
--- a/test/files/run/t7439.check
+++ b/test/files/run/t7439.check
@@ -1,2 +1,2 @@
Recompiling after deleting t7439-run.obj/A_1.class
-pos: NoPosition Class A_1 not found - continuing with a stub. WARNING
+
diff --git a/test/files/run/t8442.check b/test/files/run/t8442.check
index ce9e8b52ff..8b13789179 100644
--- a/test/files/run/t8442.check
+++ b/test/files/run/t8442.check
@@ -1 +1 @@
-pos: NoPosition Class A_1 not found - continuing with a stub. WARNING
+
diff --git a/test/files/run/t9268.check b/test/files/run/t9268.check
index 90ef940eb3..60afcbb648 100644
--- a/test/files/run/t9268.check
+++ b/test/files/run/t9268.check
@@ -1,5 +1,4 @@
Compiling Client1
-pos: NoPosition Class Waiter not found - continuing with a stub. WARNING
+
Compiling Client2
-pos: NoPosition Class Waiter not found - continuing with a stub. WARNING
pos: NoPosition Unable to locate class corresponding to inner class entry for Predicate in owner Waiter ERROR
diff --git a/test/files/run/typetags_without_scala_reflect_typetag_lookup.scala b/test/files/run/typetags_without_scala_reflect_typetag_lookup.scala
index 3d2b9f77be..dccb2af8f5 100644
--- a/test/files/run/typetags_without_scala_reflect_typetag_lookup.scala
+++ b/test/files/run/typetags_without_scala_reflect_typetag_lookup.scala
@@ -38,6 +38,6 @@ object Test extends StoreReporterDirectTest {
compileApp();
// we should get "missing or invalid dependency detected" errors, because we're trying to use an implicit that can't be unpickled
// but we don't know the number of these errors and their order, so I just ignore them all
- println(filteredInfos.filterNot(_.msg.contains("missing or invalid dependency detected")).mkString("\n"))
+ println(filteredInfos.filterNot(_.msg.contains("is missing from the classpath")).mkString("\n"))
}
}
diff --git a/test/files/run/typetags_without_scala_reflect_typetag_manifest_interop.scala b/test/files/run/typetags_without_scala_reflect_typetag_manifest_interop.scala
index a865f4d137..c865759588 100644
--- a/test/files/run/typetags_without_scala_reflect_typetag_manifest_interop.scala
+++ b/test/files/run/typetags_without_scala_reflect_typetag_manifest_interop.scala
@@ -42,6 +42,6 @@ object Test extends StoreReporterDirectTest {
compileApp();
// we should get "missing or invalid dependency detected" errors, because we're trying to use an implicit that can't be unpickled
// but we don't know the number of these errors and their order, so I just ignore them all
- println(filteredInfos.filterNot (_.msg.contains("missing or invalid dependency detected")).mkString("\n"))
+ println(filteredInfos.filterNot (_.msg.contains("is missing from the classpath")).mkString("\n"))
}
}