Skip to content

Commit 2e2c520

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 f208994 commit 2e2c520

File tree

4 files changed

+29
-3
lines changed

4 files changed

+29
-3
lines changed

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

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

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

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

+4-1
Original file line numberDiff line numberDiff line change
@@ -890,11 +890,14 @@ object SymDenotations {
890890
* accessed via prefix `pre`?
891891
*/
892892
def membersNeedAsSeenFrom(pre: Type)(using Context): Boolean =
893+
def preIsThis = pre match
894+
case pre: ThisType => pre.sameThis(thisType)
895+
case _ => false
893896
!( this.isTerm
894897
|| this.isStaticOwner && !this.seesOpaques
895898
|| ctx.erasedTypes
896899
|| (pre eq NoPrefix)
897-
|| (pre eq thisType)
900+
|| preIsThis
898901
)
899902

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

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

+8-1
Original file line numberDiff line numberDiff line change
@@ -2636,8 +2636,11 @@ object Types {
26362636
* the future. See also NamedType#withDenot. Test case is neg/opaque-self-encoding.scala.
26372637
*/
26382638
private def designatorFor(prefix: Type, name: Name, denot: Denotation)(using Context): Designator = {
2639+
def ownerIsPrefix(owner: Symbol) = prefix match
2640+
case prefix: ThisType => prefix.sameThis(owner.thisType)
2641+
case _ => false
26392642
val sym = denot.symbol
2640-
if (sym.exists && (prefix.eq(NoPrefix) || prefix.ne(sym.owner.thisType)))
2643+
if (sym.exists && (prefix.eq(NoPrefix) || !ownerIsPrefix(sym.owner)))
26412644
sym
26422645
else
26432646
name
@@ -2709,6 +2712,10 @@ object Types {
27092712
case that: ThisType => tref.eq(that.tref)
27102713
case _ => false
27112714
}
2715+
2716+
def sameThis(that: Type)(using Context): Boolean = (that eq this) || that.match
2717+
case that: ThisType => this =:= that
2718+
case _ => false
27122719
}
27132720

27142721
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)