diff options
-rw-r--r-- | src/dotty/tools/dotc/core/NameOps.scala | 15 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/StdNames.scala | 1 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/SymDenotations.scala | 9 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/FirstTransform.scala | 10 | ||||
-rw-r--r-- | tests/new/S5.scala (renamed from tests/pending/pos/S5.scala) | 3 |
5 files changed, 31 insertions, 7 deletions
diff --git a/src/dotty/tools/dotc/core/NameOps.scala b/src/dotty/tools/dotc/core/NameOps.scala index a6b40fe66..240447e6d 100644 --- a/src/dotty/tools/dotc/core/NameOps.scala +++ b/src/dotty/tools/dotc/core/NameOps.scala @@ -72,6 +72,7 @@ object NameOps { def isSetterName = name endsWith SETTER_SUFFIX def isSingletonName = name endsWith SINGLETON_SUFFIX def isModuleClassName = name endsWith MODULE_SUFFIX + def isAvoidClashName = name endsWith AVOID_CLASH_SUFFIX def isImportName = name startsWith IMPORT def isFieldName = name endsWith LOCAL_SUFFIX def isInheritedName = name.length > 0 && name.head == '(' && name.startsWith(nme.INHERITED) @@ -129,11 +130,19 @@ object NameOps { /** If name ends in module class suffix, drop it */ def stripModuleClassSuffix: Name = if (isModuleClassName) name dropRight MODULE_SUFFIX.length else name + + /** Append a suffix so that this name does not clash with another name in the same scope */ + def avoidClashName: TermName = (name ++ AVOID_CLASH_SUFFIX).toTermName + + /** If name ends in "avoid clash" suffix, drop it */ + def stripAvoidClashSuffix: Name = + if (isAvoidClashName) name dropRight AVOID_CLASH_SUFFIX.length else name /** If flags is a ModuleClass but not a Package, add module class suffix */ - def adjustIfModuleClass(flags: Flags.FlagSet): N = - if (flags is (ModuleClass, butNot = Package)) name.asTypeName.moduleClassName.asInstanceOf[N] - else name + def adjustIfModuleClass(flags: Flags.FlagSet): N = { + if (flags is (ModuleClass, butNot = Package)) name.asTypeName.moduleClassName + else stripAvoidClashSuffix + }.asInstanceOf[N] /** The superaccessor for method with given name */ def superName: TermName = (nme.SUPER_PREFIX ++ name).toTermName diff --git a/src/dotty/tools/dotc/core/StdNames.scala b/src/dotty/tools/dotc/core/StdNames.scala index 04bcf616d..27aa00392 100644 --- a/src/dotty/tools/dotc/core/StdNames.scala +++ b/src/dotty/tools/dotc/core/StdNames.scala @@ -107,6 +107,7 @@ object StdNames { val INTERPRETER_WRAPPER_SUFFIX: N = "$object" val LOCALDUMMY_PREFIX: N = "<local " // owner of local blocks val MODULE_SUFFIX: N = NameTransformer.MODULE_SUFFIX_STRING + val AVOID_CLASH_SUFFIX: N = "$_avoid_name_clash_$" val MODULE_VAR_SUFFIX: N = "$module" val NAME_JOIN: N = NameTransformer.NAME_JOIN_STRING val USCORE_PARAM_PREFIX: N = "_$" diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala index eccdcbfb9..613d4b29c 100644 --- a/src/dotty/tools/dotc/core/SymDenotations.scala +++ b/src/dotty/tools/dotc/core/SymDenotations.scala @@ -171,9 +171,14 @@ object SymDenotations { myInfo = tp } - /** The name, except if this is a module class, strip the module class suffix */ + /** The name, except + * - if this is a module class, strip the module class suffix + * - if this is a companion object with a clash-avoiding name, strip the + * "avoid clash" suffix + */ def effectiveName(implicit ctx: Context) = - if (this is ModuleClass) name.stripModuleClassSuffix else name + if (this is ModuleClass) name.stripModuleClassSuffix + else name.stripAvoidClashSuffix /** The privateWithin boundary, NoSymbol if no boundary is given. */ diff --git a/src/dotty/tools/dotc/transform/FirstTransform.scala b/src/dotty/tools/dotc/transform/FirstTransform.scala index 62045890e..bde17c854 100644 --- a/src/dotty/tools/dotc/transform/FirstTransform.scala +++ b/src/dotty/tools/dotc/transform/FirstTransform.scala @@ -81,7 +81,15 @@ class FirstTransform extends MiniPhaseTransform with IdentityDenotTransformer wi def addMissingCompanions(stats: List[Tree]): List[Tree] = stats map { case stat: TypeDef if singleClassDefs contains stat.name => - Thicket(stat :: newCompanion(stat.name.toTermName).trees) + val objName = stat.name.toTermName + val nameClash = stats.exists { + case other: MemberDef => + other.name == objName && other.symbol.info.isParameterless + case _ => + false + } + val uniqueName = if (nameClash) objName.avoidClashName else objName + Thicket(stat :: newCompanion(uniqueName).trees) case stat => stat } diff --git a/tests/pending/pos/S5.scala b/tests/new/S5.scala index f0b66a6e6..ba87869a1 100644 --- a/tests/pending/pos/S5.scala +++ b/tests/new/S5.scala @@ -1,4 +1,5 @@ -/* Here's a fragment of a Scala encoding for the Keris module system; +/* Original comment: + * Here's a fragment of a Scala encoding for the Keris module system; ** the compiler claims: ** ** S5.scala:28: value n in class N of type N.this._N.n |