From ff14efd396e7d24ec1b8970c312e996e761a0c6a Mon Sep 17 00:00:00 2001 From: Tomasz Godzik Date: Sun, 12 Oct 2025 23:41:48 +0200 Subject: [PATCH 1/2] bugfix: Fix possible SuspendException thrown when using macros Fixes https://github.com/scalameta/metals/issues/7872 [Cherry-picked 3dfa5ee919029b88ffcb2f366e6564327811d608] --- .../tools/dotc/interactive/Completion.scala | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/interactive/Completion.scala b/compiler/src/dotty/tools/dotc/interactive/Completion.scala index 3d1c595877df..1ea19f88bb99 100644 --- a/compiler/src/dotty/tools/dotc/interactive/Completion.scala +++ b/compiler/src/dotty/tools/dotc/interactive/Completion.scala @@ -591,12 +591,15 @@ object Completion: case _: MethodOrPoly => tpe case _ => ExprType(tpe) + // Try added due to https://github.com/scalameta/metals/issues/7872 def tryApplyingReceiverToExtension(termRef: TermRef): Option[SingleDenotation] = - ctx.typer.tryApplyingExtensionMethod(termRef, qual) - .map { tree => - val tpe = asDefLikeType(tree.typeOpt.dealias) - termRef.denot.asSingleDenotation.mapInfo(_ => tpe) - } + try + ctx.typer.tryApplyingExtensionMethod(termRef, qual) + .map { tree => + val tpe = asDefLikeType(tree.typeOpt.dealias) + termRef.denot.asSingleDenotation.mapInfo(_ => tpe) + } + catch case NonFatal(_) => None def extractMemberExtensionMethods(types: Seq[Type]): Seq[(TermRef, TermName)] = object DenotWithMatchingName: @@ -694,13 +697,13 @@ object Completion: * @param qual The argument to which the implicit conversion should be applied. * @return The set of types after `qual` implicit conversion. */ - private def implicitConversionTargets(qual: tpd.Tree)(using Context): Set[SearchSuccess] = { + private def implicitConversionTargets(qual: tpd.Tree)(using Context): Set[SearchSuccess] = try { val typer = ctx.typer val conversions = new typer.ImplicitSearch(defn.AnyType, qual, pos.span, Set.empty).allImplicits interactiv.println(i"implicit conversion targets considered: ${conversions.toList}%, %") conversions - } + } catch case NonFatal(_) => Set.empty /** Filter for names that should appear when looking for completions. */ private object completionsFilter extends NameFilter: From 66b9b1b2089471da5c9e8bb4fb5a1cb56684d838 Mon Sep 17 00:00:00 2001 From: Tomasz Godzik Date: Mon, 13 Oct 2025 14:09:30 +0200 Subject: [PATCH 2/2] chore: Add logget.warn in case where it breaks [Cherry-picked 078be56f0625c52a274161703b0b7d56eb257ad2] --- .../tools/dotc/interactive/Completion.scala | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/interactive/Completion.scala b/compiler/src/dotty/tools/dotc/interactive/Completion.scala index 1ea19f88bb99..5cbe430b38e8 100644 --- a/compiler/src/dotty/tools/dotc/interactive/Completion.scala +++ b/compiler/src/dotty/tools/dotc/interactive/Completion.scala @@ -35,6 +35,8 @@ import dotty.tools.dotc.core.Constants import dotty.tools.dotc.core.TypeOps import dotty.tools.dotc.core.StdNames +import java.util.logging.Logger + /** * One of the results of a completion query. * @@ -48,6 +50,8 @@ case class Completion(label: String, description: String, symbols: List[Symbol]) object Completion: + private val logger = Logger.getLogger(this.getClass.getName) + def scopeContext(pos: SourcePosition)(using Context): CompletionResult = val tpdPath = Interactive.pathTo(ctx.compilationUnit.tpdTree, pos.span) val completionContext = Interactive.contextOfPath(tpdPath).withPhase(Phases.typerPhase) @@ -599,7 +603,11 @@ object Completion: val tpe = asDefLikeType(tree.typeOpt.dealias) termRef.denot.asSingleDenotation.mapInfo(_ => tpe) } - catch case NonFatal(_) => None + catch case NonFatal(ex) => + logger.warning( + s"Exception when trying to apply extension method:\n ${ex.getMessage()}\n${ex.getStackTrace().mkString("\n")}" + ) + None def extractMemberExtensionMethods(types: Seq[Type]): Seq[(TermRef, TermName)] = object DenotWithMatchingName: @@ -703,7 +711,11 @@ object Completion: interactiv.println(i"implicit conversion targets considered: ${conversions.toList}%, %") conversions - } catch case NonFatal(_) => Set.empty + } catch case NonFatal(ex) => + logger.warning( + s"Exception when searching for implicit conversions:\n ${ex.getMessage()}\n${ex.getStackTrace().mkString("\n")}" + ) + Set.empty /** Filter for names that should appear when looking for completions. */ private object completionsFilter extends NameFilter: