From ff90012510dd986381871c425bd9341e9216d3c8 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Thu, 26 Oct 2023 11:18:01 +0100 Subject: [PATCH 1/2] Identify structural trees on Match Type qualifiers Without this change, selecting `v1` on a type `Ifce[(true : Boolean)]#RT` which widens to a MatchType wouldn't be identified as a structural tree, which later breaks Erasure. --- compiler/src/dotty/tools/dotc/ast/TreeInfo.scala | 2 ++ tests/neg/i17192.5.scala | 12 ++++++++++++ tests/pos/i17192.scala | 11 +++++++++++ 3 files changed, 25 insertions(+) create mode 100644 tests/neg/i17192.5.scala create mode 100644 tests/pos/i17192.scala diff --git a/compiler/src/dotty/tools/dotc/ast/TreeInfo.scala b/compiler/src/dotty/tools/dotc/ast/TreeInfo.scala index ac7fec4b02df..23dcfe392c27 100644 --- a/compiler/src/dotty/tools/dotc/ast/TreeInfo.scala +++ b/compiler/src/dotty/tools/dotc/ast/TreeInfo.scala @@ -992,6 +992,8 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] => def hasRefinement(qualtpe: Type): Boolean = qualtpe.dealias match case defn.PolyFunctionOf(_) => false + case tp: MatchType => + hasRefinement(tp.tryNormalize) case RefinedType(parent, rname, rinfo) => rname == tree.name || hasRefinement(parent) case tp: TypeProxy => diff --git a/tests/neg/i17192.5.scala b/tests/neg/i17192.5.scala new file mode 100644 index 000000000000..2837af36b573 --- /dev/null +++ b/tests/neg/i17192.5.scala @@ -0,0 +1,12 @@ +class Ifce[BT <: Boolean]: + type RT = BT match + case true => this.type { val v1: Int } + def cast: RT = this.asInstanceOf[RT] + +class Test: + def t1: Unit = + val full1 = new Ifce[true]().cast + val v1 = full1.v1 // error +// ^^^^^ +// Found: (full1 : Ifce[(true : Boolean)]#RT) +// Required: Selectable | Dynamic diff --git a/tests/pos/i17192.scala b/tests/pos/i17192.scala new file mode 100644 index 000000000000..129da358b3ba --- /dev/null +++ b/tests/pos/i17192.scala @@ -0,0 +1,11 @@ +class Ifce[BT <: Boolean] extends Selectable: + type RT = BT match + case true => this.type { val v1: Int } + case false => this.type + def cast : RT = this.asInstanceOf[RT] + def selectDynamic(key: String): Any = ??? + +class Test: + def t1: Unit = + val full = (new Ifce[true]).cast + val v1 = full.v1 From cc69d9067fe451c51edf17cb2caf551ebb55c876 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Fri, 27 Oct 2023 13:33:01 +0100 Subject: [PATCH 2/2] Align pos and neg test pair MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Sébastien Doeraene --- tests/neg/i17192.5.scala | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/neg/i17192.5.scala b/tests/neg/i17192.5.scala index 2837af36b573..a23c8b589a1a 100644 --- a/tests/neg/i17192.5.scala +++ b/tests/neg/i17192.5.scala @@ -1,6 +1,7 @@ class Ifce[BT <: Boolean]: type RT = BT match - case true => this.type { val v1: Int } + case true => this.type { val v1: Int } + case false => this.type def cast: RT = this.asInstanceOf[RT] class Test: