From 8fcb94e134cae78fbc53be02e1d66948a3c28779 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 7 Apr 2020 16:16:20 +0200 Subject: [PATCH] Use a fast path when looking up trait setter getters. --- .../src/dotty/tools/dotc/core/NameOps.scala | 10 +++------- .../dotty/tools/dotc/transform/Memoize.scala | 18 +++++++++++++----- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/core/NameOps.scala b/compiler/src/dotty/tools/dotc/core/NameOps.scala index 57e4be8cd4ce..550f3243df6e 100644 --- a/compiler/src/dotty/tools/dotc/core/NameOps.scala +++ b/compiler/src/dotty/tools/dotc/core/NameOps.scala @@ -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) diff --git a/compiler/src/dotty/tools/dotc/transform/Memoize.scala b/compiler/src/dotty/tools/dotc/transform/Memoize.scala index bb23e6b5c7a9..4fb3d9876cfd 100644 --- a/compiler/src/dotty/tools/dotc/transform/Memoize.scala +++ b/compiler/src/dotty/tools/dotc/transform/Memoize.scala @@ -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))) {