From c32e5354a256acf8ff237e19c5b1258235025b41 Mon Sep 17 00:00:00 2001 From: Guillaume Martres Date: Thu, 3 Oct 2024 21:45:02 +0200 Subject: [PATCH] Fix incorrect caching with path-dependent types The added test case used to fail Ycheck:typer with the seemingly identicals: Found: (a: (aa : A{type B = Int}), b: a.B): CCPoly[(aa : A{type B = Int})] Required: (a: (aa : A{type B = Int}), b: a.B): CCPoly[(aa : A{type B = Int})] In fact one of the `aa` is a a TypeVar instantiated to `A {type B = Int }`. The MethodType comparison failed the signature check because the `a.B` where `a` is backed by a type variable had a stale signature cached. Fixed by changing `isProvisional` to traverse ParamRefs. --- .../src/dotty/tools/dotc/core/Types.scala | 3 +++ tests/neg/i16842.check | 20 +++++++++++++++---- tests/neg/i16842.scala | 2 +- tests/pos/dep-poly-class.scala | 9 +++++++++ 4 files changed, 29 insertions(+), 5 deletions(-) create mode 100644 tests/pos/dep-poly-class.scala diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index aba8c3bb31fd..cf73bda0d131 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -144,6 +144,9 @@ object Types extends TypeUtils { !t.isPermanentlyInstantiated || test(t.permanentInst, theAcc) case t: LazyRef => !t.completed || test(t.ref, theAcc) + case t: ParamRef => + (t: Type).mightBeProvisional = false // break cycles + test(t.underlying, theAcc) case _ => (if theAcc != null then theAcc else ProAcc()).foldOver(false, t) end if diff --git a/tests/neg/i16842.check b/tests/neg/i16842.check index 936b08f95dbb..8cad4bc7656f 100644 --- a/tests/neg/i16842.check +++ b/tests/neg/i16842.check @@ -1,4 +1,16 @@ --- Error: tests/neg/i16842.scala:24:7 ---------------------------------------------------------------------------------- -24 | Liter(SemanticArray[SemanticInt.type], x) // error - | ^ - | invalid new prefix (dim: Int): SemanticArray[SemanticInt.type] cannot replace ty.type in type ty.T +-- [E007] Type Mismatch Error: tests/neg/i16842.scala:24:8 ------------------------------------------------------------- +24 | Liter(SemanticArray[SemanticInt.type], x) // error // error + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | Found: Int => SemanticArray[SemanticInt.type] + | Required: SemanticArray[SemanticType] + | + | longer explanation available when compiling with `-explain` +-- [E007] Type Mismatch Error: tests/neg/i16842.scala:24:41 ------------------------------------------------------------ +24 | Liter(SemanticArray[SemanticInt.type], x) // error // error + | ^ + | Found: (x : List[Expr2[SemanticInt.type]]) + | Required: ty.T + | Note that implicit conversions were not tried because the result of an implicit conversion + | must be more specific than ty.T + | + | longer explanation available when compiling with `-explain` diff --git a/tests/neg/i16842.scala b/tests/neg/i16842.scala index e9935b46c01d..1e7e5cc14339 100644 --- a/tests/neg/i16842.scala +++ b/tests/neg/i16842.scala @@ -21,5 +21,5 @@ def typecheckArrayLiter( a: ArrayLiter ): Liter[SemanticArray[SemanticType]] = { val x: List[Expr2[SemanticInt.type]] = List() - Liter(SemanticArray[SemanticInt.type], x) // error + Liter(SemanticArray[SemanticInt.type], x) // error // error } diff --git a/tests/pos/dep-poly-class.scala b/tests/pos/dep-poly-class.scala new file mode 100644 index 000000000000..3615b699ff3a --- /dev/null +++ b/tests/pos/dep-poly-class.scala @@ -0,0 +1,9 @@ +trait A: + type B + +class CCPoly[T <: A](a: T, b: a.B) + +object Test: + def test(): Unit = + val aa: A { type B = Int } = new A { type B = Int } + val x: CCPoly[aa.type] = CCPoly(aa, 1)