diff options
author | Adriaan Moors <adriaan.moors@typesafe.com> | 2014-03-16 20:10:34 -0700 |
---|---|---|
committer | Adriaan Moors <adriaan.moors@typesafe.com> | 2014-03-16 20:10:34 -0700 |
commit | 79f7e05c082a1810f9315e19658e20af15b08235 (patch) | |
tree | 363ce40d0f0650be8a081ca2ac7a5eee53ac1c2c /src | |
parent | 492624d729730d594097aa618f8f1e34caa79639 (diff) | |
parent | b310d8c2e862d0a0db505eed8a29c15520fba845 (diff) | |
download | scala-79f7e05c082a1810f9315e19658e20af15b08235.tar.gz scala-79f7e05c082a1810f9315e19658e20af15b08235.tar.bz2 scala-79f7e05c082a1810f9315e19658e20af15b08235.zip |
Merge pull request #3631 from adriaanm/t4492
SI-4492 More informative error when class not found on classpath
Diffstat (limited to 'src')
4 files changed, 32 insertions, 7 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala index d439bb5603..9715fdaf00 100644 --- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala +++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala @@ -359,6 +359,14 @@ trait ContextErrors { //setError(sel) } + def SelectWithUnderlyingError(sel: Tree, err: AbsTypeError) = { + // if there's no position, this is likely the result of a MissingRequirementError + // use the position of the selection we failed to type check to report the original message + if (err.errPos == NoPosition) issueNormalTypeError(sel, err.errMsg) + else issueTypeError(err) + setError(sel) + } + //typedNew def IsAbstractError(tree: Tree, sym: Symbol) = { issueNormalTypeError(tree, sym + " is abstract; cannot be instantiated") diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala index 994a2a4f4f..8e1ceffecd 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala @@ -103,7 +103,7 @@ trait Contexts { self: Analyzer => // there must be a scala.xml package when xml literals were parsed in this unit if (unit.hasXml && ScalaXmlPackage == NoSymbol) - unit.error(unit.firstXmlPos, "To compile XML syntax, the scala.xml package must be on the classpath.\nPlease see https://github.com/scala/scala/wiki/Scala-2.11#xml.") + unit.error(unit.firstXmlPos, "To compile XML syntax, the scala.xml package must be on the classpath.\nPlease see http://docs.scala-lang.org/overviews/core/scala-2.11.html#scala-xml.") // scala-xml needs `scala.xml.TopScope` to be in scope globally as `$scope` // We detect `scala-xml` by looking for `scala.xml.TopScope` and @@ -544,6 +544,8 @@ trait Contexts { self: Analyzer => if (checking) onTreeCheckerError(pos, msg) else unit.error(pos, msg) @inline private def issueCommon(err: AbsTypeError)(pf: PartialFunction[AbsTypeError, Unit]) { + // TODO: are errors allowed to have pos == NoPosition?? + // if not, Jason suggests doing: val pos = err.errPos.orElse( { devWarning("Que?"); context.tree.pos }) if (settings.Yissuedebug) { log("issue error: " + err.errMsg) (new Exception).printStackTrace() diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 9f3f257529..9f557f4aa5 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -4670,8 +4670,8 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper case SilentTypeError(err: AccessTypeError) => (tree1, Some(err)) case SilentTypeError(err) => - context issue err - return setError(tree) + SelectWithUnderlyingError(tree, err) + return tree case SilentResultValue(treeAndPre) => (stabilize(treeAndPre._1, treeAndPre._2, mode, pt), None) } diff --git a/src/reflect/scala/reflect/internal/pickling/UnPickler.scala b/src/reflect/scala/reflect/internal/pickling/UnPickler.scala index 42f794736a..64a1a44722 100644 --- a/src/reflect/scala/reflect/internal/pickling/UnPickler.scala +++ b/src/reflect/scala/reflect/internal/pickling/UnPickler.scala @@ -229,6 +229,20 @@ abstract class UnPickler { NoSymbol } + def moduleAdvice(missing: String): String = { + val module = + if (missing.startsWith("scala.xml")) Some(("org.scala-lang.modules", "scala-xml")) + else if (missing.startsWith("scala.util.parsing")) Some(("org.scala-lang.modules", "scala-parser-combinators")) + else if (missing.startsWith("scala.swing")) Some(("org.scala-lang.modules", "scala-swing")) + else if (missing.startsWith("scala.util.continuations")) Some(("org.scala-lang.plugins", "scala-continuations-library")) + else None + + (module map { case (group, art) => + s"""\n(NOTE: It looks like the $art module is missing; try adding a dependency on "$group" : "$art". + | See http://docs.scala-lang.org/overviews/core/scala-2.11.html for more information.)""".stripMargin + } getOrElse "") + } + // (1) Try name. fromName(name) orElse { // (2) Try with expanded name. Can happen if references to private @@ -240,11 +254,12 @@ abstract class UnPickler { // (4) Call the mirror's "missing" hook. adjust(mirrorThatLoaded(owner).missingHook(owner, name)) orElse { // (5) Create a stub symbol to defer hard failure a little longer. + val fullName = s"${owner.fullName}.$name" val missingMessage = - s"""|bad symbolic reference. A signature in $filename refers to ${name.longString} - |in ${owner.kindString} ${owner.fullName} which is not available. - |It may be completely missing from the current classpath, or the version on - |the classpath might be incompatible with the version used when compiling $filename.""".stripMargin + s"""|bad symbolic reference to $fullName encountered in class file '$filename'. + |Cannot access ${name.longString} in ${owner.kindString} ${owner.fullName}. The current classpath may be + |missing a definition for $fullName, or $filename may have been compiled against a version that's + |incompatible with the one found on the current classpath.${moduleAdvice(fullName)}""".stripMargin owner.newStubSymbol(name, missingMessage) } } |