File tree 7 files changed +68
-11
lines changed
compiler/src/dotty/tools/dotc/transform
7 files changed +68
-11
lines changed Original file line number Diff line number Diff line change @@ -4,6 +4,7 @@ package transform
4
4
5
5
import dotty .tools .dotc .core .Contexts ._
6
6
import dotty .tools .dotc .core .Decorators ._
7
+ import dotty .tools .dotc .core .Symbols ._
7
8
import dotty .tools .dotc .core .Flags ._
8
9
import dotty .tools .dotc .core .Types ._
9
10
import dotty .tools .dotc .transform .MegaPhase .MiniPhase
@@ -37,7 +38,10 @@ class InlineVals extends MiniPhase:
37
38
if ! isPureExpr(rhs) then
38
39
val details = if enclosingInlineds.isEmpty then " " else em " but was: $rhs"
39
40
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)
43
47
}
Original file line number Diff line number Diff line change @@ -84,11 +84,13 @@ object FromExpr {
84
84
def unapply (expr : Expr [T ])(using Quotes ) =
85
85
import quotes .reflect ._
86
86
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
89
89
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
92
94
}
93
95
rec(expr.asTerm)
94
96
}
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 6
6
neht
7
7
esle
8
8
lav
9
- vals
9
+ slav
10
10
fed
11
- defs
11
+ sfed
12
12
fed
13
13
rab
14
14
yrt
Original file line number Diff line number Diff line change @@ -31,7 +31,7 @@ object Test {
31
31
32
32
rewrite {
33
33
val s : " vals" = " vals"
34
- println(s) // prints "foo" not "oof"
34
+ println(s)
35
35
}
36
36
37
37
rewrite {
@@ -41,7 +41,7 @@ object Test {
41
41
42
42
rewrite {
43
43
def s : " defs" = " defs"
44
- println(s) // prints "foo" not "oof"
44
+ println(s)
45
45
}
46
46
47
47
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