From e90d3766538d47a87b18880c4a8bc0555d913293 Mon Sep 17 00:00:00 2001 From: odersky Date: Mon, 23 Oct 2023 17:59:00 +0200 Subject: [PATCH] Avoid crash arising from trying to find conversions from polymorphic singleton types This is an alternative fix for #18695, which already got fixed in a different way by #18719. This PR adds the actual tests, and leaves in the fix as a defensive measure in case the situation arises by some other means than the one foxed in #18719. [Cherry-picked f995a8c5eeeaff97c682d802be81ab728387ce6a] --- compiler/src/dotty/tools/dotc/ast/tpd.scala | 14 ++++++-------- compiler/src/dotty/tools/dotc/typer/Typer.scala | 8 +++++++- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/ast/tpd.scala b/compiler/src/dotty/tools/dotc/ast/tpd.scala index 72e9e58eefad..a0913b628abd 100644 --- a/compiler/src/dotty/tools/dotc/ast/tpd.scala +++ b/compiler/src/dotty/tools/dotc/ast/tpd.scala @@ -45,21 +45,19 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo { def Apply(fn: Tree, args: List[Tree])(using Context): Apply = fn match case Block(Nil, expr) => Apply(expr, args) + case _: RefTree | _: GenericApply | _: Inlined | _: Hole => + ta.assignType(untpd.Apply(fn, args), fn, args) case _ => - assert( - fn.isInstanceOf[RefTree | GenericApply | Inlined | Hole] || ctx.reporter.errorsReported, - s"Illegal Apply function prefix: $fn" - ) + assert(ctx.reporter.errorsReported) ta.assignType(untpd.Apply(fn, args), fn, args) def TypeApply(fn: Tree, args: List[Tree])(using Context): TypeApply = fn match case Block(Nil, expr) => TypeApply(expr, args) + case _: RefTree | _: GenericApply => + ta.assignType(untpd.TypeApply(fn, args), fn, args) case _ => - assert( - fn.isInstanceOf[RefTree | GenericApply] || ctx.reporter.errorsReported, - s"Illegal TypeApply function prefix: $fn" - ) + assert(ctx.reporter.errorsReported, s"unexpected tree for type application: $fn") ta.assignType(untpd.TypeApply(fn, args), fn, args) def Literal(const: Constant)(using Context): Literal = diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index 65b474f24b3e..bf6e0631ca10 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -4267,7 +4267,13 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer case _ => adaptOverloaded(ref) } - case poly: PolyType if !(ctx.mode is Mode.Type) => + case poly: PolyType + if !(ctx.mode is Mode.Type) && dummyTreeOfType.unapply(tree).isEmpty => + // If we are in a conversion from a TermRef with polymorphic underlying + // type, give up. In this case the typed `null` literal cannot be instantiated. + // Test case was but i18695.scala, but it got fixed by a different tweak in #18719. + // We leave test for this condition in as a defensive measure in case + // it arises somewhere else. if isApplyProxy(tree) then newExpr else if pt.isInstanceOf[PolyProto] then tree else