File tree Expand file tree Collapse file tree 7 files changed +68
-11
lines changed
compiler/src/dotty/tools/dotc/transform Expand file tree Collapse file tree 7 files changed +68
-11
lines changed Original file line number Diff line number Diff line change @@ -4,6 +4,7 @@ package transform
44
55import dotty .tools .dotc .core .Contexts ._
66import dotty .tools .dotc .core .Decorators ._
7+ import dotty .tools .dotc .core .Symbols ._
78import dotty .tools .dotc .core .Flags ._
89import dotty .tools .dotc .core .Types ._
910import dotty .tools .dotc .transform .MegaPhase .MiniPhase
@@ -37,7 +38,10 @@ class InlineVals extends MiniPhase:
3738 if ! isPureExpr(rhs) then
3839 val details = if enclosingInlineds.isEmpty then " " else em " but was: $rhs"
3940 report.error(s " inline value must be pure $details" , rhs.srcPos)
40- case _ =>
41- val pos = if tpt.span.isZeroExtent then rhs.srcPos else tpt.srcPos
42- report.error(em " inline value must have a literal constant type " , pos)
41+ case tp =>
42+ if tp.derivesFrom(defn.StringClass ) || defn.ScalaValueClasses ().exists(tp.derivesFrom(_)) then
43+ val pos = if tpt.span.isZeroExtent then rhs.srcPos else tpt.srcPos
44+ report.error(em " inline value must have a literal constant type " , pos)
45+ else
46+ report.error(em " inline value must contain a literal constant value. \n\n To inline more complex types consider using `inline def` " , rhs)
4347 }
Original file line number Diff line number Diff line change @@ -84,11 +84,13 @@ object FromExpr {
8484 def unapply (expr : Expr [T ])(using Quotes ) =
8585 import quotes .reflect ._
8686 def rec (tree : Term ): Option [T ] = tree match {
87- case Literal (c) if c.value != null => Some (c.value. asInstanceOf [ T ])
88- case Block ( Nil , e) => rec(e)
87+ case Block (stats, e) => if stats.isEmpty then rec(e) else None
88+ case Inlined (_, bindings, e) => if bindings.isEmpty then rec(e) else None
8989 case Typed (e, _) => rec(e)
90- case Inlined (_, Nil , e) => rec(e)
91- case _ => None
90+ case _ =>
91+ tree.tpe.widenTermRefByName match
92+ case ConstantType (c) => Some (c.value.asInstanceOf [T ])
93+ case _ => None
9294 }
9395 rec(expr.asTerm)
9496 }
Original file line number Diff line number Diff line change 1+ -- Error: tests/neg/i11854.scala:4:14 ----------------------------------------------------------------------------------
2+ 4 |inline val j: Int = 2 // error
3+ | ^^^
4+ | inline value must have a literal constant type
5+ -- Error: tests/neg/i11854.scala:5:14 ----------------------------------------------------------------------------------
6+ 5 |inline val b: Boolean = true // error
7+ | ^^^^^^^
8+ | inline value must have a literal constant type
9+ -- Error: tests/neg/i11854.scala:6:14 ----------------------------------------------------------------------------------
10+ 6 |inline val s: String = "" // error
11+ | ^^^^^^
12+ | inline value must have a literal constant type
13+ -- Error: tests/neg/i11854.scala:7:18 ----------------------------------------------------------------------------------
14+ 7 |inline val bagA = new Bag(Seq('a', 'b', 'c')) // error
15+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
16+ | inline value must contain a literal constant value.
17+ |
18+ | To inline more complex types consider using `inline def`
19+ -- Error: tests/neg/i11854.scala:8:23 ----------------------------------------------------------------------------------
20+ 8 |inline val bagB: Bag = new Bag(Seq('a', 'b', 'c')) // error
21+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
22+ | inline value must contain a literal constant value.
23+ |
24+ | To inline more complex types consider using `inline def`
Original file line number Diff line number Diff line change 66neht
77esle
88lav
9- vals
9+ slav
1010fed
11- defs
11+ sfed
1212fed
1313rab
1414yrt
Original file line number Diff line number Diff line change @@ -31,7 +31,7 @@ object Test {
3131
3232 rewrite {
3333 val s : " vals" = " vals"
34- println(s) // prints "foo" not "oof"
34+ println(s)
3535 }
3636
3737 rewrite {
@@ -41,7 +41,7 @@ object Test {
4141
4242 rewrite {
4343 def s : " defs" = " defs"
44- println(s) // prints "foo" not "oof"
44+ println(s)
4545 }
4646
4747 rewrite {
Original file line number Diff line number Diff line change 1+ @ main def Test : Unit =
2+ inline def str1 = " Hello, "
3+ inline val str2 = " Scala 3"
4+ println(Str .concat(str1, str2))
5+
6+ inline def i1 = 1
7+ inline val i2 = 2
8+ println(I .sum(i1, i2))
Original file line number Diff line number Diff line change 1+ import scala .quoted .*
2+
3+ object Str :
4+ inline def concat (inline a : String , inline b : String ): String =
5+ $ { evalConcat(' a , ' b ) }
6+
7+ def evalConcat (expra : Expr [String ], exprb : Expr [String ])(using Quotes ): Expr [String ] =
8+ val a = expra.valueOrError
9+ val b = exprb.valueOrError
10+ Expr (a ++ b)
11+
12+ object I :
13+ inline def sum (inline a : Int , inline b : Int ): Int =
14+ $ { evalConcat(' a , ' b ) }
15+
16+ def evalConcat (expra : Expr [Int ], exprb : Expr [Int ])(using Quotes ): Expr [Int ] =
17+ val a = expra.valueOrError
18+ val b = exprb.valueOrError
19+ Expr (a + b)
You can’t perform that action at this time.
0 commit comments