From 972a39b890b1113b4eb097a289f0ef9897cd0816 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. --- compiler/src/dotty/tools/dotc/core/Types.scala | 3 +++ tests/pos/dep-poly-class.scala | 9 +++++++++ 2 files changed, 12 insertions(+) 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/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)