Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
242 commits
Select commit Hold shift + click to select a range
baedc75
inline trait implementation
timotheeandres Feb 24, 2023
80b3d2f
Fix child reference mapping for nested class inside inline trait
starswap Feb 24, 2026
6aa569f
Add some more tests for inline traits
starswap Feb 24, 2026
6bf2567
Add more inline-traits tests
starswap Feb 24, 2026
421083f
Add another test case for inline traits
starswap Feb 24, 2026
a30d370
Add inline-trait-nested-class-parameter-passing.scala
starswap Feb 25, 2026
9a33768
Add inline trait parameter passing test case
starswap Feb 25, 2026
e774122
Fix inline-trait-parent-ref.scala
starswap Feb 26, 2026
7e54ced
Add desugar
starswap Feb 26, 2026
90d6656
Add inline trait trait inheritance
starswap Feb 26, 2026
8b49ecf
Add first version of mapping symbols
starswap Mar 1, 2026
9de5cb9
Switch from TreeTypeMap to MiniPhase
starswap Mar 1, 2026
5e169bf
Remove some unneeded stuff
starswap Mar 1, 2026
81105db
Add missing generic type
starswap Mar 2, 2026
b026b25
Fix PureInterface and NoInits flags on inline traits
starswap Mar 2, 2026
6a3ab50
Clean up unneeded comments in RepalceInlinedTraitSymbols.scala
starswap Mar 2, 2026
f9b1cd0
Fix multiple file inline trait test
starswap Mar 2, 2026
f8f7dd5
tidy
starswap Mar 2, 2026
3dcb26d
s->z
starswap Mar 3, 2026
9a74e01
Add test case for inline traits where generic type is a class
starswap Mar 3, 2026
0391b4e
Generate specialized interface traits (a bit roughly)
starswap Mar 12, 2026
bb3b2a4
Clean up
starswap Mar 12, 2026
5be0822
Add specialized traits cache
starswap Mar 13, 2026
da9b289
Save rejected method
starswap Mar 14, 2026
5296cc9
Revert "Save rejected method"
starswap Mar 14, 2026
c18dc01
Break out separate Specialized representation
starswap Mar 14, 2026
8c1fb7c
Make inline traits robust to Trees without attached symbol, such as t…
starswap Mar 14, 2026
063e4d2
Update comment
starswap Mar 14, 2026
7518cef
Save
starswap Mar 15, 2026
c3a28b3
Add impl and make work for specialized-traits-with-param.scala
starswap Mar 16, 2026
d7578a0
Add a couple more inline trait tests
starswap Mar 16, 2026
8d5dd49
Fix inline traits mixin error with indirect inheritance
starswap Mar 17, 2026
00e7fa3
Add first specialized traits run test!
starswap Mar 17, 2026
3c3b63d
Clean up test
starswap Mar 17, 2026
169daa5
Make name clearer
starswap Mar 17, 2026
b13a884
Fix incorrect owner bug
starswap Mar 17, 2026
4b253a6
Tidy
starswap Mar 17, 2026
4aa4a5f
Fix parameter passing and create pathological-context-bounds case
starswap Mar 18, 2026
d728284
Fix some bugs
starswap Mar 18, 2026
c13ec24
Also delete private members from inline traits in case they are marke…
starswap Mar 19, 2026
ae18157
Add dot product run test
starswap Mar 22, 2026
4a7e3bd
Add specialized-traits-inheritance.scala
starswap Mar 22, 2026
f038a32
Add inline-trait-private-evidence test
starswap Mar 22, 2026
4f39f0a
Uncontroversial bug fixes
starswap Mar 22, 2026
94dee85
Do transform nested inlines
starswap Mar 22, 2026
e5ff729
Allow inlining into inline traits (we prune out the definitions after…
starswap Mar 22, 2026
931b61e
Specialize member types after inlining (especially num evidence params)
starswap Mar 22, 2026
98b7dc6
Add some important TODO comments
starswap Mar 22, 2026
ab075b2
Make generated traits inline
starswap Mar 22, 2026
c4b1e8a
Add potential trait test
starswap Mar 22, 2026
ccc709a
Rename specialized-trait-vector-example to specialized-trait-collecti…
starswap Mar 22, 2026
1fc3b8e
Working up to benchmark but ugly
starswap Mar 22, 2026
eaa657c
Add inline traits desugar explanation doc
starswap Mar 22, 2026
070caea
Add todos
starswap Mar 22, 2026
a6e54bd
Add specialized traits md
starswap Mar 22, 2026
c857661
Replace manual benchmark with scala-cli --jmh compatible benchmark
starswap Mar 23, 2026
10b8d84
Move benchmark to a better location
starswap Mar 23, 2026
85aeeaf
Add run test which checks if correct method is called by reflection /…
starswap Mar 23, 2026
baf2e01
Move inline traits to run before specialized traits, loop specialized…
starswap Mar 25, 2026
e12b6a7
Update inline-traits.md
starswap Mar 25, 2026
6003015
Update specialize-traits.md to include an explanation of what we do w…
starswap Mar 25, 2026
69abd15
Fix some issues
starswap Mar 25, 2026
4f51988
Delete print
starswap Mar 26, 2026
1e60be5
Fix inline-trait-specialized-desugar.scala
starswap Mar 26, 2026
bdb5ddd
Get rid of specialized-traits-unspecialized.scala
starswap Mar 26, 2026
ee4eabb
Add test for inline trait name shadow behaviour
starswap Mar 26, 2026
25f9384
Insist on direct implementation for parameter passing, also for inlin…
starswap Mar 26, 2026
3ddb23e
Fix comment in benchmark file
starswap Mar 29, 2026
95b997a
Clean up benchmark
starswap Mar 30, 2026
24e3457
Make specialized traits experimental, using erasedDefs for Specialized
starswap Mar 30, 2026
511f730
Build new collections example from strawman
starswap Mar 30, 2026
f55b8d0
Allow specializations to match parent signatures in overriding methods
starswap Mar 30, 2026
57b5e38
Also inline interfaces in inline traits
starswap Mar 30, 2026
0137511
Specialize parents of inline traits, break out symbol replacement map…
starswap Mar 30, 2026
9fd8f5c
Enforce rules on inheritance from specialized traits
starswap Mar 30, 2026
86185a4
Homogenise test names
starswap Mar 30, 2026
836cf7d
Ban body classes in inline traits
starswap Mar 30, 2026
be7f701
Fix test warning
starswap Mar 30, 2026
b378cc3
Ban inner classes in inline traits
starswap Mar 30, 2026
0a812a9
Allow inline traits to override val params because we prune the param…
starswap Mar 30, 2026
340b6a3
Don't return inline trait val param bodies multiple times
starswap Mar 30, 2026
6144dbf
Add more name clash tests
starswap Mar 30, 2026
e03b995
Fix tests
starswap Mar 30, 2026
50c3237
Fix typo
starswap Mar 30, 2026
3113391
Add child and grandchild override case
starswap Mar 30, 2026
01c5c10
Update rules
starswap Mar 30, 2026
b0eb1bf
Fix test typo and delete duplicate test
starswap Mar 31, 2026
7282f6d
Properly delete privates when we prune inline traits
starswap Apr 13, 2026
b32bf3f
Implement banning body classes in inline traits
starswap Apr 13, 2026
70b17ff
Ban inlining of inline traits into classes defined inside inline traits
starswap Apr 13, 2026
a0b8f7d
Check all name clash cases
starswap Apr 13, 2026
76f04b7
Run transform recursively as we may need to inline inline traits into…
starswap Apr 13, 2026
a443c27
Tidy comments
starswap Apr 13, 2026
850b9a1
Specify error
starswap Apr 13, 2026
fcc0f1d
Update old test so doesn't break name clash rules
starswap Apr 13, 2026
2d13df4
Check for safe-init warning
starswap Apr 13, 2026
add1abb
Update specs
starswap Apr 13, 2026
24944f8
Make sure no spurious warn
starswap Apr 13, 2026
8d62780
Fix multiple files for inline traits by reading stats start earlier
starswap Apr 13, 2026
e1fc5fd
Deal with trait extends inline trait and vice versa
starswap Apr 13, 2026
b94370a
Merge branch 'main' into tmp/inline-traits
starswap Apr 13, 2026
8a81caa
Merge branch 'main' into tmp/inline-traits
starswap Apr 13, 2026
16f24b5
Don't hash referenced inline traits in SBT ExtractAPI
starswap Apr 14, 2026
e3e4c74
Add inline val to multiple stages generic defs
starswap Apr 14, 2026
d0ea6e3
Add inline-trait-multiple-stages-inline-traits
starswap Apr 14, 2026
bd64398
Merge branch 'tmp/inline-traits' of https://github.com/starswap/dotty…
starswap Apr 14, 2026
7060dbe
Homogenise test names
starswap Apr 14, 2026
963e1ed
Remove unnecessary comment
starswap Apr 14, 2026
4af61f3
Add coord and compilation unit info
starswap Apr 14, 2026
8fc1498
Remove comment
starswap Apr 14, 2026
08da50d
Build bridges for specialized traits
starswap Apr 14, 2026
d49054d
Fix docs
starswap Apr 14, 2026
f71f342
Revert "Allow specializations to match parent signatures in overridin…
starswap Apr 14, 2026
4b4bc5f
Test super call in inline trait transform
starswap Apr 15, 2026
7e4f439
Update version and comment for Benchmark
starswap Apr 17, 2026
adb7444
Create spec methods
starswap Apr 17, 2026
2a96a11
Inline nested inline traits calls correctly
starswap Apr 17, 2026
a86be36
Block cyclic inline trait inlining
starswap Apr 17, 2026
49b972e
Update spec
starswap Apr 17, 2026
4e6f680
Ban specialized trait not inline
starswap Apr 17, 2026
167ee4a
Fix indentation
starswap Apr 17, 2026
c29d4f0
Fix bugs with bridge method mapping
starswap Apr 19, 2026
7956e29
Fix bug with self-inlining of inline traits
starswap Apr 19, 2026
93188f3
Add specialized trait as val
starswap Apr 19, 2026
02735d7
Fix symbol mapping owner chain
starswap Apr 19, 2026
a816ba1
Fix var name
starswap Apr 19, 2026
79f02c5
Fix specialized trait as member val
starswap Apr 19, 2026
29061f5
Add and fix inline trait val def inner class inner class owners init
starswap Apr 19, 2026
f294569
Add and fix specialized-trait-anonymous-class-as-param
starswap Apr 19, 2026
5f88527
Add comment
starswap Apr 20, 2026
71791b7
Add old inline trait test
starswap Apr 20, 2026
e115e18
Add more inline-trait edge case tests
starswap Apr 20, 2026
df27cdd
Add var param clash cases
starswap Apr 20, 2026
117e94d
Add specialized-trait-requires-inline-trait-inlining.scala
starswap Apr 20, 2026
58c76d4
Add inline trait opaque type test case
starswap Apr 21, 2026
ce320bf
Allow inlining during desugarSpecializedTraits
starswap Apr 21, 2026
6589807
Add drops Specialized qualifier case
starswap Apr 21, 2026
ca1fc6d
Add specialized-trait-requires-inline-trait-inlining.scala
starswap Apr 21, 2026
d9275d2
Add more tests
starswap Apr 21, 2026
8c36495
Fix specialized trait with val param
starswap Apr 21, 2026
69b1822
Add specialized-trait-var-parameters
starswap Apr 21, 2026
1c25382
Fix symbol -> denot
starswap Apr 21, 2026
3258857
Switch to deleting Vec parent
starswap Apr 21, 2026
6c369ce
Ban Vec[?] when Specialized
starswap Apr 22, 2026
b6be527
Move comments
starswap Apr 22, 2026
1793a95
Explain removal of parent types
starswap Apr 22, 2026
7395c72
Check foo[S: Specialized] <= Vec[S: Specialized]
starswap Apr 22, 2026
82c1054
Don't warn for anonymous class inlining when it's a Specialized trait…
starswap Apr 22, 2026
e52001e
Fix syntax error in test
starswap Apr 22, 2026
85db37e
Make impl classes also pass Spec type params to parent sp classes; ev…
starswap Apr 22, 2026
4dcfd6b
Fix print and uncomment test
starswap Apr 22, 2026
f6dceb4
Fix self types and opaque types
starswap Apr 23, 2026
89f9e48
Add new line at end of file
starswap Apr 23, 2026
ca33ba6
Add another new line at end of file
starswap Apr 23, 2026
ab26f56
Fix inconsistency with override requriement between inline trait and …
starswap Apr 23, 2026
f54e694
Remove redundant doc
starswap Apr 23, 2026
41b0673
Fix super calls and deal with override conflict between parents; comm…
starswap Apr 24, 2026
3878e9e
Fix overrides nothing regresion
starswap Apr 27, 2026
e04a884
Fix inline trait super calls
starswap Apr 27, 2026
4b1491f
add another specialized trait case
starswap Apr 27, 2026
94d12b1
Make Specialized trait sealed
starswap Apr 27, 2026
cb779db
Add more test cases
starswap Apr 27, 2026
fa18e6f
Tidy up a bit
starswap Apr 28, 2026
fcbcfae
Add a couple more tests
starswap Apr 28, 2026
2461bd4
fix: Add missing flag
starswap Apr 29, 2026
f76526d
Add comment to benchmark
starswap Apr 29, 2026
430b646
Make sure RefChecks is actually fully after PruneInlineTraits
starswap May 3, 2026
02a4e56
Explicitly deal with retained inline methods in inline traits
starswap May 3, 2026
3fc202a
Add isSpecializedTrait
starswap May 3, 2026
003d28e
Add another illegal trait inlining cycle case
starswap May 3, 2026
9c8f2f8
Actually we do allow loops if the traits involved are specialized
starswap May 3, 2026
ce93c09
Break out loop checks
starswap May 3, 2026
e51284c
Specify rules for specialized trait extension, allowing object/class/…
starswap May 3, 2026
f10e40f
Switch from copying RHS type to our own specialized Numeric
starswap May 3, 2026
081b591
Fix partial parameter types for specialization
starswap May 5, 2026
16c6183
Add isSpecializedMethod
starswap May 5, 2026
b8f0731
Fix multiple parameter lists in specialized trait anonymous class ins…
starswap May 5, 2026
c2f6b1f
Fix unspecialized AppliedTypeTree bug
starswap May 5, 2026
29a4377
Add comment
starswap May 5, 2026
7ae1248
Support specialized trait inline "factory" methods
starswap May 5, 2026
d58145e
Switch vector dot product example to use factory method
starswap May 5, 2026
9b0d9de
Ban unsupported uses of Specialized
starswap May 6, 2026
e2a7e53
Add multiple stages specialized numeric case
starswap May 6, 2026
a5e23c6
Delete some dead code and comments
starswap May 6, 2026
bbaf754
Switch to identity denot transformer
starswap May 6, 2026
7a6dac1
Move transform functions outside of Transformer
starswap May 6, 2026
beed859
Share specialized trait cache between comp units in a run
starswap May 8, 2026
b2dc934
Fix outstanding bug due to putting types in a set in Specialization
starswap May 8, 2026
91ca6bb
Make two branches the same in transformStatements
starswap May 8, 2026
d041e88
Move transform functions outside of Transformer
starswap May 6, 2026
5adac5c
Save deftrees when copying symbols for ttmap
starswap May 8, 2026
a054958
Treat opaque types better based on standard approach
starswap May 8, 2026
a79100b
Fix coords in inline traits
starswap May 8, 2026
4212cec
Fix qualifier on select in replaceInlinedTraitSymbols
starswap May 8, 2026
52cb4e7
Fix param names in generated constructor
starswap May 8, 2026
8754ef9
Fix spans and coords in specialized traits
starswap May 8, 2026
7cf5ec5
Remove old comment
starswap May 8, 2026
17f8dbc
Fix positions and sources when prematurely inlining specialized inlin…
starswap May 8, 2026
95dfe2a
Process inline and specialized traits before pickling
starswap May 8, 2026
5d9b532
Add convenience toString method
starswap May 8, 2026
cac7520
Fix $ at end of name confuses class loader
starswap May 8, 2026
dcf7e42
Add specialized trait one parent is inline
starswap May 11, 2026
9fc6f8e
Add missing span / source file
starswap May 11, 2026
0046c0a
Special case treechecker for duplicate impl and sp classes as discuss…
starswap May 11, 2026
e950ecf
Add multiple files separate compilation units test
starswap May 11, 2026
f4f3b1f
Add specialized trait body macro
starswap May 11, 2026
388da41
Add specialized-trait-inline-specialized-instance
starswap May 11, 2026
2f6fb01
Fix collection of specializations as parent types
starswap May 11, 2026
f155e64
Add specialized-trait-list-of-specialized-trait.scala
starswap May 11, 2026
61b6d02
Add some more tests
starswap May 14, 2026
af08875
Stop using dollar signs in source in inline-trait-specialized-desugar
starswap May 16, 2026
f4dcfb0
Check info exists before pruning
starswap May 16, 2026
b1570f5
Add test for bug discovered in inlining
starswap May 16, 2026
f3cb5be
Add smaller version of tests/pos/specialized-trait-multiple-stages-sp…
starswap May 16, 2026
82240c9
Sharpen rules on inline vals and inline defs inside inline traits
starswap May 16, 2026
49ac34e
Fix inline-trait-y-equals-x-inlined-nowarn by special case in error r…
starswap May 16, 2026
fa0bb8b
Switch to using erasure for specialization and inline trait symbol re…
starswap May 16, 2026
2c2b6a0
Update comment
starswap May 16, 2026
25ad6b4
Specialized traits may not be extended by ordinary traits (they alway…
starswap May 25, 2026
6b7eed9
Fix object class bug manifesting across files
starswap May 25, 2026
a70eda5
Fix source file and spans for anonymous class instances
starswap May 25, 2026
b1b9f39
Support packages and objects containing specialized traits
starswap May 25, 2026
fd64930
Remove nasty gating and allow specializeInlineTraits to inline into B…
starswap May 25, 2026
b7cc899
Redo inline trait cycle check detection - catch previously missing ca…
starswap May 25, 2026
d2b0dee
Fix inline trait accesses parent val param
starswap May 25, 2026
db9a6a9
Do replaceInlineTraitSymbols by symbol lookup rather than manually ma…
starswap May 25, 2026
c593708
Fix erasure of class parents when these parents are specialized traits
starswap May 25, 2026
7903e82
Add tests for inlining a specialized instance across compilation units
starswap May 25, 2026
f6ac71a
Add explanatory comment
starswap May 25, 2026
b1faf9a
Add bridges for methods with specialized trait parameters; unlocks Ve…
starswap May 25, 2026
b0c46cc
Note a missing case
starswap May 25, 2026
80dfbdf
Do some docs updates
starswap May 25, 2026
edfa213
Merge branch 'main' into specialized-inline-traits
starswap May 25, 2026
e70887d
Merge remote-tracking branch 'scala3/main' into specialized-inline-tr…
starswap May 25, 2026
b99d58c
Move Specialized to own package to avoid conflict with specialized
starswap May 25, 2026
75c2a36
Fix inline-trait-self-type-problems to use inline traits
starswap May 26, 2026
2ec80bd
Support self types in specialized traits
starswap May 26, 2026
e9420de
Delete redundant old code
starswap May 26, 2026
f26cf2d
Add some specialized trait macro tests
starswap May 26, 2026
72efee1
Add opaque type tests for specialized traits
starswap May 26, 2026
44b4d74
Fix self type test error checking
starswap May 26, 2026
74d0e74
Fix caching issue with macros temporarily
starswap May 26, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
// Run with: scala-cli --power --jmh bench-micro/src/main/scala/dotty/tools/benchmarks/SpecializedTraitsBenchmark.scala
// May have to run it again / delete .scala-build and rerun if you get a class not found
// error from scala-cli first time - the --jmh flag is still experimental.
// Don't forget to publish the compiler first and check that the version below corresponds to the generated version,
// as well as to kill the bloop server if you are republishing the same version as before.
// scala-cli --power bloop exit

//> using scala 3.8.4-RC1-bin-SNAPSHOT-nonbootstrapped
//> using options -language:experimental.specializedTraits

package dotty.tools.benchmarks

import org.openjdk.jmh.annotations.*
import java.util.concurrent.TimeUnit

class VecManual(elems: Array[Int]):
private val num = summon[Numeric[Int]]

def length = elems.length

def apply(i: Int): Int = elems(i)

def scalarProduct(other: VecManual): Int =
require(this.length == other.length)
var result = num.fromInt(0)
for i <- 0 until length do
result = num.plus(result, num.times(this(i), other(i)))
result

class VecGeneric[T: Numeric](elems: Array[T]):
private val num = summon[Numeric[T]]

def length = elems.length

def apply(i: Int): T = elems(i)

def scalarProduct(other: VecGeneric[T]): T =
require(this.length == other.length)
var result = num.fromInt(0)
for i <- 0 until length do
result = num.plus(result, num.times(this(i), other(i)))
result

inline trait VecSpecialized[T: {Specialized, Numeric2}](elems: Array[T]):
private val num = summon[Numeric2[T]]

def length = elems.length

def apply(i: Int): T = elems(i)

def scalarProduct(other: VecSpecialized[T]): T =
require(this.length == other.length)
var result = num.fromInt(0)
for i <- 0 until length do
result = num.plus(result, num.times(this(i), other(i)))
result

@State(Scope.Benchmark)
class Arrays:
var arr1 = Array.fill(100_000_000) {math.round(math.random().floatValue * 4)}
var arr2 = Array.fill(100_000_000) {math.round(math.random().floatValue * 4)}
val target = arr1.zip(arr2).map((x, y) => x * y).fold(0)(_ + _)

@State(Scope.Benchmark)
@BenchmarkMode(Array(Mode.AverageTime))
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@Warmup(iterations = 5, time = 100, timeUnit = TimeUnit.MILLISECONDS)
@Measurement(iterations = 15, time = 100, timeUnit = TimeUnit.MILLISECONDS)
@Fork(1)
class VecBench:
@Benchmark
def manual(arr: Arrays) =
val x = VecManual(arr.arr1)
val y = VecManual(arr.arr2)
assert(x.scalarProduct(y) == arr.target)

@Benchmark
def generic(arr: Arrays) =
val x = VecGeneric[Int](arr.arr1)
val y = VecGeneric[Int](arr.arr2)
assert(x.scalarProduct(y) == arr.target)

@Benchmark
def specialized(arr: Arrays) =
val x = new VecSpecialized[Int](arr.arr1) {}
val y = new VecSpecialized[Int](arr.arr2) {}
assert(x.scalarProduct(y) == arr.target)

// You can really see the impact of Specialized on the interface usage here
// Remove Specialized and see that the generated code gets much more boxing and unboxing
// which slows it down substantially.
inline trait Numeric2[T: Specialized]:
def fromInt(x: Int): T
def plus(x: T, y: T): T
def times(x: T, y: T): T

implicit object IntIsIntegral extends Numeric2[Int]:
override def fromInt(x: Int): Int = x
override def plus(x: Int, y: Int): Int = x + y
override def times(x: Int, y: Int): Int = x * y
26 changes: 15 additions & 11 deletions compiler/src/dotty/tools/dotc/Compiler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,19 @@ class Compiler {
List(new UnrollDefinitions) :: // Unroll annotated methods if detected in PostTyper
List(new sjs.PrepJSInterop) :: // Additional checks and transformations for Scala.js (Scala.js only)
List(new SetRootTree) :: // Set the `rootTreeOrProvider` on class symbols
List(new DesugarSpecializedTraits) :: // Process Specialized traits
List(new SpecializeInlineTraits) :: // Inline the code of inline traits into their children
Nil

/** Phases dealing with TASTY tree pickling and unpickling */
protected def picklerPhases: List[List[Phase]] =
List(new Pickler) :: // Generate TASTY info
List(new sbt.ExtractAPI) :: // Sends a representation of the API of classes to sbt via callbacks
List(new Inlining) :: // Inline and execute macros
List(new PostInlining) :: // Add mirror support for inlined code
List(new Staging) :: // Check staging levels and heal staged types
List(new Splicing) :: // Replace level 1 splices with holes
List(new PickleQuotes) :: // Turn quoted trees into explicit run-time data structures
List(new Pickler) :: // Generate TASTY info
List(new sbt.ExtractAPI) :: // Sends a representation of the API of classes to sbt via callbacks
List(new Inlining) :: // Inline and execute macros
List(new PostInlining) :: // Add mirror support for inlined code
List(new Staging) :: // Check staging levels and heal staged types
List(new Splicing) :: // Replace level 1 splices with holes
List(new PickleQuotes) :: // Turn quoted trees into explicit run-time data structures
Nil

/** Phases dealing with the transformation from pickled trees to backend trees */
Expand All @@ -69,8 +71,9 @@ class Compiler {
new InlineVals, // Check right hand-sides of an `inline val`s
new ExpandSAMs, // Expand single abstract method closures to anonymous classes
new ElimRepeated, // Rewrite vararg parameters and arguments
new RefChecks, // Various checks mostly related to abstract members and overriding
new DropForMap) :: // Drop unused trailing map calls in for comprehensions
new DropForMap, // Drop unused trailing map calls in for comprehensions
new PruneSpecializedMethods) :: // Remove right-hand side of definitions in inline traits
List(new RefChecks) :: // Various checks mostly related to abstract members and overriding
List(new init.Checker) :: // Check initialization of objects
List(new ProtectedAccessors, // Add accessors for protected members
new ExtensionMethods, // Expand methods of value classes with extension methods
Expand All @@ -81,7 +84,8 @@ class Compiler {
new ForwardDepChecks, // Check that there are no forward references to local vals
new SpecializeApplyMethods, // Adds specialized methods to FunctionN
new TryCatchPatterns, // Compile cases in try/catch
new PatternMatcher) :: // Compile pattern matches
new PatternMatcher, // Compile pattern matches
new PruneInlineTraits) :: // Remove right-hand side of definitions in inline traits
List(new TestRecheck.Pre) :: // Test only: run rechecker, enabled under -Yrecheck-test
List(new TestRecheck) :: // Test only: run rechecker, enabled under -Yrecheck-test
List(new cc.Setup) :: // Preparations for check captures phase, enabled under captureChecking
Expand All @@ -94,7 +98,7 @@ class Compiler {
new ExplicitSelf, // Make references to non-trivial self types explicit as casts
new StringInterpolatorOpt, // Optimizes raw and s and f string interpolators by rewriting them to string concatenations or formats
new DropBreaks) :: // Optimize local Break throws by rewriting them
List(new PruneErasedDefs, // Make erased symbols private
List(new PruneErasedDefs, // Drop erased definitions from scopes and simplify erased expressions
new UninitializedDefs, // Replaces `compiletime.uninitialized` by `_`
new InlinePatterns, // Remove placeholders of inlined patterns
new VCInlineMethods, // Inlines calls to value class methods
Expand Down
7 changes: 4 additions & 3 deletions compiler/src/dotty/tools/dotc/ast/TreeTypeMap.scala
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ class TreeTypeMap(

override def transform(tree: Tree)(using Context): Tree = treeMap(tree) match {
case impl @ Template(constr, _, self, _) =>
val tmap = withMappedSyms(localSyms(impl :: self :: Nil))
val tmap = withMappedSyms(localSyms(impl :: self :: Nil))
cpy.Template(impl)(
constr = tmap.transformSub(constr),
parents = impl.parents.mapconserve(transform),
Expand Down Expand Up @@ -127,14 +127,15 @@ class TreeTypeMap(
cpy.Block(blk)(stats1, expr1)
case lit @ Literal(Constant(tpe: Type)) =>
cpy.Literal(lit)(Constant(mapType(tpe)))
case ddef @ DefDef(name, paramss, tpt, _) =>
case ddef @ DefDef(name, paramss, tpt, _) => // Why are we not correctly mapping foo's return type? See Reached def def ...
val (tmap1, paramss1) = transformAllParamss(paramss)
val res = cpy.DefDef(ddef)(name, paramss1, tmap1.transform(tpt), tmap1.transform(ddef.rhs))
res.symbol.setParamssFromDefs(paramss1)
res.symbol.transformAnnotations {
case ann: BodyAnnotation => ann.derivedAnnotation(transform(ann.tree))
case ann => ann
}
}
// HERE?
res
case tdef @ LambdaTypeTree(tparams, body) =>
val (tmap1, tparams1) = transformDefs(tparams)
Expand Down
2 changes: 2 additions & 0 deletions compiler/src/dotty/tools/dotc/config/Feature.scala
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ object Feature:

val dependent = experimental("dependent")
val erasedDefinitions = experimental("erasedDefinitions")
val specializedTraits = experimental("specializedTraits")
val strictEqualityPatternMatching = experimental("strictEqualityPatternMatching")
val symbolLiterals = deprecated("symbolLiterals")
val saferExceptions = experimental("saferExceptions")
Expand Down Expand Up @@ -68,6 +69,7 @@ object Feature:
(scala2macros, "Allow Scala 2 macros"),
(dependent, "Allow dependent method types"),
(erasedDefinitions, "Allow erased definitions"),
(specializedTraits, "Allow specialized traits"),
(strictEqualityPatternMatching, "relaxed CanEqual checks for ADT pattern matching"),
(symbolLiterals, "Allow symbol literals"),
(saferExceptions, "Enable safer exceptions"),
Expand Down
26 changes: 26 additions & 0 deletions compiler/src/dotty/tools/dotc/core/Contexts.scala
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ import java.util.concurrent.atomic.AtomicInteger
import java.nio.file.InvalidPathException
import dotty.tools.dotc.coverage.Coverage
import scala.annotation.tailrec
import dotty.tools.dotc.inlines.Inlines.InlineTraitState
import dotty.tools.dotc.transform.SpecializedTraitState

object Contexts {

Expand Down Expand Up @@ -147,6 +149,8 @@ object Contexts {
def typerState: TyperState
def gadt: GadtConstraint = gadtState.gadt
def gadtState: GadtState
def inlineTraitState: InlineTraitState
def specializedTraitState: SpecializedTraitState
def searchHistory: SearchHistory
def source: SourceFile

Expand Down Expand Up @@ -437,6 +441,8 @@ object Contexts {
superOrThisCallContext(owner, constrCtx.scope)
.setTyperState(typerState)
.setGadtState(gadtState)
.setInlineTraitState(inlineTraitState)
.setSpecializedTraitState(specializedTraitState)
.fresh
.setScope(this.scope)
}
Expand Down Expand Up @@ -604,6 +610,12 @@ object Contexts {

private var _gadtState: GadtState = uninitialized
final def gadtState: GadtState = _gadtState

private var _inlineTraitState: InlineTraitState = uninitialized
final def inlineTraitState: InlineTraitState = _inlineTraitState

private var _specializedTraitState: SpecializedTraitState = uninitialized
final def specializedTraitState: SpecializedTraitState = _specializedTraitState

private var _searchHistory: SearchHistory = uninitialized
final def searchHistory: SearchHistory = _searchHistory
Expand All @@ -629,6 +641,8 @@ object Contexts {
_tree = origin.tree
_scope = origin.scope
_gadtState = origin.gadtState
_inlineTraitState = origin.inlineTraitState
_specializedTraitState = origin.specializedTraitState
_searchHistory = origin.searchHistory
_source = origin.source
_moreProperties = origin.moreProperties
Expand Down Expand Up @@ -692,6 +706,16 @@ object Contexts {
def setFreshGADTBounds: this.type =
setGadtState(gadtState.fresh)

def setInlineTraitState(inlineTraitState: InlineTraitState): this.type =
util.Stats.record("Context.setInlineTraitState")
this._inlineTraitState = inlineTraitState
this

def setSpecializedTraitState(specializedTraitState: SpecializedTraitState): this.type =
util.Stats.record("Context.setSpecializedTraitState")
this._specializedTraitState = specializedTraitState
this

def setSearchHistory(searchHistory: SearchHistory): this.type =
util.Stats.record("Context.setSearchHistory")
this._searchHistory = searchHistory
Expand Down Expand Up @@ -786,6 +810,8 @@ object Contexts {
.updated(profilerLoc, Profiler.NoOp)
c._searchHistory = new SearchRoot
c._gadtState = GadtState(GadtConstraint.empty)
c._inlineTraitState = InlineTraitState()
c._specializedTraitState = SpecializedTraitState()
c
end FreshContext

Expand Down
12 changes: 10 additions & 2 deletions compiler/src/dotty/tools/dotc/core/Definitions.scala
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@ class Definitions {
@tu lazy val ScalaCollectionImmutablePackageClass: ClassSymbol = requiredPackage("scala.collection.immutable").moduleClass.asClass
@tu lazy val ScalaMathPackageClass: ClassSymbol = requiredPackage("scala.math").moduleClass.asClass
@tu lazy val ScalaUtilPackageClass: ClassSymbol = requiredPackage("scala.util").moduleClass.asClass
@tu lazy val ScalaSpecializePackageVal: TermSymbol = requiredPackage("scala.specialize")

// fundamental modules
@tu lazy val SysPackage : Symbol = requiredModule("scala.sys.package")
Expand Down Expand Up @@ -793,6 +794,10 @@ class Definitions {
@tu lazy val StringAddClass : ClassSymbol = requiredClass("scala.runtime.StringAdd")
@tu lazy val StringAdd_+ : Symbol = StringAddClass.requiredMethod(nme.raw.PLUS)

@tu lazy val SpecializedClass : ClassSymbol = requiredClass("scala.specialize.Specialized")
@tu lazy val SpecializedModule: Symbol = SpecializedClass.companionModule
@tu lazy val SpecializedModule_apply: Symbol = SpecializedModule.requiredMethod(nme.apply)

@tu lazy val StringContextClass: ClassSymbol = requiredClass("scala.StringContext")
@tu lazy val StringContext_s : Symbol = StringContextClass.requiredMethod(nme.s)
@tu lazy val StringContext_raw: Symbol = StringContextClass.requiredMethod(nme.raw_)
Expand Down Expand Up @@ -1734,6 +1739,9 @@ class Definitions {
private val PredefImportFns: RootRef =
RootRef(() => ScalaPredefModule.termRef, isPredef=true)

private val SpecializeImportFns: RootRef = // TODO: Find a solution to importing in scala package without conflict with original specialized.
RootRef(() => ScalaSpecializePackageVal.termRef)

@tu private lazy val YimportsImportFns: List[RootRef] = ctx.settings.Yimports.value.map { name =>
val denot =
getModuleIfDefined(name).suchThat(_.is(Module)) `orElse`
Expand All @@ -1749,8 +1757,8 @@ class Definitions {
@tu private lazy val ScalaRootImportFns: List[RootRef] =
if !ctx.settings.Yimports.isDefault then YimportsImportFns
else if ctx.settings.YnoImports.value then Nil
else if ctx.settings.YnoPredef.value then ScalaImportFns
else ScalaImportFns :+ PredefImportFns
else if ctx.settings.YnoPredef.value then ScalaImportFns :+ SpecializeImportFns
else ScalaImportFns :+ SpecializeImportFns :+ PredefImportFns

@tu private lazy val JavaRootImportTypes: List[TermRef] = JavaRootImportFns.map(_.refFn())
@tu private lazy val ScalaRootImportTypes: List[TermRef] = ScalaRootImportFns.map(_.refFn())
Expand Down
5 changes: 3 additions & 2 deletions compiler/src/dotty/tools/dotc/core/Flags.scala
Original file line number Diff line number Diff line change
Expand Up @@ -453,13 +453,13 @@ object Flags {

/** Flags representing source modifiers */
private val CommonSourceModifierFlags: FlagSet =
commonFlags(Private, Protected, Final, Case, Implicit, Given, Override, JavaStatic, Transparent, Erased)
commonFlags(Private, Protected, Final, Case, Implicit, Given, Override, JavaStatic, Transparent, Erased, Inline)

val TypeSourceModifierFlags: FlagSet =
CommonSourceModifierFlags.toTypeFlags | Abstract | Sealed | Opaque | Open | Into

val TermSourceModifierFlags: FlagSet =
CommonSourceModifierFlags.toTermFlags | Inline | AbsOverride | Lazy | Tracked
CommonSourceModifierFlags.toTermFlags | AbsOverride | Lazy | Tracked

/** Flags representing modifiers that can appear in trees */
val ModifierFlags: FlagSet =
Expand Down Expand Up @@ -592,6 +592,7 @@ object Flags {
val InlineOrProxy: FlagSet = Inline | InlineProxy // An inline method or inline argument proxy */
val InlineMethod: FlagSet = Inline | Method
val InlineImplicitMethod: FlagSet = Implicit | InlineMethod
val InlineTrait: FlagSet = Inline | Trait
val InlineParam: FlagSet = Inline | Param
val InlineByNameProxy: FlagSet = InlineProxy | Method
val JavaEnum: FlagSet = JavaDefined | Enum // A Java enum trait
Expand Down
2 changes: 2 additions & 0 deletions compiler/src/dotty/tools/dotc/core/NameOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ object NameOps {
def isAnonymousFunctionName: Boolean = name.startsWith(str.ANON_FUN)
def isUnapplyName: Boolean = name == nme.unapply || name == nme.unapplySeq
def isRightAssocOperatorName: Boolean = name.lastPart.last == ':'
def isSpecializedTraitInterfaceName: Boolean = name.toString.contains(str.SPECIALIZED_TRAIT_SUFFIX)
def isSpecializedTraitImplementationName: Boolean = name.toString.contains(str.SPECIALIZED_TRAIT_IMPL_SUFFIX)

/** Does this name match `[{letter | digit} '_'] op`?
*
Expand Down
8 changes: 8 additions & 0 deletions compiler/src/dotty/tools/dotc/core/Phases.scala
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,8 @@ object Phases {
private var mySbtExtractAPIPhase: Phase = uninitialized
private var myPicklerPhase: Phase = uninitialized
private var mySetRootTreePhase: Phase = uninitialized
private var mySpecializeInlineTraitsPhase: Phase = uninitialized
private var myDesugarSpecializedTraitsPhase: Phase = uninitialized
private var myInliningPhase: Phase = uninitialized
private var myStagingPhase: Phase = uninitialized
private var mySplicingPhase: Phase = uninitialized
Expand Down Expand Up @@ -266,6 +268,8 @@ object Phases {
final def sbtExtractAPIPhase: Phase = mySbtExtractAPIPhase
final def picklerPhase: Phase = myPicklerPhase
final def setRootTreePhase: Phase = mySetRootTreePhase
final def specializeInlineTraitsPhase: Phase = mySpecializeInlineTraitsPhase
final def desugarSpecializedTraitsPhase: Phase = myDesugarSpecializedTraitsPhase
final def inliningPhase: Phase = myInliningPhase
final def stagingPhase: Phase = myStagingPhase
final def splicingPhase: Phase = mySplicingPhase
Expand Down Expand Up @@ -298,6 +302,8 @@ object Phases {
mySbtExtractAPIPhase = phaseOfClass(classOf[sbt.ExtractAPI])
mySetRootTreePhase = phaseOfClass(classOf[SetRootTree])
myPicklerPhase = phaseOfClass(classOf[Pickler])
mySpecializeInlineTraitsPhase = phaseOfClass(classOf[SpecializeInlineTraits])
myDesugarSpecializedTraitsPhase = phaseOfClass(classOf[DesugarSpecializedTraits])
myInliningPhase = phaseOfClass(classOf[Inlining])
myStagingPhase = phaseOfClass(classOf[Staging])
mySplicingPhase = phaseOfClass(classOf[Splicing])
Expand Down Expand Up @@ -560,6 +566,8 @@ object Phases {
def sbtExtractDependenciesPhase(using Context): Phase = ctx.base.sbtExtractDependenciesPhase
def sbtExtractAPIPhase(using Context): Phase = ctx.base.sbtExtractAPIPhase
def picklerPhase(using Context): Phase = ctx.base.picklerPhase
def specializeInlineTraitsPhase(using Context): Phase = ctx.base.specializeInlineTraitsPhase
def desugarSpecializedTraitsPhase(using Context): Phase = ctx.base.desugarSpecializedTraitsPhase
def inliningPhase(using Context): Phase = ctx.base.inliningPhase
def stagingPhase(using Context): Phase = ctx.base.stagingPhase
def splicingPhase(using Context): Phase = ctx.base.splicingPhase
Expand Down
Loading
Loading