File tree 4 files changed +42
-1
lines changed
compiler/src/dotty/tools/dotc/typer
4 files changed +42
-1
lines changed Original file line number Diff line number Diff line change @@ -40,6 +40,11 @@ object Inliner {
40
40
41
41
private type DefBuffer = mutable.ListBuffer [ValOrDefDef ]
42
42
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
+
43
48
/** `sym` is an inline method with a known body to inline.
44
49
*/
45
50
def hasBodyToInline (sym : SymDenotation )(using Context ): Boolean =
@@ -154,7 +159,10 @@ object Inliner {
154
159
if bindings.nonEmpty then
155
160
cpy.Block (tree)(bindings.toList, inlineCall(tree1))
156
161
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)
158
166
new Inliner (tree, body).inlined(tree.srcPos)
159
167
else
160
168
ctx.base.stopInlining = true
Original file line number Diff line number Diff line change @@ -103,6 +103,10 @@ class Namer { typer: Typer =>
103
103
}
104
104
}
105
105
106
+ def hasDefinedSymbol (tree : Tree )(using Context ): Boolean =
107
+ val xtree = expanded(tree)
108
+ xtree.hasAttachment(TypedAhead ) || xtree.hasAttachment(SymOfTree )
109
+
106
110
/** The enclosing class with given name; error if none exists */
107
111
def enclosingClassNamed (name : TypeName , span : Span )(using Context ): Symbol =
108
112
if (name.isEmpty) NoSymbol
@@ -837,6 +841,10 @@ class Namer { typer: Typer =>
837
841
private def addInlineInfo (sym : Symbol ) = original match {
838
842
case original : untpd.DefDef if sym.isInlineMethod =>
839
843
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)
840
848
val mdef = typedAheadExpr(original).asInstanceOf [tpd.DefDef ]
841
849
PrepareInlineable .wrapRHS(original, mdef.tpt, mdef.rhs)
842
850
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