summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala10
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala52
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala2
-rw-r--r--test/files/neg/bug639.check2
-rw-r--r--test/files/neg/noMember1.check5
-rw-r--r--test/files/neg/noMember1.scala3
-rw-r--r--test/files/neg/noMember2.check5
-rw-r--r--test/files/neg/noMember2.scala3
8 files changed, 59 insertions, 23 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index 4b888f5a76..b578759c85 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -1239,13 +1239,13 @@ trait Namers { self: Analyzer =>
isValidSelector(from) {
if (currentRun.compileSourceFor(expr, from))
return typeSig(tree)
+
+ def notMember = context.error(tree.pos, from.decode + " is not a member of " + expr)
// for Java code importing Scala objects
- if (from.endsWith(nme.raw.DOLLAR))
- isValidSelector(from.subName(0, from.length -1)) {
- context.error(tree.pos, from.decode + " is not a member of " + expr)
- }
+ if (from endsWith nme.raw.DOLLAR)
+ isValidSelector(from stripEnd "$")(notMember)
else
- context.error(tree.pos, from.decode + " is not a member of " + expr)
+ notMember
}
if (checkNotRedundant(tree.pos, from, to))
diff --git a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
index 8e7563d9c7..b0547cb2e2 100644
--- a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
@@ -74,8 +74,12 @@ trait TypeDiagnostics {
def withAddendum(pos: Position) = (_: String) + addendums.getOrElse(pos, () => "")()
- def decodeWithNamespace(name: Name): String = {
- val prefix = if (name.isTypeName) "type " else "value "
+ def decodeWithKind(name: Name, owner: Symbol): String = {
+ val prefix = (
+ if (name.isTypeName) "type "
+ else if (owner.isPackageClass) "object "
+ else "value "
+ )
prefix + name.decode
}
@@ -84,21 +88,37 @@ trait TypeDiagnostics {
def linePrecedes(t1: Tree, t2: Tree) = t1.pos.isDefined && t1.pos.isDefined && t1.pos.line < t2.pos.line
def notAMember(sel: Tree, qual: Tree, name: Name) = {
- def decoded = decodeWithNamespace(name)
-
- def msg: String = name match {
- case nme.CONSTRUCTOR => qual.tpe.widen+" does not have a constructor"
- case _ =>
- def memberOf = if (qual.tpe.typeSymbol.isTypeParameterOrSkolem) "type parameter " else ""
- def possibleCause =
- if (linePrecedes(qual, sel))
- "\npossible cause: maybe a semicolon is missing before `"+decoded+"'?"
- else
- ""
-
- decoded+" is not a member of "+ memberOf + qual.tpe.widen + possibleCause
+ val owner = qual.tpe.typeSymbol
+ val target = qual.tpe.widen
+ def targetKindString = if (owner.isTypeParameterOrSkolem) "type parameter " else ""
+ def nameString = decodeWithKind(name, owner)
+ /** Illuminating some common situations and errors a bit further. */
+ def addendum = {
+ val companion = {
+ if (name.isTermName && owner.isPackageClass) {
+ target.member(name.toTypeName) match {
+ case NoSymbol => ""
+ case sym => "\nNote: %s exists, but it has no companion object.".format(sym)
+ }
+ }
+ else ""
+ }
+ val semicolon = (
+ if (linePrecedes(qual, sel))
+ "\npossible cause: maybe a semicolon is missing before `"+nameString+"'?"
+ else
+ ""
+ )
+ companion + semicolon
}
- inferError(sel.pos, withAddendum(qual.pos)(msg))
+
+ inferError(
+ sel.pos,
+ withAddendum(qual.pos)(
+ if (name == nme.CONSTRUCTOR) target + " does not have a constructor"
+ else nameString + " is not a member of " + targetKindString + target + addendum
+ )
+ )
}
/** Only prints the parameter names if they're not synthetic,
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index d805a33940..4d282a4e7d 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -3695,7 +3695,7 @@ trait Typers extends Modes {
log(context.imports)//debug
}
if (inaccessibleSym eq NoSymbol) {
- error(tree.pos, "not found: "+decodeWithNamespace(name))
+ error(tree.pos, "not found: "+decodeWithKind(name, context.owner))
}
else accessError(
tree, inaccessibleSym, context.enclClass.owner.thisType,
diff --git a/test/files/neg/bug639.check b/test/files/neg/bug639.check
index 2c6055cb96..30a93518a9 100644
--- a/test/files/neg/bug639.check
+++ b/test/files/neg/bug639.check
@@ -1,4 +1,4 @@
-bug639.scala:3: error: not found: value a
+bug639.scala:3: error: not found: object a
import a._
^
one error found
diff --git a/test/files/neg/noMember1.check b/test/files/neg/noMember1.check
new file mode 100644
index 0000000000..846574bef9
--- /dev/null
+++ b/test/files/neg/noMember1.check
@@ -0,0 +1,5 @@
+noMember1.scala:1: error: object MultiMap is not a member of package scala.collection.mutable
+Note: trait MultiMap exists, but it has no companion object.
+import scala.collection.mutable.MultiMap._
+ ^
+one error found
diff --git a/test/files/neg/noMember1.scala b/test/files/neg/noMember1.scala
new file mode 100644
index 0000000000..0aee7bff7f
--- /dev/null
+++ b/test/files/neg/noMember1.scala
@@ -0,0 +1,3 @@
+import scala.collection.mutable.MultiMap._
+
+class A
diff --git a/test/files/neg/noMember2.check b/test/files/neg/noMember2.check
new file mode 100644
index 0000000000..f65571bdc9
--- /dev/null
+++ b/test/files/neg/noMember2.check
@@ -0,0 +1,5 @@
+noMember2.scala:2: error: object MultiMap is not a member of package scala.collection.mutable
+Note: trait MultiMap exists, but it has no companion object.
+ val m = scala.collection.mutable.MultiMap(1, 2, 3)
+ ^
+one error found
diff --git a/test/files/neg/noMember2.scala b/test/files/neg/noMember2.scala
new file mode 100644
index 0000000000..bf72d4f471
--- /dev/null
+++ b/test/files/neg/noMember2.scala
@@ -0,0 +1,3 @@
+object Test {
+ val m = scala.collection.mutable.MultiMap(1, 2, 3)
+}