File tree 3 files changed +95
-4
lines changed
compiler/src/dotty/tools/dotc/quoted
3 files changed +95
-4
lines changed Original file line number Diff line number Diff line change @@ -353,11 +353,16 @@ object Interpreter:
353
353
if ! ctx.compilationUnit.isSuspendable then None
354
354
else targetException match
355
355
case _ : NoClassDefFoundError | _ : ClassNotFoundException =>
356
- val className = targetException.getMessage
357
- if className eq null then None
356
+ val message = targetException.getMessage
357
+ if message eq null then None
358
358
else
359
- val sym = staticRef(className.toTypeName).symbol
360
- if (sym.isDefinedInCurrentRun) Some (sym) else None
359
+ val className = message.replace('/' , '.' )
360
+ val sym =
361
+ if className.endsWith(str.MODULE_SUFFIX ) then staticRef(className.toTermName).symbol.moduleClass
362
+ else staticRef(className.toTypeName).symbol
363
+ // If the symbol does not a a position we assume that it came from the current run and it has an error
364
+ if sym.isDefinedInCurrentRun || (sym.exists && ! sym.srcPos.span.exists) then Some (sym)
365
+ else None
361
366
case _ => None
362
367
}
363
368
}
Original file line number Diff line number Diff line change
1
+ package prelude
2
+ import scala .quoted .*
3
+
4
+ object Macros {
5
+ def validateInlineImpl [A : Type ](assertionExpr : Expr [Assertion [A ]], a : Expr [A ])(using
6
+ Quotes
7
+ ): Expr [Unit ] = {
8
+ import quotes .reflect .*
9
+ val crashRoot = assertionExpr.value
10
+ ' { () }
11
+
12
+ }
13
+ given [A ](using Type [A ]): FromExpr [Assertion [A ]] with {
14
+ def unapply (assertion : Expr [Assertion [A ]])(using Quotes ): Option [Assertion [A ]] = {
15
+ import quotes .reflect .*
16
+
17
+ assertion match {
18
+ case ' { Assertion .greaterThanOrEqualTo[A ]($ { LiteralUnlift (value) })($_) } =>
19
+ Some (Assertion .greaterThanOrEqualTo(value)(orderingForValue(value)))
20
+ case _ => None
21
+ }
22
+ }
23
+ }
24
+
25
+ object LiteralUnlift {
26
+ def unapply [A : Type ](expr : Expr [A ])(using Quotes ): Option [A ] = expr match {
27
+ case ' { $ { Expr (int) }: Int } => Some (int)
28
+ case ' { Int .MaxValue } => Some (Int .MaxValue .asInstanceOf [A ])
29
+ case ' { Int .MinValue } => Some (Int .MinValue .asInstanceOf [A ])
30
+ case ' { $ { Expr (string) }: String } => Some (string)
31
+ case ' { $ { Expr (double) }: Double } => Some (double)
32
+ case ' { $ { Expr (float) }: Float } => Some (float)
33
+ case ' { $ { Expr (long) }: Long } => Some (long)
34
+ case ' { $ { Expr (short) }: Short } => Some (short)
35
+ case ' { $ { Expr (byte) }: Byte } => Some (byte)
36
+ case ' { $ { Expr (char) }: Char } => Some (char)
37
+ case _ => None
38
+ }
39
+ }
40
+
41
+ private def orderingForValue (any : Any )(using Quotes ): Ordering [Any ] = null .asInstanceOf [Ordering [Any ]]
42
+ }
Original file line number Diff line number Diff line change
1
+ package prelude
2
+
3
+ sealed trait Assertion [- A ]:
4
+ def unary_! : Assertion [A ] = ???
5
+ def apply (a : A ): Either [AssertionError , Unit ] = ???
6
+ object Assertion :
7
+ val anything : Assertion [Any ] = ???
8
+ def greaterThanOrEqualTo [A ](value : A )(implicit ordering : Ordering [A ]): Assertion [A ] = ???
9
+
10
+ sealed trait AssertionError
11
+
12
+ abstract class NewtypeCustom [A ] {
13
+ type Type
14
+ protected inline def validateInline (inline value : A ): Unit
15
+
16
+ inline def apply (inline a1 : A ): Type = {
17
+ validateInline(a1)
18
+ a1.asInstanceOf [Type ]
19
+ }
20
+ }
21
+ abstract class Newtype [A ] extends NewtypeCustom [A ] {
22
+ def assertion : Assertion [A ] = Assertion .anything
23
+ protected inline def validateInline (inline value : A ): Unit = $ {
24
+ Macros .validateInlineImpl[A ](' assertion , ' value )
25
+ }
26
+ }
27
+
28
+
29
+ abstract class Subtype [A ] extends Newtype [A ] {
30
+ type Type <: A
31
+ }
32
+
33
+
34
+ package object newtypes {
35
+ type Natural = Natural .Type
36
+ object Natural extends Subtype [Int ] {
37
+
38
+ override inline def assertion = Assertion .greaterThanOrEqualTo(0 )
39
+
40
+ val one : Natural = Natural (1 ) // triggers macro
41
+ }
42
+ }
43
+
44
+ // nopos-error: Cyclic macro dependencies in tests/pos-macros/i19601/Test.scala. Compilation stopped since no further progress can be made.
You can’t perform that action at this time.
0 commit comments