Skip to content

Commit

Permalink
Use a fast path when looking up trait setter getters.
Browse files Browse the repository at this point in the history
  • Loading branch information
sjrd committed Apr 7, 2020
1 parent 0d9e3fc commit 8fcb94e
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 12 deletions.
10 changes: 3 additions & 7 deletions compiler/src/dotty/tools/dotc/core/NameOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -259,13 +259,9 @@ object NameOps {
def setterName: TermName = name.exclude(FieldName) ++ str.SETTER_SUFFIX

def getterName: TermName =
if name.is(TraitSetterName) then
val TraitSetterName(_, original) = name
original.getterName
else
name.exclude(FieldName).mapLast(n =>
if (n.endsWith(str.SETTER_SUFFIX)) n.take(n.length - str.SETTER_SUFFIX.length).asSimpleName
else n)
name.exclude(FieldName).mapLast(n =>
if (n.endsWith(str.SETTER_SUFFIX)) n.take(n.length - str.SETTER_SUFFIX.length).asSimpleName
else n)

def fieldName: TermName =
if (name.isSetterName)
Expand Down
18 changes: 13 additions & 5 deletions compiler/src/dotty/tools/dotc/transform/Memoize.scala
Original file line number Diff line number Diff line change
Expand Up @@ -117,12 +117,20 @@ class Memoize extends MiniPhase with IdentityDenotTransformer { thisPhase =>

def traitSetterGetter: Symbol =
/* We have to compare SimpleNames here, because the setter name only
* embed the original getter's simple name, not its semantic name.
* embeds the original getter's simple name, not its semantic name.
* To mitigate the issue, we first try a fast path where we look up the
* simple name itself, which works for public fields.
*/
val getterSimpleName = sym.asTerm.name.getterName
sym.owner.info.decls.find { getter =>
getter.is(Accessor) && getter.asTerm.name.toSimpleName == getterSimpleName
}
val TraitSetterName(_, original) = sym.name
val getterSimpleName = original.getterName
val ownerInfo = sym.owner.info
val fastPath = ownerInfo.decl(getterSimpleName)
if fastPath.exists then
fastPath.symbol
else
ownerInfo.decls.find { getter =>
getter.is(Accessor) && getter.asTerm.name.toSimpleName == getterSimpleName
}

if (sym.is(Accessor, butNot = NoFieldNeeded)
&& (!sym.name.is(TraitSetterName) || traitSetterGetter.is(Accessor, butNot = NoFieldNeeded))) {
Expand Down

0 comments on commit 8fcb94e

Please sign in to comment.