Skip to content

Commit 0bb6e78

Browse files
committed
Re-establish missing symbol from previous phase (in one specific case)
Fixes #15158
1 parent b61036b commit 0bb6e78

File tree

2 files changed

+56
-1
lines changed

2 files changed

+56
-1
lines changed

compiler/src/dotty/tools/dotc/transform/Erasure.scala

+13-1
Original file line numberDiff line numberDiff line change
@@ -695,7 +695,19 @@ object Erasure {
695695
return tree.asInstanceOf[Tree] // we are re-typing a primitive array op
696696

697697
val owner = mapOwner(origSym)
698-
val sym = if (owner eq origSym.maybeOwner) origSym else owner.info.decl(tree.name).symbol
698+
var sym = if (owner eq origSym.maybeOwner) origSym else owner.info.decl(tree.name).symbol
699+
if !sym.exists then
700+
// We fail the sym.exists test for pos/i15158.scala, where we pass an infinitely
701+
// recurring match type to an overloaded constructor. An equivalent test
702+
// with regular apply methods succeeds. It's at present unclear whether
703+
// - the program should be rejected, or
704+
// - there is another fix.
705+
// Therefore, we apply the fix to use the pre-erasure symbol, but only
706+
// for constructors, in order not to mask other possible bugs that would
707+
// trigger the assert(sym.exists, ...) below.
708+
val prevSym = tree.symbol(using preErasureCtx)
709+
if prevSym.isConstructor then sym = prevSym
710+
699711
assert(sym.exists, i"no owner from $owner/${origSym.showLocated} in $tree")
700712

701713
if owner == defn.ObjectClass then checkValue(qual1)

tests/pos/i15158.scala

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
class Opt[T]
2+
3+
class Buf[A](elts: Any, sz: Int):
4+
def this(n: Int) = this(???, n)
5+
6+
object Buf:
7+
def apply[A](elts: Any, sz: Int): Buf[A] = new Buf[A](elts, sz)
8+
def apply[A](n: Int): Buf[A] = apply[A](???, n)
9+
10+
inline def foo(testFun: Any): Unit = {}
11+
12+
val x = foo {
13+
type Rec[A] = A match
14+
case String => Opt[Rec[String]]
15+
16+
val arr = new Buf[Rec[String]](8)
17+
val arr2 = Buf[Rec[String]](8)
18+
val arr3 = Buf.apply[Rec[String]](8)
19+
}
20+
21+
import scala.collection.mutable
22+
23+
// https://github.com/plokhotnyuk/jsoniter-scala/blob/74d6d557bf81e904d07d4b8fbead4e4cab700bea/jsoniter-scala-macros/shared/src/test/scala-3/com/github/plokhotnyuk/jsoniter_scala/macros/JsonCodeMakerNewTypeSpec.scala#L40-L148
24+
class Spec {
25+
inline def in(testFun: => Any): Unit = {
26+
val _ = testFun
27+
}
28+
29+
in {
30+
type JsonPrimitive = String | Int
31+
type Rec[JA[_], A] = A match {
32+
case JsonPrimitive => JsonPrimitive | JA[Rec[JA, JsonPrimitive]]
33+
case _ => A | JA[Rec[JA, A]]
34+
}
35+
36+
type Json = Rec[
37+
[A] =>> Seq[A],
38+
JsonPrimitive
39+
]
40+
41+
val arr = new mutable.ArrayBuffer[Json](8)
42+
}
43+
}

0 commit comments

Comments
 (0)