<commit_before>package eu.timepit.refined
package macros

import macrocompat.bundle
import scala.reflect.macros.blackbox
import scala.util.{Success, Try}

@bundle
trait MacroUtils {
  val c: blackbox.Context

  def abort(msg: String): Nothing =
    c.abort(c.enclosingPosition, msg)

  def eval[T](t: c.Expr[T]): T = {
    val expr = c.Expr[T](c.untypecheck(t.tree))

    // Try evaluating expr twice before failing, see
    // https://github.com/fthomas/refined/issues/3
    tryN(2, c.eval(expr))
  }

  def tryN[T](n: Int, t: => T): T =
    Stream.fill(n)(Try(t)).collectFirst { case Success(r) => r }.getOrElse(t)
}<commit_msg>Improve MacroUtils.eval<commit_after>package eu.timepit.refined
package macros

import macrocompat.bundle
import scala.reflect.macros.blackbox
import scala.util.{Success, Try}

@bundle
trait MacroUtils {
  val c: blackbox.Context

  def abort(msg: String): Nothing =
    c.abort(c.enclosingPosition, msg)

  def eval[T](t: c.Expr[T]): T = {
    // Duplicate and untypecheck before calling `eval`, see:
    // http://www.scala-lang.org/api/2.12.0/scala-reflect/scala/reflect/macros/Evals.html#eval[T]%28expr:Evals.this.Expr[T]%29:T
    val expr = c.Expr[T](c.untypecheck(t.tree.duplicate))

    // Try evaluating expr twice before failing, see
    // https://github.com/fthomas/refined/issues/3
    tryN(2, c.eval(expr))
  }

  def tryN[T](n: Int, t: => T): T =
    Stream.fill(n)(Try(t)).collectFirst { case Success(r) => r }.getOrElse(t)
}
{'fraction_non_alphanumeric': 0.15918367346938775, 'fraction_numerical': 0.00816326530612245, 'mean_word_length': 3.7451612903225806, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, 'https://': 2, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3405728', 'n_tokens_mistral': 569, 'n_tokens_neox': 546, 'n_words': 111}