Skip to content

Commit 7356a2c

Browse files
Merge branch 'main' into feature/preview
2 parents 12526fb + 4dc4668 commit 7356a2c

File tree

326 files changed

+5873
-1847
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

326 files changed

+5873
-1847
lines changed

.github/workflows/ci.yaml

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -630,7 +630,10 @@ jobs:
630630
- ${{ github.workspace }}/../../cache/general:/root/.cache
631631
strategy:
632632
matrix:
633-
branch: [main, lts-3.3]
633+
series: [
634+
{repository: scala/scala3, branch: main}, # Scala Next nightly
635+
{repository: scala/scala3-lts, branch: lts-3.3} # Scala LTS nightly
636+
]
634637
needs: [test_non_bootstrapped, test, mima, community_build_a, community_build_b, community_build_c, test_sbt, test_java8]
635638
if: "(github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') && github.repository == 'scala/scala3'"
636639
env:
@@ -660,7 +663,8 @@ jobs:
660663
- name: Git Checkout
661664
uses: actions/checkout@v4
662665
with:
663-
ref: ${{ matrix.branch }}
666+
repository: ${{ matrix.series.repository }}
667+
ref: ${{ matrix.series.branch }}
664668

665669
- name: Add SBT proxy repositories
666670
run: cp -vf .github/workflows/repositories /root/.sbt/ ; true
@@ -832,7 +836,7 @@ jobs:
832836
sha256sum "${msiInstaller}" > "${msiInstaller}.sha256"
833837
834838
- name: Install GH CLI
835-
uses: dev-hanz-ops/[email protected].0
839+
uses: dev-hanz-ops/[email protected].1
836840
with:
837841
gh-cli-version: 2.59.0
838842

.github/workflows/lts-backport.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ jobs:
1515
with:
1616
fetch-depth: 0
1717
- uses: coursier/cache-action@v6
18-
- uses: VirtusLab/[email protected].1
18+
- uses: VirtusLab/[email protected].2
1919
- run: scala-cli ./project/scripts/addToBackportingProject.scala -- ${{ github.sha }}
2020
env:
2121
GRAPHQL_API_TOKEN: ${{ secrets.GRAPHQL_API_TOKEN }}

.github/workflows/spec.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ jobs:
4949
env:
5050
USER_FOR_TEST: ${{ secrets.SPEC_DEPLOY_USER }}
5151
if: ${{ env.USER_FOR_TEST != '' }}
52-
uses: burnett01/[email protected].1
52+
uses: burnett01/[email protected].2
5353
with:
5454
switches: -rzv
5555
path: docs/_spec/_site/

compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -818,7 +818,7 @@ trait BCodeSkelBuilder extends BCodeHelpers {
818818

819819
methSymbol = dd.symbol
820820
jMethodName = methSymbol.javaSimpleName
821-
returnType = asmMethodType(dd.symbol).returnType
821+
returnType = asmMethodType(methSymbol).returnType
822822
isMethSymStaticCtor = methSymbol.isStaticConstructor
823823

824824
resetMethodBookkeeping(dd)
@@ -915,7 +915,7 @@ trait BCodeSkelBuilder extends BCodeHelpers {
915915
for (p <- params) { emitLocalVarScope(p.symbol, veryFirstProgramPoint, onePastLastProgramPoint, force = true) }
916916
}
917917

918-
if (isMethSymStaticCtor) { appendToStaticCtor(dd) }
918+
if (isMethSymStaticCtor) { appendToStaticCtor() }
919919
} // end of emitNormalMethodBody()
920920

