summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala')
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala42
1 files changed, 30 insertions, 12 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
index 6e0e78e8e2..6c735a2d44 100644
--- a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
@@ -82,6 +82,17 @@ trait TypeDiagnostics {
def posPrecedes(p1: Position, p2: Position) = p1.isDefined && p2.isDefined && p1.line < p2.line
def linePrecedes(t1: Tree, t2: Tree) = posPrecedes(t1.pos, t2.pos)
+ private object DealiasedType extends TypeMap {
+ def apply(tp: Type): Type = tp match {
+ // Avoid "explaining" that String is really java.lang.String,
+ // while still dealiasing types from non-default namespaces.
+ case TypeRef(pre, sym, args) if sym.isAliasType && !sym.isInDefaultNamespace =>
+ mapOver(tp.dealias)
+ case _ =>
+ mapOver(tp)
+ }
+ }
+
def notAMemberMessage(pos: Position, qual: Tree, name: Name) = {
val owner = qual.tpe.typeSymbol
val target = qual.tpe.widen
@@ -212,12 +223,17 @@ trait TypeDiagnostics {
else if (sym.variance == -1) "contravariant"
else "invariant"
- // I think this should definitely be on by default, but I need to
- // play with it a bit longer. For now it's behind -Xlint.
- def explainAlias(tp: Type) = (
- if (!settings.lint.value || (tp eq tp.normalize)) ""
- else " (which expands to)\n " + tp.normalize
- )
+ def explainAlias(tp: Type) = {
+ // Don't automatically normalize standard aliases; they still will be
+ // expanded if necessary to disambiguate simple identifiers.
+ if ((tp eq tp.normalize) || tp.typeSymbolDirect.isInDefaultNamespace) ""
+ else {
+ // A sanity check against expansion being identical to original.
+ val s = "" + DealiasedType(tp)
+ if (s == "" + tp) ""
+ else "\n (which expands to) " + s
+ }
+ }
/** Look through the base types of the found type for any which
* might have been valid subtypes if given conformant type arguments.
@@ -292,7 +308,6 @@ trait TypeDiagnostics {
}
"" // no elaborable variance situation found
}
-
def foundReqMsg(found: Type, req: Type): String = (
withDisambiguation(Nil, found, req)(
";\n found : " + found.toLongString + existentialContext(found) + explainAlias(found) +
@@ -309,8 +324,11 @@ trait TypeDiagnostics {
def modifyName(f: String => String) =
sym.name = newTypeName(f(sym.name.toString))
- def scalaQualify() = {
- val intersect = Set(trueOwner, aliasOwner) intersect Set(ScalaPackageClass, PredefModuleClass)
+ /** Prepend java.lang, scala., or Predef. if this type originated
+ * in one of those.
+ */
+ def qualifyDefaultNamespaces() = {
+ val intersect = Set(trueOwner, aliasOwner) intersect UnqualifiedOwners
if (intersect.nonEmpty) preQualify()
}
@@ -320,8 +338,8 @@ trait TypeDiagnostics {
def typeQualify() = if (sym.isTypeParameterOrSkolem) postQualify()
def nameQualify() = if (trueOwner.isPackageClass) preQualify() else postQualify()
- def trueOwner = tp.typeSymbol.owner.skipPackageObject
- def aliasOwner = tp.typeSymbolDirect.owner.skipPackageObject
+ def trueOwner = tp.typeSymbol.effectiveOwner
+ def aliasOwner = tp.typeSymbolDirect.effectiveOwner
def sym_==(other: TypeDiag) = tp.typeSymbol == other.tp.typeSymbol
def owner_==(other: TypeDiag) = trueOwner == other.trueOwner
@@ -385,7 +403,7 @@ trait TypeDiagnostics {
// scala package or predef, qualify with scala so it is not confusing why
// e.g. java.util.Iterator and Iterator are different types.
if (td1 name_== td2)
- tds foreach (_.scalaQualify())
+ tds foreach (_.qualifyDefaultNamespaces())
// If they still print identically:
// a) If they are type parameters with different owners, append (in <owner>)