summaryrefslogtreecommitdiff
path: root/src/compiler/scala
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2011-10-03 01:28:04 +0000
committerPaul Phillips <paulp@improving.org>2011-10-03 01:28:04 +0000
commitbeadafa2d83a539dae8f969b9789f896346484ec (patch)
tree90c69a49397cdb59120d59307b843c54c8f68908 /src/compiler/scala
parent55109d0d253c7e89660f1b61d17408648c0c53a4 (diff)
downloadscala-beadafa2d83a539dae8f969b9789f896346484ec.tar.gz
scala-beadafa2d83a539dae8f969b9789f896346484ec.tar.bz2
scala-beadafa2d83a539dae8f969b9789f896346484ec.zip
Selective dealiasing when printing errors.
*** Important note for busy commit log skimmers *** Symbol method "fullName" has been trying to serve the dual role of "how to print a symbol" and "how to find a class file." It cannot serve both these roles simultaneously, primarily because of package objects but other little things as well. Since in the majority of situations we want the one which corresponds to the idealized scala world, not the grubby bytecode, I went with that for fullName. When you require the path to a class (e.g. you are calling Class.forName) you should use javaClassName. package foo { package object bar { class Bippy } } If sym is Bippy's symbol, then sym.fullName == foo.bar.Bippy sym.javaClassName == foo.bar.package.Bippy *** End important note *** There are many situations where we (until now) forewent revealing everything we knew about a type mismatch. For instance, this isn't very helpful of scalac (at least in those more common cases where you didn't define type X on the previous repl line.) scala> type X = Int defined type alias X scala> def f(x: X): Byte = x <console>:8: error: type mismatch; found : X required: Byte def f(x: X): Byte = x ^ Now it says: found : X (which expands to) Int required: Byte def f(x: X): Byte = x ^ In addition I rearchitected a number of methods involving: - finding a symbol's owner - calculating a symbol's name - determining whether to print a prefix No review.
Diffstat (limited to 'src/compiler/scala')
-rw-r--r--src/compiler/scala/reflect/internal/Definitions.scala23
-rw-r--r--src/compiler/scala/reflect/internal/Symbols.scala86
-rw-r--r--src/compiler/scala/reflect/internal/Types.scala20
-rw-r--r--src/compiler/scala/reflect/runtime/Loaders.scala2
-rw-r--r--src/compiler/scala/reflect/runtime/ScalaToJava.scala2
-rw-r--r--src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Implicits.scala8
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala42
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala2
10 files changed, 113 insertions, 76 deletions
diff --git a/src/compiler/scala/reflect/internal/Definitions.scala b/src/compiler/scala/reflect/internal/Definitions.scala
index a46b7d6bc7..1d0ed2442e 100644
--- a/src/compiler/scala/reflect/internal/Definitions.scala
+++ b/src/compiler/scala/reflect/internal/Definitions.scala
@@ -142,12 +142,13 @@ trait Definitions extends reflect.api.StandardDefinitions {
lazy val EmptyPackage = RootClass.newPackage(NoPosition, nme.EMPTY_PACKAGE_NAME).setFlag(FINAL)
lazy val EmptyPackageClass = EmptyPackage.moduleClass
- lazy val JavaLangPackage = getModule(sn.JavaLang)
- lazy val ScalaPackage = getModule("scala")
- lazy val ScalaPackageClass = ScalaPackage.tpe.typeSymbol
+ lazy val JavaLangPackage = getModule(sn.JavaLang)
+ lazy val JavaLangPackageClass = JavaLangPackage.moduleClass
+ lazy val ScalaPackage = getModule(nme.scala_)
+ lazy val ScalaPackageClass = ScalaPackage.moduleClass
lazy val RuntimePackage = getModule("scala.runtime")
- lazy val RuntimePackageClass = RuntimePackage.tpe.typeSymbol
+ lazy val RuntimePackageClass = RuntimePackage.moduleClass
// convenient one-argument parameter lists
lazy val anyparam = List(AnyClass.typeConstructor)
@@ -221,7 +222,7 @@ trait Definitions extends reflect.api.StandardDefinitions {
lazy val BridgeClass = getClass("scala.annotation.bridge")
// fundamental reference classes
- lazy val ScalaObjectClass = getClass("scala.ScalaObject")
+ lazy val ScalaObjectClass = getMember(ScalaPackageClass, tpnme.ScalaObject)
lazy val PartialFunctionClass = getClass("scala.PartialFunction")
lazy val SymbolClass = getClass("scala.Symbol")
lazy val StringClass = getClass(sn.String)
@@ -233,9 +234,17 @@ trait Definitions extends reflect.api.StandardDefinitions {
// fundamental modules
lazy val SysPackage = getPackageObject("scala.sys")
def Sys_error = getMember(SysPackage, nme.error)
+
+ // Modules whose members are in the default namespace
+ lazy val UnqualifiedModules = List(PredefModule, ScalaPackage, JavaLangPackage)
+ // Those modules and their module classes
+ lazy val UnqualifiedOwners = UnqualifiedModules.toSet ++ UnqualifiedModules.map(_.moduleClass)
+
lazy val PredefModule: Symbol = getModule("scala.Predef")
- lazy val PredefModuleClass = PredefModule.tpe.typeSymbol
- def Predef_AnyRef = getMember(PredefModule, "AnyRef") // used by the specialization annotation
+ lazy val PredefModuleClass = PredefModule.moduleClass
+ // Note: this is not the type alias AnyRef, it's a val defined in Predef
+ // used by the @specialize annotation.
+ def Predef_AnyRef = getMember(PredefModule, tpnme.AnyRef.toTermName)
def Predef_classOf = getMember(PredefModule, nme.classOf)
def Predef_identity = getMember(PredefModule, nme.identity)
def Predef_conforms = getMember(PredefModule, nme.conforms)
diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala
index 82706d7265..aebe4184f4 100644
--- a/src/compiler/scala/reflect/internal/Symbols.scala
+++ b/src/compiler/scala/reflect/internal/Symbols.scala
@@ -395,22 +395,24 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
final def isAnonymousFunction = isSynthetic && (name containsName tpnme.ANON_FUN_NAME)
final def isAnonOrRefinementClass = isAnonymousClass || isRefinementClass
- final def isPackageObject = isModule && name == nme.PACKAGEkw && owner.isPackageClass
- final def isPackageObjectClass = isModuleClass && name.toTermName == nme.PACKAGEkw && owner.isPackageClass
- final def definedInPackage = owner.isPackageClass || owner.isPackageObjectClass
+ def isPackageObjectOrClass = (name.toTermName == nme.PACKAGEkw) && owner.isPackageClass
+ final def isPackageObject = isModule && isPackageObjectOrClass
+ final def isPackageObjectClass = isModuleClass && isPackageObjectOrClass
+ final def isDefinedInPackage = effectiveOwner.isPackageClass
final def isJavaInterface = isJavaDefined && isTrait
final def needsFlatClasses: Boolean = phase.flatClasses && rawowner != NoSymbol && !rawowner.isPackageClass
- // not printed as prefixes
- final def isPredefModule = this == PredefModule
- final def isScalaPackage = (this == ScalaPackage) || (isPackageObject && owner == ScalaPackageClass)
- final def isScalaPackageClass = skipPackageObject == ScalaPackageClass
- def inDefaultNamespace = owner.isPredefModule || owner.isScalaPackageClass
+ // In java.lang, Predef, or scala package/package object
+ def isInDefaultNamespace = UnqualifiedOwners(effectiveOwner)
/** If this is a package object or package object class, its owner: otherwise this.
*/
final def skipPackageObject: Symbol = if (isPackageObjectClass) owner else this
+ /** The owner, skipping package objects.
+ */
+ def effectiveOwner = owner.skipPackageObject
+
/** If this is a constructor, its owner: otherwise this.
*/
final def skipConstructor: Symbol = if (isConstructor) owner else this
@@ -418,11 +420,15 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** Conditions where we omit the prefix when printing a symbol, to avoid
* unpleasantries like Predef.String, $iw.$iw.Foo and <empty>.Bippy.
*/
- final def printWithoutPrefix = !settings.debug.value && (
- isScalaPackageClass || isPredefModule || isEffectiveRoot || isAnonOrRefinementClass ||
- nme.isReplWrapperName(name) // not isInterpreterWrapper due to nesting
+ final def isOmittablePrefix = !settings.debug.value && (
+ UnqualifiedOwners(skipPackageObject)
+ || isEmptyPrefix
+ )
+ def isEmptyPrefix = (
+ isEffectiveRoot // has no prefix for real, <empty> or <root>
+ || isAnonOrRefinementClass // has uninteresting <anon> or <refinement> prefix
+ || nme.isReplWrapperName(name) // has ugly $iw. prefix (doesn't call isInterpreterWrapper due to nesting)
)
-
def isFBounded = info.baseTypeSeq exists (_ contains this)
/** Is symbol a monomorphic type?
@@ -723,7 +729,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** The decoded name of the symbol, e.g. `==` instead of `\$eq\$eq`.
*/
- def decodedName: String = stripLocalSuffix(NameTransformer.decode(encodedName))
+ def decodedName: String = stripNameString(NameTransformer.decode(encodedName))
def moduleSuffix: String = (
if (hasModuleFlag && !isMethod && !isImplClass && !isJavaDefined) nme.MODULE_SUFFIX_STRING
@@ -732,22 +738,32 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** These should be moved somewhere like JavaPlatform.
*/
- def javaSimpleName = stripLocalSuffix("" + simpleName) + moduleSuffix
- def javaBinaryName = fullName('/') + moduleSuffix
- def javaClassName = fullName('.') + moduleSuffix
+ def javaSimpleName = ("" + simpleName).trim + moduleSuffix
+ def javaBinaryName = fullNameInternal('/') + moduleSuffix
+ def javaClassName = fullNameInternal('.') + moduleSuffix
/** The encoded full path name of this symbol, where outer names and inner names
* are separated by `separator` characters.
* Never translates expansions of operators back to operator symbol.
* Never adds id.
+ * Drops package objects.
+ */
+ final def fullName(separator: Char): String = stripNameString(fullNameInternal(separator))
+
+ /** Doesn't drop package objects, for those situations (e.g. classloading)
+ * where the true path is needed.
*/
- final def fullName(separator: Char): String = stripLocalSuffix {
+ private def fullNameInternal(separator: Char): String = (
if (isRoot || isRootPackage || this == NoSymbol) this.toString
else if (owner.isEffectiveRoot) encodedName
- else owner.enclClass.fullName(separator) + separator + encodedName
- }
+ else effectiveOwner.enclClass.fullName(separator) + separator + encodedName
+ )
- private def stripLocalSuffix(s: String) = s stripSuffix nme.LOCAL_SUFFIX_STRING
+ /** Strip package objects and any local suffix.
+ */
+ private def stripNameString(s: String) =
+ if (settings.debug.value) s
+ else s.replaceAllLiterally(".package", "").trim
/** The encoded full path name of this symbol, where outer names and inner names
* are separated by periods.
@@ -1358,11 +1374,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** The package containing this symbol, or NoSymbol if there
* is not one. */
- def enclosingPackage: Symbol = {
- val packSym = enclosingPackageClass
- if (packSym != NoSymbol) packSym.companionModule
- else packSym
- }
+ def enclosingPackage: Symbol = enclosingPackageClass.companionModule
/** Return the original enclosing method of this symbol. It should return
* the same thing as enclMethod when called before lambda lift,
@@ -1420,8 +1432,8 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** Is this symbol defined in the same scope and compilation unit as `that` symbol? */
def isCoDefinedWith(that: Symbol) = (
(this.rawInfo ne NoType) &&
- (this.owner == that.owner) && {
- !this.owner.isPackageClass ||
+ (this.effectiveOwner == that.effectiveOwner) && {
+ !this.effectiveOwner.isPackageClass ||
(this.sourceFile eq null) ||
(that.sourceFile eq null) ||
(this.sourceFile == that.sourceFile) || {
@@ -1784,11 +1796,10 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
* to the name of the owner.
*/
def hasMeaninglessName = (
- isSetterParameter // x$1
- || isClassConstructor // this
- || isPackageObject // package
- || isPackageObjectClass // package$
- || isRefinementClass // <refinement>
+ isSetterParameter // x$1
+ || isClassConstructor // this
+ || isPackageObjectOrClass // package
+ || isRefinementClass // <refinement>
)
/** String representation of symbol's simple name.
@@ -1812,9 +1823,8 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** String representation of location.
*/
def ownsString = {
- val owns = owner.skipPackageObject
- if (owns.isClass && !owns.printWithoutPrefix && !isScalaPackageClass) "" + owns
- else ""
+ val owns = effectiveOwner
+ if (owns.isClass && !owns.isEmptyPrefix) "" + owns else ""
}
/** String representation of location, plus a preposition. Doesn't do much,
@@ -1963,7 +1973,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
protected def doCookJavaRawInfo() {
def cook(sym: Symbol) {
- require(sym hasFlag JAVA)
+ require(sym.isJavaDefined, sym)
// @M: I think this is more desirable, but Martin prefers to leave raw-types as-is as much as possible
// object rawToExistentialInJava extends TypeMap {
// def apply(tp: Type): Type = tp match {
@@ -1985,9 +1995,9 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
if (isJavaDefined)
cook(this)
- else if (hasFlag(OVERLOADED))
+ else if (isOverloaded)
for (sym2 <- alternatives)
- if (sym2 hasFlag JAVA)
+ if (sym2.isJavaDefined)
cook(sym2)
}
}
diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala
index 34c6570c2a..43168190a3 100644
--- a/src/compiler/scala/reflect/internal/Types.scala
+++ b/src/compiler/scala/reflect/internal/Types.scala
@@ -1157,7 +1157,7 @@ trait Types extends api.Types { self: SymbolTable =>
override def prefixString =
if (settings.debug.value) sym.nameString + ".this."
else if (sym.isAnonOrRefinementClass) "this."
- else if (sym.printWithoutPrefix) ""
+ else if (sym.isOmittablePrefix) ""
else if (sym.isModuleClass) sym.fullName + "."
else sym.nameString + ".this."
override def safeToString: String =
@@ -1220,8 +1220,9 @@ trait Types extends api.Types { self: SymbolTable =>
override def termSymbol = sym
override def prefix: Type = pre
- override def prefixString: String =
- if ((sym.isEmptyPackage || sym.isInterpreterWrapper || sym.isPredefModule || sym.isScalaPackage) && !settings.debug.value) ""
+ override def prefixString =
+ if (sym.isPackageObjectOrClass) pre.prefixString
+ else if (sym.isOmittablePrefix) ""
else pre.prefixString + sym.nameString + "."
override def kind = "SingleType"
}
@@ -2050,8 +2051,10 @@ A type's typeSymbol should never be inspected directly.
override def prefixString = "" + (
if (settings.debug.value)
super.prefixString
- else if (sym.printWithoutPrefix)
+ else if (sym.isOmittablePrefix)
""
+ else if (sym.isPackageObjectOrClass)
+ sym.owner.fullName + "."
else if (sym.isPackageClass)
sym.fullName + "."
else if (isStable && nme.isSingletonName(sym.name))
@@ -4080,7 +4083,7 @@ A type's typeSymbol should never be inspected directly.
def corresponds(sym1: Symbol, sym2: Symbol): Boolean =
sym1.name == sym2.name && (sym1.isPackageClass || corresponds(sym1.owner, sym2.owner))
if (!corresponds(sym.owner, rebind0.owner)) {
- debuglog("ADAPT1 pre = "+pre+", sym = "+sym+sym.locationString+", rebind = "+rebind0+rebind0.locationString)
+ debuglog("ADAPT1 pre = "+pre+", sym = "+sym.fullLocationString+", rebind = "+rebind0.fullLocationString)
val bcs = pre.baseClasses.dropWhile(bc => !corresponds(bc, sym.owner));
if (bcs.isEmpty)
assert(pre.typeSymbol.isRefinementClass, pre) // if pre is a refinementclass it might be a structural type => OK to leave it in.
@@ -4089,11 +4092,8 @@ A type's typeSymbol should never be inspected directly.
debuglog(
"ADAPT2 pre = " + pre +
", bcs.head = " + bcs.head +
- ", sym = " + sym+sym.locationString +
- ", rebind = " + rebind0 + (
- if (rebind0 == NoSymbol) ""
- else rebind0.locationString
- )
+ ", sym = " + sym.fullLocationString +
+ ", rebind = " + rebind0.fullLocationString
)
}
val rebind = rebind0.suchThat(sym => sym.isType || sym.isStable)
diff --git a/src/compiler/scala/reflect/runtime/Loaders.scala b/src/compiler/scala/reflect/runtime/Loaders.scala
index e16431df99..46ee176b0f 100644
--- a/src/compiler/scala/reflect/runtime/Loaders.scala
+++ b/src/compiler/scala/reflect/runtime/Loaders.scala
@@ -35,7 +35,7 @@ trait Loaders { self: SymbolTable =>
assert(sym == clazz || sym == module || sym == module.moduleClass)
// try {
atPhaseNotLaterThan(picklerPhase) {
- unpickleClass(clazz, module, javaClass(clazz.fullName))
+ unpickleClass(clazz, module, javaClass(clazz.javaClassName))
// } catch {
// case ex: ClassNotFoundException => makePackage()
// case ex: NoClassDefFoundError => makePackage()
diff --git a/src/compiler/scala/reflect/runtime/ScalaToJava.scala b/src/compiler/scala/reflect/runtime/ScalaToJava.scala
index db8658d30c..b1e4d6224c 100644
--- a/src/compiler/scala/reflect/runtime/ScalaToJava.scala
+++ b/src/compiler/scala/reflect/runtime/ScalaToJava.scala
@@ -43,7 +43,7 @@ trait ScalaToJava extends ConversionUtil { self: SymbolTable =>
else if (clazz == ArrayClass)
noClass
else if (clazz.owner.isPackageClass)
- javaClass(clazz.fullName)
+ javaClass(clazz.javaClassName)
else if (clazz.owner.isClass)
classToJava(clazz.owner)
.getDeclaredClasses
diff --git a/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala b/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala
index 2a7f11325c..d735044e07 100644
--- a/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala
+++ b/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala
@@ -39,7 +39,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
"memberSym " + memberSym + " templateSym " + templateSym + " encls = " +
closestPackage(memberSym) + ", " + closestPackage(templateSym)
)
- memberSym.inDefaultNamespace || (closestPackage(memberSym) == closestPackage(templateSym))
+ memberSym.isOmittablePrefix || (closestPackage(memberSym) == closestPackage(templateSym))
}
private lazy val noSubclassCache = Set(AnyClass, AnyRefClass, ObjectClass, ScalaObjectClass)
diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
index 169295e5c9..660999eb64 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
@@ -335,8 +335,8 @@ trait Implicits {
pre1: String, pre2: String, trailer: String) =
if (!info1.tpe.isErroneous && !info2.tpe.isErroneous) {
val coreMsg =
- pre1+" "+info1.sym+info1.sym.locationString+" of type "+info1.tpe+"\n "+
- pre2+" "+info2.sym+info2.sym.locationString+" of type "+info2.tpe+"\n "+
+ pre1+" "+info1.sym.fullLocationString+" of type "+info1.tpe+"\n "+
+ pre2+" "+info2.sym.fullLocationString+" of type "+info2.tpe+"\n "+
trailer
error(tree.pos,
if (isView) {
@@ -408,7 +408,7 @@ trait Implicits {
if (!(pt.isErroneous))
context.unit.error(
tree.pos, "diverging implicit expansion for type "+pt+"\nstarting with "+
- info.sym+info.sym.locationString)
+ info.sym.fullLocationString)
SearchFailure
} else {
throw DivergentImplicit
@@ -545,7 +545,7 @@ trait Implicits {
SearchFailure
else if (!hasMatchingSymbol(itree1))
fail("candidate implicit %s is shadowed by other implicit %s".format(
- info.sym + info.sym.locationString, itree1.symbol + itree1.symbol.locationString))
+ info.sym.fullLocationString, itree1.symbol.fullLocationString))
else {
val tvars = undetParams map freshVar
diff --git a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
index 360acbd469..31aaaa36b8 100644
--- a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
@@ -403,7 +403,7 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT
val isCandidate = (
sym.isProtected
&& sym.isJavaDefined
- && !sym.definedInPackage
+ && !sym.isDefinedInPackage
&& !accessibleThroughSubclassing
&& (sym.owner.enclosingPackageClass != currentOwner.enclosingPackageClass)
&& (sym.owner.enclosingPackageClass == packageAccessBoundry(sym))
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>)
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 5bd936bfb7..deff4c10a2 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -3848,7 +3848,7 @@ trait Typers extends Modes with Adaptations {
if (defSym.exists && impSym.exists) {
// imported symbols take precedence over package-owned symbols in different
// compilation units. Defined symbols take precedence over erroneous imports.
- if (defSym.definedInPackage &&
+ if (defSym.isDefinedInPackage &&
(!currentRun.compiles(defSym) ||
context.unit.exists && defSym.sourceFile != context.unit.source.file))
defSym = NoSymbol