@@ -1239,17 +1239,60 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
12391239 assert(level == 0 )
12401240 val inlinedFrom = enclosingInlineds.last
12411241 val ctx1 = tastyreflect.MacroExpansion .context(inlinedFrom)
1242- val evaluatedSplice = Splicer .splice(body, inlinedFrom.sourcePos, MacroClassLoader .fromContext)(ctx1)
12431242
1244- val inlinedNormailizer = new TreeMap {
1245- override def transform (tree : tpd.Tree )(implicit ctx : Context ): tpd.Tree = tree match {
1246- case Inlined (EmptyTree , Nil , expr) if enclosingInlineds.isEmpty => transform(expr)
1247- case _ => super .transform(tree)
1243+ val dependencies = macroDependencies(body)
1244+
1245+ if (dependencies.nonEmpty) {
1246+ var location = inlinedFrom.symbol
1247+ if (location.isLocalDummy) location = location.owner
1248+
1249+ val msg =
1250+ em """ Failed to expand macro. This macro depends on an implementation that is defined in the same project and not yet compiled.
1251+ |In particular ${inlinedFrom.symbol} depends on ${dependencies.map(_.show).mkString(" , " )}.
1252+ |
1253+ |Moving ${dependencies.map(_.show).mkString(" , " )} to a different project would fix this.
1254+ | """ .stripMargin
1255+ ctx.error(msg, inlinedFrom.sourcePos)
1256+ EmptyTree
1257+ } else {
1258+ val evaluatedSplice = Splicer .splice(body, inlinedFrom.sourcePos, MacroClassLoader .fromContext)(ctx1)
1259+
1260+ val inlinedNormailizer = new TreeMap {
1261+ override def transform (tree : tpd.Tree )(implicit ctx : Context ): tpd.Tree = tree match {
1262+ case Inlined (EmptyTree , Nil , expr) if enclosingInlineds.isEmpty => transform(expr)
1263+ case _ => super .transform(tree)
1264+ }
12481265 }
1266+ val normalizedSplice = inlinedNormailizer.transform(evaluatedSplice)
1267+ if (normalizedSplice.isEmpty) normalizedSplice
1268+ else normalizedSplice.withSpan(span)
12491269 }
1250- val normalizedSplice = inlinedNormailizer.transform(evaluatedSplice)
1251- if (normalizedSplice.isEmpty) normalizedSplice
1252- else normalizedSplice.withSpan(span)
1270+ }
1271+
1272+ /** Return the set of symbols that are refered at level -1 by the tree and defined in the current run.
1273+ * This corresponds to the symbols that will need to be interpreted.
1274+ */
1275+ private def macroDependencies (tree : Tree )(implicit ctx : Context ) = {
1276+ new TreeAccumulator [Set [Symbol ]] {
1277+ private [this ] var level = - 1
1278+ override def apply (syms : Set [Symbol ], tree : tpd.Tree )(implicit ctx : Context ): Set [Symbol ] = {
1279+ if (level != - 1 ) foldOver(syms, tree)
1280+ else tree match {
1281+ case tree : RefTree if level == - 1 && tree.symbol.isDefinedInCurrentRun && ! tree.symbol.isLocal =>
1282+ foldOver(syms + tree.symbol, tree)
1283+ case Quoted (body) =>
1284+ level += 1
1285+ try apply(syms, body)
1286+ finally level -= 1
1287+ case Spliced (body) =>
1288+ level -= 1
1289+ try apply(syms, body)
1290+ finally level += 1
1291+ case _ =>
1292+ foldOver(syms, tree)
1293+ }
1294+ }
1295+ }.apply(Set .empty, tree)
12531296 }
12541297}
12551298
0 commit comments