From ccde55e6271ad40715a46a42d228b669ea8e24d8 Mon Sep 17 00:00:00 2001 From: Hamza Remmal Date: Wed, 24 Sep 2025 17:32:32 +0200 Subject: [PATCH 1/2] Revert "fix: do not transform `Ident` to `This` in PostTyper anymore" --- .../src/dotty/tools/dotc/transform/PostTyper.scala | 6 +++++- tests/run/i23875.check | 3 --- tests/run/i23875.scala | 11 ----------- 3 files changed, 5 insertions(+), 15 deletions(-) delete mode 100644 tests/run/i23875.check delete mode 100644 tests/run/i23875.scala diff --git a/compiler/src/dotty/tools/dotc/transform/PostTyper.scala b/compiler/src/dotty/tools/dotc/transform/PostTyper.scala index d1246aacf7d5..9f79c063dc03 100644 --- a/compiler/src/dotty/tools/dotc/transform/PostTyper.scala +++ b/compiler/src/dotty/tools/dotc/transform/PostTyper.scala @@ -391,7 +391,11 @@ class PostTyper extends MacroTransform with InfoTransformer { thisPhase => checkNotPackage(tree) else registerNeedsInlining(tree) - checkUsableAsValue(tree) + val tree1 = checkUsableAsValue(tree) + tree1.tpe match { + case tpe: ThisType => This(tpe.cls).withSpan(tree.span) + case _ => tree1 + } case tree @ Select(qual, name) => registerNeedsInlining(tree) if name.isTypeName then diff --git a/tests/run/i23875.check b/tests/run/i23875.check deleted file mode 100644 index 36bc6136b8bf..000000000000 --- a/tests/run/i23875.check +++ /dev/null @@ -1,3 +0,0 @@ -true -false -false diff --git a/tests/run/i23875.scala b/tests/run/i23875.scala deleted file mode 100644 index 6993fb39f50b..000000000000 --- a/tests/run/i23875.scala +++ /dev/null @@ -1,11 +0,0 @@ -object Foo { - override def equals(that : Any) = that match { - case _: this.type => true - case _ => false - } -} - -@main def Test = - println(Foo.equals(Foo)) - println(Foo.equals(new AnyRef {})) - println(Foo.equals(0)) From 01eab3b9be7065cfc1fc241223b9b6ceea8dc9e6 Mon Sep 17 00:00:00 2001 From: Hamza Remmal Date: Wed, 24 Sep 2025 18:00:37 +0200 Subject: [PATCH 2/2] fix: make the pattern matcher understand this types --- .../dotty/tools/dotc/transform/PatternMatcher.scala | 8 +++++++- tests/run/i23875.check | 3 +++ tests/run/i23875.scala | 11 +++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 tests/run/i23875.check create mode 100644 tests/run/i23875.scala diff --git a/compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala b/compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala index 825b7dc337b4..558cbd72dd43 100644 --- a/compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala +++ b/compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala @@ -482,7 +482,13 @@ object PatternMatcher { onSuccess ) } - case WildcardPattern() => + // When match against a `this.type` (say case a: this.type => ???), + // the typer will transform the pattern to a `Bind(..., Typed(Ident(a), ThisType(...)))`, + // then post typer will change all the `Ident` with a `ThisType` to a `This`. + // Therefore, after pattern matching, we will have the following tree `Bind(..., Typed(This(...), ThisType(...)))`. + // We handle now here the case were the pattern was transformed to a `This`, relying on the fact that the logic for + // `Typed` above will create the correct type test. + case WildcardPattern() | This(_) => onSuccess case SeqLiteral(pats, _) => matchElemsPlan(scrutinee, pats, exact = true, onSuccess) diff --git a/tests/run/i23875.check b/tests/run/i23875.check new file mode 100644 index 000000000000..36bc6136b8bf --- /dev/null +++ b/tests/run/i23875.check @@ -0,0 +1,3 @@ +true +false +false diff --git a/tests/run/i23875.scala b/tests/run/i23875.scala new file mode 100644 index 000000000000..6993fb39f50b --- /dev/null +++ b/tests/run/i23875.scala @@ -0,0 +1,11 @@ +object Foo { + override def equals(that : Any) = that match { + case _: this.type => true + case _ => false + } +} + +@main def Test = + println(Foo.equals(Foo)) + println(Foo.equals(new AnyRef {})) + println(Foo.equals(0))