Skip to content

Commit

Permalink
Tweak withDenot for overloaded denotations
Browse files Browse the repository at this point in the history
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 scala#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.
  • Loading branch information
odersky committed Feb 13, 2023
1 parent 1a4f3ac commit ea87c08
Showing 1 changed file with 15 additions and 6 deletions.
21 changes: 15 additions & 6 deletions compiler/src/dotty/tools/dotc/core/Types.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2644,8 +2644,12 @@ object Types {
}

/** A reference like this one, but with the given symbol, if it exists */
final def withSym(sym: Symbol)(using Context): ThisType =
if ((designator ne sym) && sym.exists) NamedType(prefix, sym).asInstanceOf[ThisType]
private def withSym(sym: Symbol)(using Context): ThisType =
if designator ne sym then NamedType(prefix, sym).asInstanceOf[ThisType]
else this

private def withName(name: Name)(using Context): ThisType =
if designator ne name then NamedType(prefix, name).asInstanceOf[ThisType]
else this

/** A reference like this one, but with the given denotation, if it exists.
Expand All @@ -2656,6 +2660,8 @@ object Types {
* does not have a currently known denotation.
* 3. The current designator is a name and the new symbolic named type
* has the same info as the current info
* Returns a new named type with a name as designator if the denotation is
* overloaded and the name is different from the current designator.
* Otherwise the current denotation is overwritten with the given one.
*
* Note: (2) and (3) are a "lock in mechanism" where a reference with a name as
Expand All @@ -2669,13 +2675,16 @@ object Types {
*/
final def withDenot(denot: Denotation)(using Context): ThisType =
if denot.exists then
val adapted = withSym(denot.symbol)
val adapted =
if denot.symbol.exists then withSym(denot.symbol)
else if denot.isOverloaded then withName(denot.name)
else this
val result =
if (adapted.eq(this)
if adapted.eq(this)
|| designator.isInstanceOf[Symbol]
|| !adapted.denotationIsCurrent
|| adapted.info.eq(denot.info))
adapted
|| adapted.info.eq(denot.info)
then adapted
else this
val lastDenot = result.lastDenotation
denot match
Expand Down

0 comments on commit ea87c08

Please sign in to comment.