Skip to content

Commit 01260f4

Browse files
committed
Don't disambiguate between terms and types
An ExplainingTypePrinter would disambiguate between a class and its companion object, like this: {message involving C and C'} where C is a class ... C' is an object I believe this is not necessessary, as types and terms should be distinguishable from the context in which they appear.
1 parent 11b8ee8 commit 01260f4

File tree

2 files changed

+27
-14
lines changed

2 files changed

+27
-14
lines changed

compiler/src/dotty/tools/dotc/printing/Formatting.scala

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -106,22 +106,32 @@ object Formatting {
106106

107107
private type Recorded = AnyRef /*Symbol | ParamRef | SkolemType */
108108

109-
private class Seen extends mutable.HashMap[String, List[Recorded]] {
109+
private case class SeenKey(str: String, isType: Boolean)
110+
private class Seen extends mutable.HashMap[SeenKey, List[Recorded]] {
110111

111-
override def default(key: String) = Nil
112+
override def default(key: SeenKey) = Nil
112113

113-
def record(str: String, entry: Recorded)(implicit ctx: Context): String = {
114+
def record(str: String, isType: Boolean, entry: Recorded)(implicit ctx: Context): String = {
115+
116+
/** If `e1` is an alias of another class of the same name, return the other
117+
* class symbol instead. This normalization avoids recording e.g. scala.List
118+
* and scala.collection.immutable.List as two different types
119+
*/
114120
def followAlias(e1: Recorded): Recorded = e1 match {
115121
case e1: Symbol if e1.isAliasType =>
116122
val underlying = e1.typeRef.underlyingClassRef(refinementOK = false).typeSymbol
117123
if (underlying.name == e1.name) underlying else e1
118124
case _ => e1
119125
}
126+
val key = SeenKey(str, isType)
127+
val existing = apply(key)
120128
lazy val dealiased = followAlias(entry)
121-
var alts = apply(str).dropWhile(alt => dealiased ne followAlias(alt))
129+
130+
// alts: The alternatives in `existing` that are equal, or follow (an alias of) `entry`
131+
var alts = existing.dropWhile(alt => dealiased ne followAlias(alt))
122132
if (alts.isEmpty) {
123-
alts = entry :: apply(str)
124-
update(str, alts)
133+
alts = entry :: existing
134+
update(key, alts)
125135
}
126136
str + "'" * (alts.length - 1)
127137
}
@@ -135,13 +145,13 @@ object Formatting {
135145

136146
override def simpleNameString(sym: Symbol): String =
137147
if (useSourceModule(sym)) simpleNameString(sym.sourceModule)
138-
else seen.record(super.simpleNameString(sym), sym)
148+
else seen.record(super.simpleNameString(sym), sym.isType, sym)
139149

140150
override def ParamRefNameString(param: ParamRef): String =
141-
seen.record(super.ParamRefNameString(param), param)
151+
seen.record(super.ParamRefNameString(param), param.isInstanceOf[TypeParamRef], param)
142152

143153
override def toTextRef(tp: SingletonType): Text = tp match {
144-
case tp: SkolemType => seen.record(tp.repr.toString, tp)
154+
case tp: SkolemType => seen.record(tp.repr.toString, isType = true, tp)
145155
case _ => super.toTextRef(tp)
146156
}
147157

@@ -207,10 +217,13 @@ object Formatting {
207217
}
208218

209219
val toExplain: List[(String, Recorded)] = seen.toList.flatMap {
210-
case (str, entry :: Nil) =>
211-
if (needsExplanation(entry)) (str, entry) :: Nil else Nil
212-
case (str, entries) =>
213-
entries.map(alt => (seen.record(str, alt), alt))
220+
case (key, entry :: Nil) =>
221+
if (needsExplanation(entry)) (key.str, entry) :: Nil else Nil
222+
case (key, entries) =>
223+
for (alt <- entries) yield {
224+
val tickedString = seen.record(key.str, key.isType, alt)
225+
(tickedString, alt)
226+
}
214227
}.sortBy(_._1)
215228

216229
def columnar(parts: List[(String, String)]): List[String] = {

compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ class PlainPrinter(_ctx: Context) extends Printer {
298298
}
299299
}
300300

301-
/** The string representation of this type used as a prefix */
301+
/** The string representation of this type used as a prefix, including separator */
302302
protected def toTextPrefix(tp: Type): Text = controlled {
303303
homogenize(tp) match {
304304
case NoPrefix => ""

0 commit comments

Comments
 (0)