Skip to content

Commit 65bbf78

Browse files
committed
Expr#show: Don't crash when the expression contains an unsupported type (like a SkolemType)
When the SkolemType appears as the prefix of a TypeRef, we avoid it by going using `qualifier` which is defined in QuotesImpl to widen skolem, but skolems can appear in any position, and so before this change we would get a compiler crash in the added test case where the skolem appears as the prefix of a TermRef. We fix this by adding fallback cases in the quotes pretty-printer, now for the test case we get: Test.f.ho(((arg: <<SkolemType(693709097) does not have a corresponding extractor> does not have a source representation>.x.type) => arg)) Which isn't great, but better than a crash. Maybe we should run `Type#deskolemized` on a type before trying to print it in SourceCode/Extractors, but currently these files are intentionally defined to not depend on compiler internals and do not have a `Context` so we cannot even call `deskolemized` on them. Alternatively, maybe SkolemType should be a tasty-reflect constructor but that would also be a pretty big change. [Cherry-picked 0ee8762][modified]
1 parent a4141dd commit 65bbf78

File tree

5 files changed

+30
-5
lines changed

5 files changed

+30
-5
lines changed

Diff for: compiler/src/scala/quoted/runtime/impl/printers/Extractors.scala

+4
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,8 @@ object Extractors {
177177
this += "Alternatives(" ++= patterns += ")"
178178
case TypedOrTest(tree, tpt) =>
179179
this += "TypedOrTest(" += tree += ", " += tpt += ")"
180+
case tree =>
181+
this += s"<Internal compiler AST $tree does not have a corresponding reflect extractor>"
180182
}
181183

182184
def visitConstant(x: Constant): this.type = x match {
@@ -239,6 +241,8 @@ object Extractors {
239241
this += "NoPrefix()"
240242
case MatchCase(pat, rhs) =>
241243
this += "MatchCase(" += pat += ", " += rhs += ")"
244+
case tp =>
245+
this += s"<Internal compiler type $tp does not have a corresponding reflect extractor>"
242246
}
243247

244248
def visitSignature(sig: Signature): this.type = {

Diff for: compiler/src/scala/quoted/runtime/impl/printers/SourceCode.scala

+5-3
Original file line numberDiff line numberDiff line change
@@ -1287,7 +1287,9 @@ object SourceCode {
12871287
val sym = annot.tpe.typeSymbol
12881288
sym != Symbol.requiredClass("scala.forceInline") &&
12891289
sym.maybeOwner != Symbol.requiredPackage("scala.annotation.internal")
1290-
case x => cannotBeShownAsSource(x.show(using Printer.TreeStructure))
1290+
case x =>
1291+
cannotBeShownAsSource(x.show(using Printer.TreeStructure))
1292+
false
12911293
}
12921294
printAnnotations(annots)
12931295
if (annots.nonEmpty) this += " "
@@ -1462,8 +1464,8 @@ object SourceCode {
14621464
}
14631465
}
14641466

1465-
private def cannotBeShownAsSource(x: String): Nothing =
1466-
throw new Exception(s"$x does not have a source representation")
1467+
private def cannotBeShownAsSource(x: String): this.type =
1468+
this += s"<$x does not have a source representation>"
14671469

14681470
private object SpecialOp {
14691471
def unapply(arg: Tree): Option[(String, List[Term])] = arg match {

Diff for: tests/pos-macros/skolem/Macro_1.scala

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import scala.quoted.*
2+
3+
object Macro {
4+
5+
def impl(expr: Expr[Any])(using Quotes): Expr[Unit] =
6+
println(expr.show)
7+
'{ () }
8+
9+
inline def macr(inline x: Any): Unit = ${impl('x)}
10+
}

Diff for: tests/pos-macros/skolem/Test_2.scala

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
trait Foo:
2+
val x: Int
3+
def ho(p: x.type => x.type): Unit = ()
4+
5+
object Test {
6+
var f: Foo = ???
7+
Macro.macr:
8+
f.ho(arg => arg)
9+
}

Diff for: tests/run-macros/i19905.check

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
java.lang.Exception: NoPrefix() does not have a source representation
2-
java.lang.Exception: NoPrefix() does not have a source representation
1+
<NoPrefix() does not have a source representation>
2+
<NoPrefix() does not have a source representation>
33
NoPrefix()

0 commit comments

Comments
 (0)