如何避免Scala编译器忽略`scala.quoted.Quotes.reflectModule.report.info`输出?
解决Scala 3.6.4递归宏中
report.info消息被去重的问题 以下是几个可行的解决方案,帮你通过编译器报告机制输出所有调试信息:
给每条消息指定唯一的位置参数
Scala 3编译器默认会对同一位置的消息进行去重处理,即便消息文本不同,若位置相同也可能被合并。你可以在调用report.info时,显式传递不同的Position实例,比如使用当前处理的Expr的位置,或者手动生成偏移后的位置:// 使用Expr的位置绑定消息 def debugExpr[A](expr: Expr[A])(using Quotes): Unit = { quotes.reflect.report.info(s"Processing expr: ${expr.show}", expr.pos) // 递归处理逻辑... } // 手动生成唯一位置(无现成Expr时) def debugMsg(msg: String)(using Quotes): Unit = { val basePos = quotes.reflect.Position.ofMacroExpansion // 通过随机偏移生成唯一位置,避免与其他消息位置冲突 val uniquePos = basePos.withOffset(basePos.start + scala.util.Random.nextInt(1000)) quotes.reflect.report.info(msg, uniquePos) }调整编译器的消息去重阈值
通过编译器选项修改消息去重的触发规则:- 使用
-Xmessage-duplication-threshold N:设置同一位置/内容的消息出现N次后才去重,比如设置-Xmessage-duplication-threshold 10000,确保调试消息不会被轻易合并。 - 使用
-Xno-message-duplication:直接关闭所有消息去重功能,适合临时调试场景。
- 使用
临时切换报告级别
编译器对不同级别的消息处理策略不同,warning级别的消息默认不会被去重。你可以临时将report.info替换为report.warning,调试完成后再改回:quotes.reflect.report.warning("调试消息:xxxx")注意:这会产生编译警告,调试结束后记得恢复为
info,避免干扰正常编译流程。确保递归宏的Quotes上下文正确传递
在递归宏中,每次递归调用都要显式传递当前的Quotes实例,避免因上下文丢失导致报告机制异常:def recursiveMacro[A](expr: Expr[A])(using Quotes): Expr[A] = { quotes.reflect.report.info(s"递归处理:${expr.show}", expr.pos) // 递归调用时传递当前上下文 expr match { case '{ $x: Int + $y: Int } => recursiveMacro(x) recursiveMacro(y) // ... case _ => expr } }
内容的提问来源于stack exchange,提问作者Readren
相关产品推荐
相关产品推荐

