summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@typesafe.com>2014-03-14 13:43:22 -0700
committerAdriaan Moors <adriaan.moors@typesafe.com>2014-03-14 15:41:29 -0700
commitb310d8c2e862d0a0db505eed8a29c15520fba845 (patch)
tree64637d3598a9441640fa7245c94fecf1654cddbe /src
parentefc0905f6b7a78bf3b454fbd9adb50aab5ffe20d (diff)
downloadscala-b310d8c2e862d0a0db505eed8a29c15520fba845.tar.gz
scala-b310d8c2e862d0a0db505eed8a29c15520fba845.tar.bz2
scala-b310d8c2e862d0a0db505eed8a29c15520fba845.zip
SI-4492 More informative error when class not found on classpath
Position the error based on Select tree that failed to type check, presumably due to an underlying MissingRequirementError, which has no position. There are lots of other ways we could rewrap a MRE and supplement position info, but that remains TODO. Jason's review comment is recorded in the code. Also try to detect the case of a missing module and provide some advice, as well as linking to the forthcoming 2.11 guide at http://docs.scala-lang.org/overviews/core/scala-2.11.html.
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala8
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Contexts.scala4
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala4
-rw-r--r--src/reflect/scala/reflect/internal/pickling/UnPickler.scala23
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)
}
}