From d95e7a78d2bb5df8639b7f0ee804e013583bd602 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Tue, 24 Oct 2023 16:38:08 +0200 Subject: [PATCH] Add hint for nested quotes missing staged `Quotes` Fix #17338 --- .../src/dotty/tools/dotc/staging/CrossStageSafety.scala | 4 ++++ tests/neg-macros/i17338.check | 9 +++++++++ tests/neg-macros/i17338.scala | 4 ++++ 3 files changed, 17 insertions(+) create mode 100644 tests/neg-macros/i17338.check create mode 100644 tests/neg-macros/i17338.scala diff --git a/compiler/src/dotty/tools/dotc/staging/CrossStageSafety.scala b/compiler/src/dotty/tools/dotc/staging/CrossStageSafety.scala index 25887cedb3e5..89d8f9a80ee3 100644 --- a/compiler/src/dotty/tools/dotc/staging/CrossStageSafety.scala +++ b/compiler/src/dotty/tools/dotc/staging/CrossStageSafety.scala @@ -228,6 +228,10 @@ class CrossStageSafety extends TreeMapWithStages { "\n\n" + "Hint: Staged references to inline definition in quotes are only inlined after the quote is spliced into level 0 code by a macro. " + "Try moving this inline definition in a statically accessible location such as an object (this definition can be private)." + else if level > 0 && sym.info.derivesFrom(defn.QuotesClass) then + s"""\n + |Hint: Nested quote needs a local context defined at level $level. + |One way to introduce this context is to give the outer quote the type `Expr[Quotes ?=> Expr[T]]`.""".stripMargin else "" report.error( em"""access to $symStr from wrong staging level: diff --git a/tests/neg-macros/i17338.check b/tests/neg-macros/i17338.check new file mode 100644 index 000000000000..e47312130b1e --- /dev/null +++ b/tests/neg-macros/i17338.check @@ -0,0 +1,9 @@ +-- Error: tests/neg-macros/i17338.scala:4:5 ---------------------------------------------------------------------------- +4 | '{ '{ 1 } } // error + | ^ + | access to parameter quotes from wrong staging level: + | - the definition is at level 0, + | - but the access is at level 1. + | + | Hint: Nested quote needs a local context defined at level 1. + | One way to introduce this context is to give the outer quote the type `Expr[Quotes ?=> Expr[T]]`. diff --git a/tests/neg-macros/i17338.scala b/tests/neg-macros/i17338.scala new file mode 100644 index 000000000000..941cbdd6216d --- /dev/null +++ b/tests/neg-macros/i17338.scala @@ -0,0 +1,4 @@ +import scala.quoted.* + +def test(using quotes: Quotes): Expr[Expr[Int]] = + '{ '{ 1 } } // error