@@ -118,61 +118,51 @@ class Memoize extends MiniPhase with IdentityDenotTransformer { thisPhase =>
118118 EmptyTree
119119 }
120120
121- def traitSetterGetter : Symbol =
122- /* We have to compare SimpleNames here, because the setter name only
123- * embeds the original getter's simple name, not its semantic name.
124- * To mitigate the issue, we first try a fast path where we look up the
125- * simple name itself, which works for public fields.
126- */
127- val TraitSetterName (_, original) = sym.name
128- val getterSimpleName = original.getterName
129- val ownerInfo = sym.owner.info
130- val fastPath = ownerInfo.findDecl(getterSimpleName, excluded = Bridge )
131- if fastPath.exists then
132- fastPath.symbol
133- else
134- ownerInfo.decls.find { getter =>
135- getter.is(Accessor , butNot = Bridge ) && getter.asTerm.name.toSimpleName == getterSimpleName
136- }
137-
138- val constantFinalVal = sym.isAllOf(Accessor | Final , butNot = Mutable ) && tree.rhs.isInstanceOf [Literal ]
139-
140- if (sym.is(Accessor , butNot = NoFieldNeeded ) && ! constantFinalVal
141- && (! sym.name.is(TraitSetterName ) || traitSetterGetter.is(Accessor , butNot = NoFieldNeeded ))) {
142- val field = sym.field.orElse(newField).asTerm
143-
144- def adaptToField (tree : Tree ): Tree =
121+ if sym.is(Accessor , butNot = NoFieldNeeded ) then
122+ def adaptToField (field : Symbol , tree : Tree ): Tree =
145123 if (tree.isEmpty) tree else tree.ensureConforms(field.info.widen)
146124
147- def isErasableBottomField (cls : Symbol ): Boolean =
125+ def isErasableBottomField (field : Symbol , cls : Symbol ): Boolean =
148126 ! field.isVolatile && ((cls eq defn.NothingClass ) || (cls eq defn.NullClass ) || (cls eq defn.BoxedUnitClass ))
149127
150- if (sym.isGetter) {
151- var rhs = tree.rhs.changeOwnerAfter(sym, field, thisPhase)
152- if (isWildcardArg(rhs)) rhs = EmptyTree
153- val fieldDef = transformFollowing(ValDef (field, adaptToField(rhs)))
154- val rhsClass = tree.tpt.tpe.widenDealias.classSymbol
155- val getterRhs =
156- if (isErasableBottomField(rhsClass)) erasedBottomTree(rhsClass)
157- else transformFollowingDeep(ref(field))(using ctx.withOwner(sym))
158- val getterDef = cpy.DefDef (tree)(rhs = getterRhs)
159- addAnnotations(fieldDef.denot)
160- removeUnwantedAnnotations(sym)
161- Thicket (fieldDef, getterDef)
162- }
163- else if (sym.isSetter) {
128+ if sym.isGetter then
129+ val constantFinalVal = sym.isAllOf(Accessor | Final , butNot = Mutable ) && tree.rhs.isInstanceOf [Literal ]
130+ if constantFinalVal then
131+ // constant final vals do not need to be transformed at all, and do not need a field
132+ tree
133+ else
134+ val field = newField.asTerm
135+ var rhs = tree.rhs.changeOwnerAfter(sym, field, thisPhase)
136+ if (isWildcardArg(rhs)) rhs = EmptyTree
137+ val fieldDef = transformFollowing(ValDef (field, adaptToField(field, rhs)))
138+ val rhsClass = tree.tpt.tpe.widenDealias.classSymbol
139+ val getterRhs =
140+ if isErasableBottomField(field, rhsClass) then erasedBottomTree(rhsClass)
141+ else transformFollowingDeep(ref(field))(using ctx.withOwner(sym))
142+ val getterDef = cpy.DefDef (tree)(rhs = getterRhs)
143+ addAnnotations(fieldDef.denot)
144+ removeUnwantedAnnotations(sym)
145+ Thicket (fieldDef, getterDef)
146+ else if sym.isSetter then
164147 if (! sym.is(ParamAccessor )) { val Literal (Constant (())) = tree.rhs } // This is intended as an assertion
165- field.setFlag(Mutable ) // Necessary for vals mixed in from Scala2 traits
166- val initializer =
167- if (isErasableBottomField(tree.vparamss.head.head.tpt.tpe.classSymbol)) Literal (Constant (()))
168- else Assign (ref(field), adaptToField(ref(tree.vparamss.head.head.symbol)))
169- val setterDef = cpy.DefDef (tree)(rhs = transformFollowingDeep(initializer)(using ctx.withOwner(sym)))
170- removeUnwantedAnnotations(sym)
171- setterDef
172- }
173- else tree // curiously, some accessors from Scala2 have ' ' suffixes. They count as
174- // neither getters nor setters
175- }
176- else tree
148+ val field = sym.field
149+ if ! field.exists then
150+ // When transforming the getter, we determined that no field was needed.
151+ // In that case we can keep the setter as is, with a () rhs.
152+ tree
153+ else
154+ field.setFlag(Mutable ) // Necessary for vals mixed in from traits
155+ val initializer =
156+ if (isErasableBottomField(field, tree.vparamss.head.head.tpt.tpe.classSymbol)) Literal (Constant (()))
157+ else Assign (ref(field), adaptToField(field, ref(tree.vparamss.head.head.symbol)))
158+ val setterDef = cpy.DefDef (tree)(rhs = transformFollowingDeep(initializer)(using ctx.withOwner(sym)))
159+ removeUnwantedAnnotations(sym)
160+ setterDef
161+ else
162+ // Curiously, some accessors from Scala2 have ' ' suffixes.
163+ // They count as neither getters nor setters.
164+ tree
165+ else
166+ tree
177167 }
178168}
0 commit comments