Skip to content

Commit f51aaa8

Browse files
committed
SI-8071 Allow unification for prefixes of form ThisType(refinement)
In the enclosed test, we ended up relating the following types: tp1 = AnyRef{type Mem <: AnyRef{def x: Int}; type Memory#3 = this.Mem}" // #1 tp2 = AnyRef{type Mem <: AnyRef{def x: Int @ann}; type Memory#4 = this.Mem}" // #2 The first was the result of `Use.field`, in which the `asSeenFrom` had stripped the annotation. (`AsSeenFromMap` extends `KeepOnlyTypeConstraints`). The second type was the declared return type of the accessor method. Usually, `=:=` and `<:<` are annotation agnostic, and unless a plugin says otherwise, just compare the underlying types. But, when refinements are thrown into the mix, one has to wade through `specializesSym`. On the way, we get to: tp1 = Use.<refinement#1>.type tp2 = Use.<refinement#2>.type sym1 = type Memory#3 sym2 = type Memory#4 tp2.memberType(sym2).substThis(tp2.typeSymbol, tp1) =:= tp1.memberType(sym1) And finally down to business in `equalSymsAndPrefixes`. Here, we allow loose matching, based on symbol names, if the prefixes are =:= and represent a refined type (or a singleton type or type variable over a refined type.) But none of these cases covered what we encounter here: a this type over a refinement class. This commit adds that case to `isEligibleForPrefixUnification`.
1 parent b345b42 commit f51aaa8

File tree

4 files changed

+39
-0
lines changed

4 files changed

+39
-0
lines changed

src/reflect/scala/reflect/internal/Types.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3977,6 +3977,7 @@ trait Types
39773977
case SingleType(pre, sym) => !(sym hasFlag PACKAGE) && isEligibleForPrefixUnification(pre)
39783978
case tv@TypeVar(_, constr) => !tv.instValid || isEligibleForPrefixUnification(constr.inst)
39793979
case RefinedType(_, _) => true
3980+
case ThisType(sym) => sym.isRefinementClass // See SI-8071
39803981
case _ => false
39813982
}
39823983

test/files/pos/t8071.scala

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
class ann extends annotation.StaticAnnotation
2+
3+
object Use {
4+
def ??? = sys.error("!!!")
5+
val field = new AnyRef { // <---- error reported here
6+
class Mem { def x: (Int @ann) = ??? }
7+
type Memory = Mem
8+
}
9+
}
10+
11+
/**
12+
error: type mismatch;
13+
found : AnyRef{type Mem(in <refinement of AnyRef>)(in <refinement of AnyRef>)(in <refinement of AnyRef>)(in <refinement of AnyRef>) <: AnyRef{def x: Int}; type Memory = this.Mem(in <refinement of AnyRef>)(in <refinement of AnyRef>)(in <refinement of AnyRef>)(in <refinement of AnyRef>)}
14+
required: AnyRef{type Mem(in <refinement of AnyRef>)(in <refinement of AnyRef>)(in <refinement of AnyRef>)(in <refinement of AnyRef>) <: AnyRef{def x: Int @ann}; type Memory = this.Mem(in <refinement of AnyRef>)(in <refinement of AnyRef>)(in <refinement of AnyRef>)(in <refinement of AnyRef>)}
15+
*/

test/files/pos/t8071b.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
class ann extends annotation.StaticAnnotation
2+
3+
class Use {
4+
def foo: (Int @ann) = ???
5+
def bar: (Int @ann) = (new Use{}).foo
6+
}

test/files/pos/t8071c.scala

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
trait DataSetup {
2+
type Memory <: AnyRef with Serializable
3+
def run(): Memory
4+
}
5+
6+
object Use {
7+
8+
val dataSetup = new DataSetup { // <---- error reported here
9+
case class Mem(ids: List[Int])
10+
type Memory = Mem
11+
def run(): Memory = {
12+
val ids = List(1,2,3)
13+
Mem(ids)
14+
}
15+
}
16+
17+
}

0 commit comments

Comments
 (0)