Skip to content

Commit 16324c1

Browse files
committed
Tweak withDenot for overloaded denotations
When creating a NamedType with a given overloaded denotation, make sure that the type has a Name as designator. This prevents accidentally overwriting a more precise symbolic TermRef that refers to one specific alternative of the denotation. This might be enough to fix #16884. It would be great if we could maintain the general invariant that NamedTypes with overloaded denotations always have names as designators. But that looks very hard when we take into account that we need to update named types to new runs. A type might have a single denotation in one round and an overloaded one in the next.
1 parent 3d251d6 commit 16324c1

File tree

1 file changed

+15
-6
lines changed

1 file changed

+15
-6
lines changed

compiler/src/dotty/tools/dotc/core/Types.scala

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2644,8 +2644,12 @@ object Types {
26442644
}
26452645

26462646
/** A reference like this one, but with the given symbol, if it exists */
2647-
final def withSym(sym: Symbol)(using Context): ThisType =
2648-
if ((designator ne sym) && sym.exists) NamedType(prefix, sym).asInstanceOf[ThisType]
2647+
private def withSym(sym: Symbol)(using Context): ThisType =
2648+
if designator ne sym then NamedType(prefix, sym).asInstanceOf[ThisType]
2649+
else this
2650+
2651+
private def withName(name: Name)(using Context): ThisType =
2652+
if designator ne name then NamedType(prefix, name).asInstanceOf[ThisType]
26492653
else this
26502654

26512655
/** A reference like this one, but with the given denotation, if it exists.
@@ -2656,6 +2660,8 @@ object Types {
26562660
* does not have a currently known denotation.
26572661
* 3. The current designator is a name and the new symbolic named type
26582662
* has the same info as the current info
2663+
* Returns a new named type with a name as designator if the denotation is
2664+
* overloaded and the name is different from the current designator.
26592665
* Otherwise the current denotation is overwritten with the given one.
26602666
*
26612667
* Note: (2) and (3) are a "lock in mechanism" where a reference with a name as
@@ -2669,13 +2675,16 @@ object Types {
26692675
*/
26702676
final def withDenot(denot: Denotation)(using Context): ThisType =
26712677
if denot.exists then
2672-
val adapted = withSym(denot.symbol)
2678+
val adapted =
2679+
if denot.symbol.exists then withSym(denot.symbol)
2680+
else if denot.isOverloaded then withName(denot.name)
2681+
else this
26732682
val result =
2674-
if (adapted.eq(this)
2683+
if adapted.eq(this)
26752684
|| designator.isInstanceOf[Symbol]
26762685
|| !adapted.denotationIsCurrent
2677-
|| adapted.info.eq(denot.info))
2678-
adapted
2686+
|| adapted.info.eq(denot.info)
2687+
then adapted
26792688
else this
26802689
val lastDenot = result.lastDenotation
26812690
denot match

0 commit comments

Comments
 (0)