diff --git a/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala b/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala index a91ece4da07f..3a3cb512cc6b 100644 --- a/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala +++ b/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala @@ -99,6 +99,7 @@ class ScalaSettings extends Settings.SettingGroup { val YdumpSbtInc = BooleanSetting("-Ydump-sbt-inc", "For every compiled foo.scala, output the API representation and dependencies used for sbt incremental compilation in foo.inc, implies -Yforce-sbt-phases.") val YcheckAllPatmat = BooleanSetting("-Ycheck-all-patmat", "Check exhaustivity and redundancy of all pattern matching (used for testing the algorithm)") val YretainTrees = BooleanSetting("-Yretain-trees", "Retain trees for top-level classes, accessible from ClassSymbol#tree") + val YshowTreeIds = BooleanSetting("-Yshow-tree-ids", "Uniquely tag all tree nodes in debugging output.") /** Area-specific debug output */ val Yexplainlowlevel = BooleanSetting("-Yexplain-lowlevel", "When explaining type errors, show types at a lower level.") diff --git a/compiler/src/dotty/tools/dotc/core/NameKinds.scala b/compiler/src/dotty/tools/dotc/core/NameKinds.scala index 396ef6f821e7..430a36fda1c0 100644 --- a/compiler/src/dotty/tools/dotc/core/NameKinds.scala +++ b/compiler/src/dotty/tools/dotc/core/NameKinds.scala @@ -42,10 +42,11 @@ object NameKinds { override def toString = infoString } - /** Does this kind define logically a new name? Tested by the `rewrite` and `collect` - * combinators of names. + /** Does this kind define logically a new name (respectively qualified name)? + * Tested by the `rewrite` and `collect` combinators of class `Name`. */ def definesNewName = false + def definesQualifiedName = false /** Unmangle simple name `name` into a name of this kind, or return * original name if this is not possible. @@ -142,6 +143,7 @@ object NameKinds { } override def definesNewName = true + override def definesQualifiedName = true def mkString(underlying: TermName, info: ThisInfo) = s"$underlying$separator${info.name}" diff --git a/compiler/src/dotty/tools/dotc/core/Names.scala b/compiler/src/dotty/tools/dotc/core/Names.scala index 9d6b03cf5afc..d379653aa372 100644 --- a/compiler/src/dotty/tools/dotc/core/Names.scala +++ b/compiler/src/dotty/tools/dotc/core/Names.scala @@ -233,9 +233,15 @@ object Names { } } + /** Is it impossible that names of kind `kind` also qualify as names of kind `shadowed`? */ + private def shadows(kind: NameKind, shadowed: NameKind): Boolean = + kind.tag < shadowed.tag || + kind.definesQualifiedName || + kind.definesNewName && !shadowed.definesQualifiedName + override def exclude(kind: NameKind): TermName = { val thisKind = this.info.kind - if (thisKind.tag < kind.tag || thisKind.definesNewName) this + if (shadows(thisKind, kind)) this else if (thisKind.tag > kind.tag) rewrap(underlying.exclude(kind)) else underlying } @@ -243,7 +249,7 @@ object Names { override def is(kind: NameKind): Boolean = { val thisKind = this.info.kind thisKind == kind || - !thisKind.definesNewName && thisKind.tag > kind.tag && underlying.is(kind) + !shadows(thisKind, kind) && underlying.is(kind) } @sharable // because it's just a cache for performance diff --git a/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala b/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala index 5b2cbc5718cb..6cfec7f16c1d 100644 --- a/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala +++ b/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala @@ -617,6 +617,8 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) { val clsStr = ""//if (tree.isType) tree.getClass.toString else "" txt = (txt ~ "@" ~ pos.toString ~ clsStr).close } + if (ctx.settings.YshowTreeIds.value) + txt = (txt ~ "#" ~ tree.uniqueId.toString).close tree match { case Block(_, _) | Template(_, _, _, _) => txt case _ => txt.close diff --git a/tests/run/i2795.scala b/tests/run/i2795.scala new file mode 100644 index 000000000000..154fc160df25 --- /dev/null +++ b/tests/run/i2795.scala @@ -0,0 +1,9 @@ +import reflect.ClassTag + +trait Foo[T: ClassTag]() { + def foo(x: T) = Array(x) +} +class Bar extends Foo[Int]() +object Test extends App { + (new Bar).foo(3) +} \ No newline at end of file