@@ -573,8 +573,12 @@ object Denotations {
573573
574574 final def name (using Context ): Name = symbol.name
575575
576- /** If this is not a SymDenotation: The prefix under which the denotation was constructed.
577- * NoPrefix for SymDenotations.
576+ /** For SymDenotation, this is NoPrefix. For other denotations this is the prefix
577+ * under which the denotation was constructed.
578+ *
579+ * Note that `asSeenFrom` might return a `SymDenotation` and therefore in
580+ * general one cannot rely on `prefix` being set, see
581+ * `Config.reuseSymDenotations` for details.
578582 */
579583 def prefix : Type = NoPrefix
580584
@@ -1044,24 +1048,25 @@ object Denotations {
10441048 }
10451049
10461050 /** The derived denotation with the given `info` transformed with `asSeenFrom`.
1047- * The prefix of the derived denotation is the new prefix `pre` if the type is
1048- * opaque, or if the current prefix is already different from `NoPrefix`.
1049- * That leaves SymDenotations (which have NoPrefix as the prefix), which are left
1050- * as SymDenotations unless the type is opaque. The treatment of opaque types
1051- * is needed, without it i7159.scala fails in from-tasty. Without the treatment,
1052- * opaque type denotations in subclasses are kept as SymDenotations, which means
1053- * that the transform in `ElimOpaque` will return the symbol's opaque alias without
1054- * adding the needed asSeenFrom.
10551051 *
1056- * Logically, the right thing to do would be to extend the same treatment to all denotations
1057- * Currently this fails the bootstrap. There's also a concern that this generalization
1058- * would create more denotation objects, at a price in performance .
1052+ * As a performance hack, we might reuse an existing SymDenotation,
1053+ * instead of creating a new denotation with a given `prefix`,
1054+ * see `Config.reuseSymDenotations` .
10591055 */
10601056 def derived (info : Type ) =
1061- derivedSingleDenotation(
1062- symbol,
1063- info.asSeenFrom(pre, owner),
1064- if (symbol.is(Opaque ) || this .prefix != NoPrefix ) pre else this .prefix)
1057+ /** Do we need to return a denotation with a prefix set? */
1058+ def needsPrefix =
1059+ // For opaque types, the prefix is used in `ElimOpaques#transform`,
1060+ // without this i7159.scala would fail when compiled from tasty.
1061+ symbol.is(Opaque )
1062+
1063+ val derivedInfo = info.asSeenFrom(pre, owner)
1064+ if Config .reuseSymDenotations && this .isInstanceOf [SymDenotation ]
1065+ && (derivedInfo eq info) && ! needsPrefix then
1066+ this
1067+ else
1068+ derivedSingleDenotation(symbol, derivedInfo, pre)
1069+ end derived
10651070
10661071 // Tt could happen that we see the symbol with prefix `this` as a member a different class
10671072 // through a self type and that it then has a different info. In this case we have to go
0 commit comments