From c4a18969d54d1fd3256efe0407ff4f74727e0446 Mon Sep 17 00:00:00 2001 From: Wojciech Mazur Date: Mon, 24 Feb 2025 14:47:16 +0100 Subject: [PATCH 1/2] Revert "Drop phase.isTyper use in isLegalPrefix/asf" This reverts commit 26ecda540b93fbe1fc7be030559a78dd2db364f2. --- .../dotty/tools/dotc/core/TypeComparer.scala | 5 +- .../src/dotty/tools/dotc/core/TypeOps.scala | 2 +- .../src/dotty/tools/dotc/core/Types.scala | 29 ++++---- .../dotty/tools/dotc/transform/Recheck.scala | 4 +- .../test/dotc/pos-test-pickling.blacklist | 1 - tests/neg/6314-6.check | 4 +- tests/neg/i6225.scala | 2 +- tests/pos/i17222.2.scala | 30 -------- tests/pos/i17222.3.scala | 39 ---------- tests/pos/i17222.4.scala | 71 ------------------- tests/pos/i17222.5.scala | 26 ------- tests/pos/i17222.8.scala | 18 ----- tests/pos/i17222.scala | 33 --------- 13 files changed, 24 insertions(+), 240 deletions(-) delete mode 100644 tests/pos/i17222.2.scala delete mode 100644 tests/pos/i17222.3.scala delete mode 100644 tests/pos/i17222.4.scala delete mode 100644 tests/pos/i17222.5.scala delete mode 100644 tests/pos/i17222.8.scala delete mode 100644 tests/pos/i17222.scala diff --git a/compiler/src/dotty/tools/dotc/core/TypeComparer.scala b/compiler/src/dotty/tools/dotc/core/TypeComparer.scala index bbe157d4a29b..ca3df65625a8 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeComparer.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeComparer.scala @@ -369,8 +369,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling } compareWild case tp2: LazyRef => - isBottom(tp1) - || !tp2.evaluating && recur(tp1, tp2.ref) + isBottom(tp1) || !tp2.evaluating && recur(tp1, tp2.ref) case CapturingType(_, _) => secondTry case tp2: AnnotatedType if !tp2.isRefining => @@ -490,7 +489,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling // If `tp1` is in train of being evaluated, don't force it // because that would cause an assertionError. Return false instead. // See i859.scala for an example where we hit this case. - tp2.isAny + tp2.isRef(AnyClass, skipRefined = false) || !tp1.evaluating && recur(tp1.ref, tp2) case AndType(tp11, tp12) => if tp11.stripTypeVar eq tp12.stripTypeVar then recur(tp11, tp2) diff --git a/compiler/src/dotty/tools/dotc/core/TypeOps.scala b/compiler/src/dotty/tools/dotc/core/TypeOps.scala index a7f41a71d7ce..e3168ca5a27d 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeOps.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeOps.scala @@ -124,7 +124,7 @@ object TypeOps: } def isLegalPrefix(pre: Type)(using Context): Boolean = - pre.isStable + pre.isStable || !ctx.phase.isTyper /** Implementation of Types#simplified */ def simplify(tp: Type, theMap: SimplifyMap | Null)(using Context): Type = { diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index c5937074f4bc..f77f268d6ee6 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -98,8 +98,12 @@ object Types extends TypeUtils { // ----- Tests ----------------------------------------------------- // // debug only: a unique identifier for a type -// val uniqId = { nextId = nextId + 1; nextId } -// if uniqId == 19555 then trace.dumpStack() +// val uniqId = { +// nextId = nextId + 1 +// if (nextId == 19555) +// println("foo") +// nextId +// } /** A cache indicating whether the type was still provisional, last time we checked */ @sharable private var mightBeProvisional = true @@ -5578,25 +5582,24 @@ object Types extends TypeUtils { } def & (that: TypeBounds)(using Context): TypeBounds = - val lo1 = this.lo.stripLazyRef - val lo2 = that.lo.stripLazyRef - val hi1 = this.hi.stripLazyRef - val hi2 = that.hi.stripLazyRef - // This will try to preserve the FromJavaObjects type in upper bounds. // For example, (? <: FromJavaObjects | Null) & (? <: Any), // we want to get (? <: FromJavaObjects | Null) intead of (? <: Any), // because we may check the result <:< (? <: Object | Null) later. - if hi1.containsFromJavaObject && (hi1 frozen_<:< hi2) && (lo2 frozen_<:< lo1) then + if this.hi.containsFromJavaObject + && (this.hi frozen_<:< that.hi) + && (that.lo frozen_<:< this.lo) then // FromJavaObject in tp1.hi guarantees tp2.hi <:< tp1.hi // prefer tp1 if FromJavaObject is in its hi this - else if hi2.containsFromJavaObject && (hi2 frozen_<:< hi1) && (lo1 frozen_<:< lo2) then + else if that.hi.containsFromJavaObject + && (that.hi frozen_<:< this.hi) + && (this.lo frozen_<:< that.lo) then // Similarly, prefer tp2 if FromJavaObject is in its hi that - else if (lo1 frozen_<:< lo2) && (hi2 frozen_<:< hi1) then that - else if (lo2 frozen_<:< lo1) && (hi1 frozen_<:< hi2) then this - else TypeBounds(lo1 | lo2, hi1 & hi2) + else if (this.lo frozen_<:< that.lo) && (that.hi frozen_<:< this.hi) then that + else if (that.lo frozen_<:< this.lo) && (this.hi frozen_<:< that.hi) then this + else TypeBounds(this.lo | that.lo, this.hi & that.hi) def | (that: TypeBounds)(using Context): TypeBounds = if ((this.lo frozen_<:< that.lo) && (that.hi frozen_<:< this.hi)) this @@ -5605,7 +5608,7 @@ object Types extends TypeUtils { override def & (that: Type)(using Context): Type = that match { case that: TypeBounds => this & that - case _ => super.&(that) + case _ => super.& (that) } override def | (that: Type)(using Context): Type = that match { diff --git a/compiler/src/dotty/tools/dotc/transform/Recheck.scala b/compiler/src/dotty/tools/dotc/transform/Recheck.scala index 172ae337d6e6..9631136a1c4e 100644 --- a/compiler/src/dotty/tools/dotc/transform/Recheck.scala +++ b/compiler/src/dotty/tools/dotc/transform/Recheck.scala @@ -219,10 +219,10 @@ abstract class Recheck extends Phase, SymTransformer: sharpen: Denotation => Denotation)(using Context): Type = if name.is(OuterSelectName) then tree.tpe else - val pre = ta.maybeSkolemizePrefix(qualType, name) + //val pre = ta.maybeSkolemizePrefix(qualType, name) val mbr = sharpen( - qualType.findMember(name, pre, + qualType.findMember(name, qualType, excluded = if tree.symbol.is(Private) then EmptyFlags else Private )).suchThat(tree.symbol == _) val newType = tree.tpe match diff --git a/compiler/test/dotc/pos-test-pickling.blacklist b/compiler/test/dotc/pos-test-pickling.blacklist index 23c79affada0..07c157793f5d 100644 --- a/compiler/test/dotc/pos-test-pickling.blacklist +++ b/compiler/test/dotc/pos-test-pickling.blacklist @@ -24,7 +24,6 @@ t5031_2.scala i16997.scala i7414.scala i17588.scala -i8300.scala i9804.scala i13433.scala i16649-irrefutable.scala diff --git a/tests/neg/6314-6.check b/tests/neg/6314-6.check index df988f1db9dd..7d6bd182173d 100644 --- a/tests/neg/6314-6.check +++ b/tests/neg/6314-6.check @@ -4,7 +4,7 @@ |object creation impossible, since def apply(fa: String): Int in trait XX in object Test3 is not defined |(Note that | parameter String in def apply(fa: String): Int in trait XX in object Test3 does not match - | parameter Test3.Bar[X & (X & Y)] in def apply(fa: Test3.Bar[X & YY.this.Foo]): Test3.Bar[Y & YY.this.Foo] in trait YY in object Test3 + | parameter Test3.Bar[X & Object with Test3.YY {...}#Foo] in def apply(fa: Test3.Bar[X & YY.this.Foo]): Test3.Bar[Y & YY.this.Foo] in trait YY in object Test3 | ) -- Error: tests/neg/6314-6.scala:52:3 ---------------------------------------------------------------------------------- 52 | (new YY {}).boom // error: object creation impossible @@ -12,5 +12,5 @@ |object creation impossible, since def apply(fa: String): Int in trait XX in object Test4 is not defined |(Note that | parameter String in def apply(fa: String): Int in trait XX in object Test4 does not match - | parameter Test4.Bar[X & (X & Y)] in def apply(fa: Test4.Bar[X & YY.this.FooAlias]): Test4.Bar[Y & YY.this.FooAlias] in trait YY in object Test4 + | parameter Test4.Bar[X & Object with Test4.YY {...}#FooAlias] in def apply(fa: Test4.Bar[X & YY.this.FooAlias]): Test4.Bar[Y & YY.this.FooAlias] in trait YY in object Test4 | ) diff --git a/tests/neg/i6225.scala b/tests/neg/i6225.scala index bb936c9a79b1..148a484fd0f1 100644 --- a/tests/neg/i6225.scala +++ b/tests/neg/i6225.scala @@ -1,4 +1,4 @@ -object O1 { // error: cannot be instantiated +object O1 { type A[X] = X opaque type T = A // error: opaque type alias must be fully applied } diff --git a/tests/pos/i17222.2.scala b/tests/pos/i17222.2.scala deleted file mode 100644 index 34db494750c4..000000000000 --- a/tests/pos/i17222.2.scala +++ /dev/null @@ -1,30 +0,0 @@ -import scala.compiletime.* - -trait Reader[-In, Out] - -trait A: - type T - type F[X] - type Q = F[T] - -object Reader: - - given [X]: Reader[A { type Q = X }, X] with {} - -object Test: - - trait B[X] extends A: - type T = X - - trait C extends A: - type F[X] = X - - trait D[X] extends B[X] with C - - val d = new D[Int] {} - val bc = new B[Int] with C - - summonAll[(Reader[d.type, Int], Reader[d.type, Int])] // works - summonAll[(Reader[bc.type, Int], Reader[bc.type, Int])] // error - summonInline[Reader[d.type, Int]] // works - summonInline[Reader[bc.type, Int]] // works?? diff --git a/tests/pos/i17222.3.scala b/tests/pos/i17222.3.scala deleted file mode 100644 index 7ca85f65278f..000000000000 --- a/tests/pos/i17222.3.scala +++ /dev/null @@ -1,39 +0,0 @@ -import scala.compiletime.* - -trait Reader[-In, Out] - -trait A: - type T - type F[X] - type Q = F[T] - -object Reader: - - given [X]: Reader[A { type Q = X }, X] with {} - -object Test: - - trait B[X] extends A: - type T = X - - trait C extends A: - type F[X] = X - - trait D[X] extends B[X] with C - - val d = new D[Int] {} - val bc = new B[Int] with C - - case class Box[T](value: T) - - /** compiletime.summonAll, but with one case */ - inline def summonOne[T <: Box[?]]: T = - val res = - inline erasedValue[T] match - case _: Box[t] => summonInline[t] - end match - Box(res).asInstanceOf[T] - end summonOne - - summonOne[Box[Reader[d.type, Int]]] // works - summonOne[Box[Reader[bc.type, Int]]] // errors diff --git a/tests/pos/i17222.4.scala b/tests/pos/i17222.4.scala deleted file mode 100644 index 209425d47915..000000000000 --- a/tests/pos/i17222.4.scala +++ /dev/null @@ -1,71 +0,0 @@ -import scala.compiletime.* - -trait Reader[-In, Out] - -trait A: - type T - type F[X] - type Q = F[T] - -given [X]: Reader[A { type Q = X }, X] with {} - -case class Box[T](x: T) - -/** compiletime.summonAll, but with one case */ -inline def summonOne[T]: T = - val res = - inline erasedValue[T] match - case _: Box[t] => summonInline[t] - end match - Box(res).asInstanceOf[T] -end summonOne - - -@main def main = - - - trait B[X] extends A: - type T = X - - trait C extends A: - type F[X] = X - - - val bc = new B[Int] with C - - summonOne[Box[Reader[bc.type, Int]]] // errors - - - val bc2: A { type Q = Int } = new B[Int] with C - - summonOne[Box[Reader[bc2.type, Int]]] // works - - - object BC extends B[Int] with C - - summonOne[Box[Reader[BC.type, Int]]] // works - - - val a = new A: - type T = Int - type F[X] = X - - summonOne[Box[Reader[a.type, Int]]] // works - - - val b = new B[Int]: - type F[X] = X - - summonOne[Box[Reader[b.type, Int]]] // works - - - val ac = new A with C: - type T = Int - - summonOne[Box[Reader[ac.type, Int]]] // works - - - trait D[X] extends B[X] with C - val d = new D[Int] {} - - summonOne[Box[Reader[d.type, Int]]] // works diff --git a/tests/pos/i17222.5.scala b/tests/pos/i17222.5.scala deleted file mode 100644 index dc608e94235c..000000000000 --- a/tests/pos/i17222.5.scala +++ /dev/null @@ -1,26 +0,0 @@ -import scala.compiletime.* - -trait Reader[-In, Out] - -trait A: - type T - type F[X] - type Q = F[T] - -given [X]: Reader[A { type Q = X }, X] with {} - -case class Box[T](x: T) - -inline def summonOne[T]: T = - summonInline[T] -end summonOne - -@main def main = - trait B[X] extends A: - type T = X - trait C extends A: - type F[X] = X - - val bc = new B[Int] with C - summonInline[Reader[bc.type, Int]] // (I) Works - summonOne[Reader[bc.type, Int]] // (II) Errors diff --git a/tests/pos/i17222.8.scala b/tests/pos/i17222.8.scala deleted file mode 100644 index a415a78e0703..000000000000 --- a/tests/pos/i17222.8.scala +++ /dev/null @@ -1,18 +0,0 @@ -import scala.compiletime.* - -trait A: - type F - type Q = F - -trait Reader[-In, Out] -object Reader: - given [X]: Reader[A { type Q = X }, X] with {} - -class Test: - //type BC = A { type F = Int } & A // ok - type BC = A & A { type F = Int } // fail, also ok when manually de-aliased - - inline def summonOne: Unit = summonInline[Reader[BC, Int]] - - def t1(): Unit = summonInline[Reader[BC, Int]] // ok - def t2(): Unit = summonOne // error diff --git a/tests/pos/i17222.scala b/tests/pos/i17222.scala deleted file mode 100644 index 2af9fc2861a8..000000000000 --- a/tests/pos/i17222.scala +++ /dev/null @@ -1,33 +0,0 @@ -import scala.deriving.Mirror -import scala.compiletime.* - -trait Reader[-In, Out] - -trait A: - type T - type F[X] - type Q = F[T] - -object Reader: - - given [X]: Reader[A { type Q = X }, X] with {} - - type Map2[Tup1 <: Tuple, Tup2 <: Tuple, F[_, _]] <: Tuple = (Tup1, Tup2) match - case (h1 *: t1, h2 *: t2) => F[h1, h2] *: Map2[t1, t2, F] - case (EmptyTuple, EmptyTuple) => EmptyTuple - - inline given productReader[In <: Product, Out <: Product](using mi: Mirror.ProductOf[In])(using mo: Mirror.ProductOf[Out]): Reader[In, Out] = - summonAll[Map2[mi.MirroredElemTypes, mo.MirroredElemTypes, Reader]] - ??? - -object Test: - - trait B[X] extends A: - type T = X - - trait C extends A: - type F[X] = X - - val bc = new B[Int] with C - - summon[Reader[(bc.type, bc.type), (Int, Int)]] // fails From e25316c24ad01bc5629973be13ed314deb4878dd Mon Sep 17 00:00:00 2001 From: Wojciech Mazur Date: Mon, 24 Feb 2025 14:55:38 +0100 Subject: [PATCH 2/2] Adjust captures/lazylist test --- tests/neg-custom-args/captures/lazylist.check | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/neg-custom-args/captures/lazylist.check b/tests/neg-custom-args/captures/lazylist.check index 65fed0c4ec7e..bc95a445f3f4 100644 --- a/tests/neg-custom-args/captures/lazylist.check +++ b/tests/neg-custom-args/captures/lazylist.check @@ -29,7 +29,7 @@ -- [E007] Type Mismatch Error: tests/neg-custom-args/captures/lazylist.scala:41:42 ------------------------------------- 41 | val ref4c: LazyList[Int]^{cap1, ref3} = ref4 // error | ^^^^ - | Found: (ref4 : lazylists.LazyList[Int]^{cap3, ref1, ref2}) + | Found: (ref4 : lazylists.LazyList[Int]^{cap3, cap2, ref1, cap1}) | Required: lazylists.LazyList[Int]^{cap1, ref3} | | longer explanation available when compiling with `-explain`