Skip to content

Commit e48aeed

Browse files
bishaboshasmarter
andcommitted
fix #11819: Fix comparisons against thisType
We cannot assume that all equivalent ThisType have the same identity (even with hash-consing, they can be constructed from different but equivalent TypeRefs). Co-authored-by: Guillaume Martres <[email protected]>
1 parent f6edd41 commit e48aeed

File tree

4 files changed

+31
-3
lines changed

4 files changed

+31
-3
lines changed

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

+5-1
Original file line numberDiff line numberDiff line change
@@ -1110,7 +1110,11 @@ object Denotations {
11101110
case sd: SymDenotation => true
11111111
case _ => info eq symbol.info
11121112

1113-
if !owner.membersNeedAsSeenFrom(pre) && ((pre ne owner.thisType) || hasOriginalInfo)
1113+
def ownerIsPrefix = pre match
1114+
case pre: ThisType => pre.sameThis(owner.thisType)
1115+
case _ => false
1116+
1117+
if !owner.membersNeedAsSeenFrom(pre) && (!ownerIsPrefix || hasOriginalInfo)
11141118
|| symbol.is(NonMember)
11151119
then this
11161120
else derived(symbol.info)

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

+4-1
Original file line numberDiff line numberDiff line change
@@ -896,11 +896,14 @@ object SymDenotations {
896896
* accessed via prefix `pre`?
897897
*/
898898
def membersNeedAsSeenFrom(pre: Type)(using Context): Boolean =
899+
def preIsThis = pre match
900+
case pre: ThisType => pre.sameThis(thisType)
901+
case _ => false
899902
!( this.isTerm
900903
|| this.isStaticOwner && !this.seesOpaques
901904
|| ctx.erasedTypes
902905
|| (pre eq NoPrefix)
903-
|| (pre eq thisType)
906+
|| preIsThis
904907
)
905908

906909
/** Is this symbol concrete, or that symbol deferred? */

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

+10-1
Original file line numberDiff line numberDiff line change
@@ -2663,8 +2663,11 @@ object Types {
26632663
* the future. See also NamedType#withDenot. Test case is neg/opaque-self-encoding.scala.
26642664
*/
26652665
private def designatorFor(prefix: Type, name: Name, denot: Denotation)(using Context): Designator = {
2666+
def ownerIsPrefix(owner: Symbol) = prefix match
2667+
case prefix: ThisType => prefix.sameThis(owner.thisType)
2668+
case _ => false
26662669
val sym = denot.symbol
2667-
if (sym.exists && (prefix.eq(NoPrefix) || prefix.ne(sym.owner.thisType)))
2670+
if (sym.exists && (prefix.eq(NoPrefix) || !ownerIsPrefix(sym.owner)))
26682671
sym
26692672
else
26702673
name
@@ -2736,6 +2739,12 @@ object Types {
27362739
case that: ThisType => tref.eq(that.tref)
27372740
case _ => false
27382741
}
2742+
2743+
/** Check that the rhs is a ThisType that refers to the same class.
2744+
*/
2745+
def sameThis(that: Type)(using Context): Boolean = (that eq this) || that.match
2746+
case that: ThisType => this.cls eq that.cls
2747+
case _ => false
27392748
}
27402749

27412750
final class CachedThisType(tref: TypeRef) extends ThisType(tref)

tests/pos/i11819.scala

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package opaquetypes
2+
3+
object `package`: // must be a package object
4+
5+
opaque type Foo = Double // `Foo` must be an opaque type, reference must be primitive
6+
7+
object Bar: // must have a wrapper object
8+
9+
class Baz(val i: Foo): // must be an unqualified reference to `Foo`
10+
def foo(that: Any): Boolean = that match
11+
case that1 @ (_: Baz) => Baz.this.i == that1.i // error: symbol for `==` changed
12+
case _ => true

0 commit comments

Comments
 (0)