File tree Expand file tree Collapse file tree 4 files changed +42
-1
lines changed
compiler/src/dotty/tools/dotc/typer Expand file tree Collapse file tree 4 files changed +42
-1
lines changed Original file line number Diff line number Diff line change @@ -40,6 +40,11 @@ object Inliner {
4040
4141 private type DefBuffer = mutable.ListBuffer [ValOrDefDef ]
4242
43+ /** An exception signalling that an inline info cannot be computed due to a
44+ * cyclic reference. i14772.scala shows a case where this happens.
45+ */
46+ private [typer] class MissingInlineInfo extends Exception
47+
4348 /** `sym` is an inline method with a known body to inline.
4449 */
4550 def hasBodyToInline (sym : SymDenotation )(using Context ): Boolean =
@@ -154,7 +159,10 @@ object Inliner {
154159 if bindings.nonEmpty then
155160 cpy.Block (tree)(bindings.toList, inlineCall(tree1))
156161 else if enclosingInlineds.length < ctx.settings.XmaxInlines .value && ! reachedInlinedTreesLimit then
157- val body = bodyToInline(tree.symbol) // can typecheck the tree and thereby produce errors
162+ val body =
163+ try bodyToInline(tree.symbol) // can typecheck the tree and thereby produce errors
164+ catch case _ : MissingInlineInfo =>
165+ throw CyclicReference (ctx.owner)
158166 new Inliner (tree, body).inlined(tree.srcPos)
159167 else
160168 ctx.base.stopInlining = true
Original file line number Diff line number Diff line change @@ -103,6 +103,10 @@ class Namer { typer: Typer =>
103103 }
104104 }
105105
106+ def hasDefinedSymbol (tree : Tree )(using Context ): Boolean =
107+ val xtree = expanded(tree)
108+ xtree.hasAttachment(TypedAhead ) || xtree.hasAttachment(SymOfTree )
109+
106110 /** The enclosing class with given name; error if none exists */
107111 def enclosingClassNamed (name : TypeName , span : Span )(using Context ): Symbol =
108112 if (name.isEmpty) NoSymbol
@@ -837,6 +841,10 @@ class Namer { typer: Typer =>
837841 private def addInlineInfo (sym : Symbol ) = original match {
838842 case original : untpd.DefDef if sym.isInlineMethod =>
839843 def rhsToInline (using Context ): tpd.Tree =
844+ if ! original.symbol.exists && ! hasDefinedSymbol(original) then
845+ throw
846+ if sym.isCompleted then Inliner .MissingInlineInfo ()
847+ else CyclicReference (sym)
840848 val mdef = typedAheadExpr(original).asInstanceOf [tpd.DefDef ]
841849 PrepareInlineable .wrapRHS(original, mdef.tpt, mdef.rhs)
842850 PrepareInlineable .registerInlineInfo(sym, rhsToInline)(using localContext(sym))
Original file line number Diff line number Diff line change 1+ -- [E044] Cyclic Error: tests/neg/i14772.scala:7:7 ---------------------------------------------------------------------
2+ 7 | foo(a) // error
3+ | ^
4+ | Overloaded or recursive method impl needs return type
5+ |
6+ | longer explanation available when compiling with `-explain`
7+ -- Error: tests/neg/i14772.scala:8:12 ----------------------------------------------------------------------------------
8+ 8 | Expr(()) // error
9+ | ^
10+ | no given instance of type quoted.ToExpr[Unit] was found for parameter x$2 of method apply in object Expr.
11+ | I found:
12+ |
13+ | quoted.ToExpr.ClassToExpr[T]
14+ |
15+ | But given instance ClassToExpr in object ToExpr does not match type quoted.ToExpr[Unit].
Original file line number Diff line number Diff line change 1+ import scala .quoted .*
2+
3+ object A {
4+ transparent inline def foo (a : Any ): Any = $ { impl(' a ) }
5+
6+ def impl (a : Expr [Any ])(using Quotes )/* : Expr[Any]*/ = {
7+ foo(a) // error
8+ Expr (()) // error
9+ }
10+ }
You can’t perform that action at this time.
0 commit comments