@@ -573,8 +573,12 @@ object Denotations {
573
573
574
574
final def name (using Context ): Name = symbol.name
575
575
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.
578
582
*/
579
583
def prefix : Type = NoPrefix
580
584
@@ -1044,24 +1048,25 @@ object Denotations {
1044
1048
}
1045
1049
1046
1050
/** 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.
1055
1051
*
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` .
1059
1055
*/
1060
1056
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
1065
1070
1066
1071
// Tt could happen that we see the symbol with prefix `this` as a member a different class
1067
1072
// through a self type and that it then has a different info. In this case we have to go
0 commit comments