Skip to content

Commit 03dc7ac

Browse files
committed
Disallow macro expansion in compilation depending on BE files, add tests
Also includes some minor fixes to shown errors and to the test framework.
1 parent 25b5d0b commit 03dc7ac

File tree

13 files changed

+64
-8
lines changed

13 files changed

+64
-8
lines changed

compiler/src/dotty/tools/dotc/core/Denotations.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -718,7 +718,7 @@ object Denotations {
718718
|| ctx.settings.YtestPickler.value // mixing test pickler with debug printing can travel back in time
719719
|| ctx.mode.is(Mode.Printing) // no use to be picky when printing error messages
720720
|| symbol.isOneOf(ValidForeverFlags)
721-
|| ctx.isBestEffort,
721+
|| ctx.isBestEffort || ctx.usesBestEffortTasty,
722722
s"denotation $this invalid in run ${ctx.runId}. ValidFor: $validFor")
723723
var d: SingleDenotation = this
724724
while ({

compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,9 @@ class TreePickler(pickler: TastyPickler) {
6363
fillRef(lengthAddr, currentAddr, relative = true)
6464
}
6565

66-
/* There are certain expectations with code naturally being able to reach typer vs
67-
* one that uses best-effort-compilation.
66+
/* There are certain expectations with code naturally being able to reach typer
67+
* as opposed to one that uses best-effort-compilation. For betasty files, we try
68+
* to avoid calling any assertions which can be unfullfilled.
6869
*/
6970
private inline def assertForBestEffort(assertion: Boolean)(using ctx: Context) =
7071
!ctx.isBestEffort || assertion
@@ -303,7 +304,7 @@ class TreePickler(pickler: TastyPickler) {
303304
pickleType(tpe.ref)
304305
case tpe: ErrorType if ctx.isBestEffort =>
305306
pickleError()
306-
case tree if ctx.isBestEffort =>
307+
case _ if ctx.isBestEffort =>
307308
pickleError()
308309
}
309310

compiler/src/dotty/tools/dotc/inlines/Inliner.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -835,7 +835,7 @@ class Inliner(val call: tpd.Tree)(using Context):
835835

836836
override def typedSplice(tree: untpd.Splice, pt: Type)(using Context): Tree =
837837
super.typedSplice(tree, pt) match
838-
case tree1 @ Splice(expr) if level == 0 && !hasInliningErrors =>
838+
case tree1 @ Splice(expr) if level == 0 && !hasInliningErrors && !ctx.usesBestEffortTasty =>
839839
val expanded = expandMacro(expr, tree1.srcPos)
840840
transform.TreeChecker.checkMacroGeneratedTree(tree1, expanded)
841841
typedExpr(expanded) // Inline calls and constant fold code generated by the macro

compiler/src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4280,6 +4280,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
42804280
* tree that went unreported. A scenario where this happens is i1802.scala.
42814281
*/
42824282
def ensureReported(tp: Type) = tp match {
4283+
case err: PreviousErrorType if ctx.usesBestEffortTasty => // do nothing if error was already reported in previous compilation
42834284
case err: ErrorType if !ctx.reporter.errorsReported => report.error(err.msg, tree.srcPos)
42844285
case _ =>
42854286
}

compiler/test/dotty/tools/dotc/BestEffortCompilationTests.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ class BestEffortCompilationTests {
2121
@Test def negTestFromBestEffortTasty: Unit = {
2222
// Can be reproduced with
2323
// > sbt
24-
// > scalac --Ybest-effort-dir best-effort-dir <source>
25-
// > scalac --from-tasty -Ywith-best-effort-tasty best-effort-dir/<tasty>
24+
// > scalac --Ybest-effort <source>
25+
// > scalac --from-tasty -Ywith-best-effort-tasty META_INF/best-effort/<tasty>
2626

2727
implicit val testGroup: TestGroup = TestGroup("negTestFromBestEffortTasty")
2828
compileBestEffortTastyInDir(s"tests${JFile.separator}neg", bestEffortBaselineOptions,
@@ -34,7 +34,7 @@ class BestEffortCompilationTests {
3434
// Tests an actual use case of this compilation mode, where symbol definitions of the downstream
3535
// projects depend on the best effort tasty files generated with the Best Effort dir option
3636
@Test def bestEffortIntergrationTest: Unit = {
37-
implicit val testGroup: TestGroup = TestGroup("BestEffortIntegrationTest")
37+
implicit val testGroup: TestGroup = TestGroup("bestEffortIntegrationTests")
3838
compileBestEffortIntegration(s"tests${JFile.separator}best-effort", bestEffortBaselineOptions)
3939
.noCrashWithCompilingDependencies()
4040
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
object ExecutedMacro:
2+
val failingMacro = FailingTransparent.execute()
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
object FailingTransparentInline:
2+
sealed trait Foo
3+
case class FooA() extends Foo
4+
case class FooB() extends Foo
5+
6+
transparent inline def execute(): Foo = ${ executeImpl() }
7+
def executeImpl(using Quotes)() = {
8+
val a = 0
9+
a.asInstanceOf[String]
10+
FooB()
11+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
object Main:
2+
ExecutedMacro.failingMacro
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import scala.quoted._
2+
object BrokenMacros:
3+
transparent inline def macro1() = ${macroImpl()}
4+
def macroImpl(using Quotes)(): Expr[String] =
5+
val a: Int = "str" // source of the error
6+
'{a}
7+
8+
sealed trait Foo
9+
case class FooA() extends Foo
10+
case class FooB()
11+
transparent inline def macro2(): Foo = ${macro2Impl()}
12+
def macro2Impl(using Quotes)(): Expr[Foo] =
13+
'{FooB()}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
object Main
2+
val a = BrokenMacros.macro1()
3+
val b = BrokenMacros.macro2()
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import scala.quoted._
2+
object BrokenMacros:
3+
transparent inline def macro1() = ${macroImpl()}
4+
def macroImpl(using Quotes)(): Expr[String] =
5+
val a: Int = "str" // source of the error
6+
'{a}
7+
8+
sealed trait Foo
9+
case class FooA() extends Foo
10+
case class FooB()
11+
transparent inline def macro2(): Foo = ${macro2Impl()}
12+
def macro2Impl(using Quotes)(): Expr[Foo] =
13+
'{FooB()}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
object MirrorTypes:
2+
case class BrokenType(a: NonExistent, b: Int)
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import scala.deriving.Mirror
2+
3+
object MirrorExec:
4+
transparent inline def getNames[T](using m: Mirror.Of[T]): m.MirroredElemTypes = // ???
5+
scala.compiletime.erasedValue[m.MirroredElemTypes]
6+
7+
val ab = getNames[MirrorTypes.BrokenType]
8+

0 commit comments

Comments
 (0)