921921
lineNumber(rhs)
@@ -936,7 +936,7 @@ trait BCodeSkelBuilder extends BCodeHelpers {
936936
*
937937
* TODO document, explain interplay with `fabricateStaticInitAndroid()`
938938
*/
939-
private def appendToStaticCtor(dd: DefDef): Unit = {
939+
private def appendToStaticCtor(): Unit = {
940940

941941
def insertBefore(
942942
location: asm.tree.AbstractInsnNode,

compiler/src/dotty/tools/backend/jvm/ClassfileWriters.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ import java.util.zip.{CRC32, Deflater, ZipEntry, ZipOutputStream}
1212

1313
import dotty.tools.dotc.core.Contexts.*
1414
import dotty.tools.dotc.core.Decorators.em
15+
import dotty.tools.dotc.util.chaining.*
1516
import dotty.tools.io.{AbstractFile, PlainFile, VirtualFile}
1617
import dotty.tools.io.PlainFile.toPlainFile
1718
import BTypes.InternalName
18-
import scala.util.chaining.*
1919
import dotty.tools.io.JarArchive
2020

2121
import scala.language.unsafeNulls

compiler/src/dotty/tools/dotc/Compiler.scala

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,8 @@ import typer.{TyperPhase, RefChecks}
77
import parsing.Parser
88
import Phases.Phase
99
import transform.*
10-
import dotty.tools.backend
1110
import backend.jvm.{CollectSuperCalls, GenBCode}
12-
import localopt.StringInterpolatorOpt
11+
import localopt.{StringInterpolatorOpt, DropForMap}
1312

1413
/** The central class of the dotc compiler. The job of a compiler is to create
1514
* runs, which process given `phases` in a given `rootContext`.
@@ -34,8 +33,7 @@ class Compiler {
3433
protected def frontendPhases: List[List[Phase]] =
3534
List(new Parser) :: // Compiler frontend: scanner, parser
3635
List(new TyperPhase) :: // Compiler frontend: namer, typer
37-
List(new CheckUnused.PostTyper) :: // Check for unused elements
38-
List(new CheckShadowing) :: // Check shadowing elements
36+
List(CheckUnused.PostTyper(), CheckShadowing()) :: // Check for unused, shadowed elements
3937
List(new YCheckPositions) :: // YCheck positions
4038
List(new sbt.ExtractDependencies) :: // Sends information on classes' dependencies to sbt via callbacks
4139
List(new semanticdb.ExtractSemanticDB.ExtractSemanticInfo) :: // Extract info into .semanticdb files
@@ -51,10 +49,10 @@ class Compiler {
5149
List(new sbt.ExtractAPI) :: // Sends a representation of the API of classes to sbt via callbacks
5250
List(new Inlining) :: // Inline and execute macros
5351
List(new PostInlining) :: // Add mirror support for inlined code
54-
List(new CheckUnused.PostInlining) :: // Check for unused elements
5552
List(new Staging) :: // Check staging levels and heal staged types
5653
List(new Splicing) :: // Replace level 1 splices with holes
5754
List(new PickleQuotes) :: // Turn quoted trees into explicit run-time data structures
55+
List(new CheckUnused.PostInlining) :: // Check for unused elements
5856
Nil
5957

6058
/** Phases dealing with the transformation from pickled trees to backend trees */
@@ -70,7 +68,8 @@ class Compiler {
7068
new InlineVals, // Check right hand-sides of an `inline val`s
7169
new ExpandSAMs, // Expand single abstract method closures to anonymous classes
7270
new ElimRepeated, // Rewrite vararg parameters and arguments
73-
new RefChecks) :: // Various checks mostly related to abstract members and overriding
71+
new RefChecks, // Various checks mostly related to abstract members and overriding
72+
new DropForMap) :: // Drop unused trailing map calls in for comprehensions
7473
List(new semanticdb.ExtractSemanticDB.AppendDiagnostics) :: // Attach warnings to extracted SemanticDB and write to .semanticdb file
7574
List(new init.Checker) :: // Check initialization of objects
7675
List(new ProtectedAccessors, // Add accessors for protected members

compiler/src/dotty/tools/dotc/Run.scala

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import Run.Progress
3838
import scala.compiletime.uninitialized
3939
import dotty.tools.dotc.transform.MegaPhase
4040
import dotty.tools.dotc.transform.Pickler.AsyncTastyHolder
41+
import java.util.{Timer, TimerTask}
4142

4243
/** A compiler run. Exports various methods to compile source files */
4344
class Run(comp: Compiler, ictx: Context) extends ImplicitRunInfo with ConstraintRunInfo {
@@ -382,7 +383,7 @@ class Run(comp: Compiler, ictx: Context) extends ImplicitRunInfo with Constraint
382383
initializeAsyncTasty()
383384
else () => {}
384385

385-
runPhases(allPhases = fusedPhases)(using runCtx)
386+
showProgress(runPhases(allPhases = fusedPhases)(using runCtx))
386387
cancelAsyncTasty()
387388

388389
ctx.reporter.finalizeReporting()
@@ -433,6 +434,26 @@ class Run(comp: Compiler, ictx: Context) extends ImplicitRunInfo with Constraint
433434
process()(using unitCtx)
434435
}
435436

437+
/** If set to true, prints every 10 seconds the files currently being compiled.
438+
* Turn this flag on if you want to find out which test among many takes more time
439+
* to compile than the others or causes an infinite loop in the compiler.
440+
*/
441+
private inline val debugPrintProgress = false
442+
443+
/** Period between progress reports, in ms */
444+
private inline val printProgressPeriod = 10000
445+
446+
/** Shows progress if debugPrintProgress is true */
447+
private def showProgress(proc: => Unit)(using Context): Unit =
448+
if !debugPrintProgress then proc
449+
else
450+
val watchdog = new TimerTask:
451+
def run() = println(i"[compiling $units]")
452+
try
453+
new Timer().schedule(watchdog, printProgressPeriod, printProgressPeriod)
454+
proc
455+
finally watchdog.cancel()
456+
436457
private sealed trait PrintedTree
437458
private /*final*/ case class SomePrintedTree(phase: String, tree: String) extends PrintedTree
438459
private object NoPrintedTree extends PrintedTree

compiler/src/dotty/tools/dotc/ast/Desugar.scala

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,14 @@ object desugar {
4747
*/
4848
val UntupledParam: Property.Key[Unit] = Property.StickyKey()
4949

50+
/** An attachment key to indicate that a ValDef originated from a pattern.
51+
*/
52+
val PatternVar: Property.Key[Unit] = Property.StickyKey()
53+
54+
/** An attachment key for Trees originating in for-comprehension, such as tupling of assignments.
55+
*/
56+
val ForArtifact: Property.Key[Unit] = Property.StickyKey()
57+
5058
/** An attachment key to indicate that a ValDef is an evidence parameter
5159
* for a context bound.
5260
*/
@@ -56,6 +64,11 @@ object desugar {
5664
*/
5765
val PolyFunctionApply: Property.Key[Unit] = Property.StickyKey()
5866

67+
/** An attachment key to indicate that an Apply is created as a last `map`
68+
* scall in a for-comprehension.
69+
*/
70+
val TrailingForMap: Property.Key[Unit] = Property.StickyKey()
71+
5972
/** What static check should be applied to a Match? */
6073
enum MatchCheck {
6174
case None, Exhaustive, IrrefutablePatDef, IrrefutableGenFrom
@@ -410,6 +423,7 @@ object desugar {
410423
.withMods(Modifiers(
411424
meth.mods.flags & (AccessFlags | Synthetic) | (vparam.mods.flags & Inline),
412425
meth.mods.privateWithin))
426+
.withSpan(vparam.rhs.span)
413427
val rest = defaultGetters(vparams :: paramss1, n + 1)
414428
if vparam.rhs.isEmpty then rest else defaultGetter :: rest
415429
case _ :: paramss1 => // skip empty parameter lists and type parameters
@@ -859,7 +873,7 @@ object desugar {
859873
val nu = vparamss.foldLeft(makeNew(classTypeRef)) { (nu, vparams) =>
860874
val app = Apply(nu, vparams.map(refOfDef))
861875
vparams match {
862-
case vparam :: _ if vparam.mods.is(Given) || vparam.name.is(ContextBoundParamName) =>
876+
case vparam :: _ if vparam.mods.isOneOf(GivenOrImplicit) || vparam.name.is(ContextBoundParamName) =>
863877
app.setApplyKind(ApplyKind.Using)
864878
case _ => app
865879
}
@@ -1507,7 +1521,7 @@ object desugar {
15071521
val matchExpr =
15081522
if (tupleOptimizable) rhs
15091523
else
1510-
val caseDef = CaseDef(pat, EmptyTree, makeTuple(ids))
1524+
val caseDef = CaseDef(pat, EmptyTree, makeTuple(ids).withAttachment(ForArtifact, ()))
15111525
Match(makeSelector(rhs, MatchCheck.IrrefutablePatDef), caseDef :: Nil)
15121526
vars match {
15131527
case Nil if !mods.is(Lazy) =>
@@ -1537,6 +1551,7 @@ object desugar {
15371551
ValDef(named.name.asTermName, tpt, selector(n))
15381552
.withMods(mods)
15391553
.withSpan(named.span)
1554+
.withAttachment(PatternVar, ())
15401555
)
15411556
flatTree(firstDef :: restDefs)
15421557
}
@@ -1922,6 +1937,7 @@ object desugar {
19221937
val vdef = ValDef(named.name.asTermName, tpt, rhs)
19231938
.withMods(mods)
19241939
.withSpan(original.span.withPoint(named.span.start))
1940+
.withAttachment(PatternVar, ())
19251941
val mayNeedSetter = valDef(vdef)
19261942
mayNeedSetter
19271943
}
@@ -1956,14 +1972,8 @@ object desugar {
19561972
*
19571973
* 3.
19581974
*
1959-
* for (P <- G) yield P ==> G
1960-
*
1961-
* If betterFors is enabled, P is a variable or a tuple of variables and G is not a withFilter.
1962-
*
19631975
* for (P <- G) yield E ==> G.map (P => E)
19641976
*
1965-
* Otherwise
1966-
*
19671977
* 4.
19681978
*
19691979
* for (P_1 <- G_1; P_2 <- G_2; ...) ...
@@ -2136,14 +2146,20 @@ object desugar {
21362146
case (Tuple(ts1), Tuple(ts2)) => ts1.corresponds(ts2)(deepEquals)
21372147
case _ => false
21382148

2149+
def markTrailingMap(aply: Apply, gen: GenFrom, selectName: TermName): Unit =
2150+
if betterForsEnabled
2151+
&& selectName == mapName
2152+
&& gen.checkMode != GenCheckMode.Filtered // results of withFilter have the wrong type
2153+
&& (deepEquals(gen.pat, body) || deepEquals(body, Tuple(Nil)))
2154+
then
2155+
aply.putAttachment(TrailingForMap, ())
2156+
21392157
enums match {
21402158
case Nil if betterForsEnabled => body
21412159
case (gen: GenFrom) :: Nil =>
2142-
if betterForsEnabled
2143-
&& gen.checkMode != GenCheckMode.Filtered // results of withFilter have the wrong type
2144-
&& deepEquals(gen.pat, body)
2145-
then gen.expr // avoid a redundant map with identity
2146-
else Apply(rhsSelect(gen, mapName), makeLambda(gen, body))
2160+
val aply = Apply(rhsSelect(gen, mapName), makeLambda(gen, body))
2161+
markTrailingMap(aply, gen, mapName)
2162+
aply
21472163
case (gen: GenFrom) :: (rest @ (GenFrom(_, _, _) :: _)) =>
21482164
val cont = makeFor(mapName, flatMapName, rest, body)
21492165
Apply(rhsSelect(gen, flatMapName), makeLambda(gen, cont))
@@ -2154,7 +2170,9 @@ object desugar {
21542170
val selectName =
21552171
if rest.exists(_.isInstanceOf[GenFrom]) then flatMapName
21562172
else mapName
2157-
Apply(rhsSelect(gen, selectName), makeLambda(gen, cont))
2173+
val aply = Apply(rhsSelect(gen, selectName), makeLambda(gen, cont))
2174+
markTrailingMap(aply, gen, selectName)
2175+
aply
21582176
case (gen: GenFrom) :: (rest @ GenAlias(_, _) :: _) =>
21592177
val (valeqs, rest1) = rest.span(_.isInstanceOf[GenAlias])
21602178
val pats = valeqs map { case GenAlias(pat, _) => pat }
@@ -2167,7 +2185,7 @@ object desugar {
21672185
case _ => Modifiers()
21682186
makePatDef(valeq, mods, defpat, rhs)
21692187
}
2170-
val rhs1 = makeFor(nme.map, nme.flatMap, GenFrom(defpat0, gen.expr, gen.checkMode) :: Nil, Block(pdefs, makeTuple(id0 :: ids)))
2188+
val rhs1 = makeFor(nme.map, nme.flatMap, GenFrom(defpat0, gen.expr, gen.checkMode) :: Nil, Block(pdefs, makeTuple(id0 :: ids).withAttachment(ForArtifact, ())))
21712189
val allpats = gen.pat :: pats
21722190
val vfrom1 = GenFrom(makeTuple(allpats), rhs1, GenCheckMode.Ignore)
21732191
makeFor(mapName, flatMapName, vfrom1 :: rest1, body)

compiler/src/dotty/tools/dotc/ast/MainProxies.scala

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -98,17 +98,17 @@ object MainProxies {
9898
val body = Try(call, handler :: Nil, EmptyTree)
9999
val mainArg = ValDef(nme.args, TypeTree(defn.ArrayType.appliedTo(defn.StringType)), EmptyTree)
100100
.withFlags(Param)
101-
/** Replace typed `Ident`s that have been typed with a TypeSplice with the reference to the symbol.
102-
* The annotations will be retype-checked in another scope that may not have the same imports.
101+
102+
/** This context is used to create the `TypeSplices` wrapping annotations
103+
* below. These should have `mainFun` as their owner (and not the
104+
* enclosing package class that we would get otherwise) so that
105+
* subsequent owner changes (for example in `Typer.typedTypedSplice`) are
106+
* correct. See #22364 and associated tests.
103107
*/
104-
def insertTypeSplices = new TreeMap {
105-
override def transform(tree: Tree)(using Context): Tree = tree match
106-
case tree: tpd.Ident @unchecked => TypedSplice(tree)
107-
case tree => super.transform(tree)
108-
}
108+
val annotsCtx = ctx.fresh.setOwner(mainFun)
109109
val annots = mainFun.annotations
110110
.filterNot(_.matches(defn.MainAnnot))
111-
.map(annot => insertTypeSplices.transform(annot.tree))
111+
.map(annot => TypedSplice(annot.tree)(using annotsCtx))
112112
val mainMeth = DefDef(nme.main, (mainArg :: Nil) :: Nil, TypeTree(defn.UnitType), body)
113113
.withFlags(JavaStatic | Synthetic)
114114
.withAnnotations(annots)

0 commit comments

Comments
 (0)