diff options
author | Eugene Burmako <xeno.by@gmail.com> | 2014-01-22 18:53:02 +0300 |
---|---|---|
committer | Eugene Burmako <xeno.by@gmail.com> | 2014-01-22 20:20:32 +0300 |
commit | 47d1fb1e9975998d5f8dde63c08c0b3ab1cd5ae2 (patch) | |
tree | bf707759b878e3b1584c5497d5153c664bce5d07 /src/compiler/scala/reflect/macros | |
parent | a242101282ba986c4e336b759aaa08a32ca82a7b (diff) | |
download | scala-47d1fb1e9975998d5f8dde63c08c0b3ab1cd5ae2.tar.gz scala-47d1fb1e9975998d5f8dde63c08c0b3ab1cd5ae2.tar.bz2 scala-47d1fb1e9975998d5f8dde63c08c0b3ab1cd5ae2.zip |
SI-6879 improves Context.freshName
Instead of per-compilation unit unique counters, the freshName API now
uses a per-Global counter. Fresh names now also contain dollars to exclude
clashes with supported user-defined names (the ones without dollar signs).
This doesn’t fix the bug, because per-Global counters get created anew
every time a new Global is instantiated, and that provides some potential
for name clashes even for def macros, but at least it completely excludes
clashes in typical situations.
Diffstat (limited to 'src/compiler/scala/reflect/macros')
-rw-r--r-- | src/compiler/scala/reflect/macros/contexts/Names.scala | 28 |
1 files changed, 22 insertions, 6 deletions
diff --git a/src/compiler/scala/reflect/macros/contexts/Names.scala b/src/compiler/scala/reflect/macros/contexts/Names.scala index c2f14cf0f1..299af40b94 100644 --- a/src/compiler/scala/reflect/macros/contexts/Names.scala +++ b/src/compiler/scala/reflect/macros/contexts/Names.scala @@ -4,7 +4,9 @@ package contexts trait Names { self: Context => - def freshNameCreator = callsiteTyper.context.unit.fresh + import global._ + + def freshNameCreator = globalFreshNameCreator def fresh(): String = freshName() @@ -16,11 +18,25 @@ trait Names { freshName[NameType](name) def freshName(): String = - freshName("fresh$") - - def freshName(name: String): String = - freshNameCreator.newName(name) + freshName(nme.FRESH_PREFIX) + + def freshName(name: String): String = { + // In comparison with the first version of freshName, current "fresh" names + // at least can't clash with legible user-written identifiers and are much less likely to clash with each other. + // It is still not good enough however, because the counter gets reset every time we create a new Global. + // + // This would most certainly cause problems if Scala featured something like introduceTopLevel, + // but even for def macros this can lead to unexpected troubles. Imagine that one Global + // creates a term of an anonymous type with a member featuring a "fresh" name, and then another Global + // imports that term with a wildcard and then generates a "fresh" name of its own. Given unlucky + // circumstances these "fresh" names might end up clashing. + // + // TODO: hopefully SI-7823 will provide an ultimate answer to this problem. + // In the meanwhile I will also keep open the original issue: SI-6879 "c.freshName is broken". + val sortOfUniqueSuffix = freshNameCreator.newName(nme.FRESH_SUFFIX) + name + "$" + sortOfUniqueSuffix + } def freshName[NameType <: Name](name: NameType): NameType = - name.mapName(freshNameCreator.newName(_)).asInstanceOf[NameType] + name.mapName(freshName(_)).asInstanceOf[NameType] }
\ No newline at end of file |