Skip to content

Commit

Permalink
Merge branch 'main' into feature/preview
Browse files Browse the repository at this point in the history
  • Loading branch information
WojciechMazur authored Feb 22, 2025
2 parents 12526fb + 4dc4668 commit 7356a2c
Show file tree
Hide file tree
Showing 326 changed files with 5,873 additions and 1,847 deletions.
10 changes: 7 additions & 3 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -630,7 +630,10 @@ jobs:
- ${{ github.workspace }}/../../cache/general:/root/.cache
strategy:
matrix:
branch: [main, lts-3.3]
series: [
{repository: scala/scala3, branch: main}, # Scala Next nightly
{repository: scala/scala3-lts, branch: lts-3.3} # Scala LTS nightly
]
needs: [test_non_bootstrapped, test, mima, community_build_a, community_build_b, community_build_c, test_sbt, test_java8]
if: "(github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') && github.repository == 'scala/scala3'"
env:
Expand Down Expand Up @@ -660,7 +663,8 @@ jobs:
- name: Git Checkout
uses: actions/checkout@v4
with:
ref: ${{ matrix.branch }}
repository: ${{ matrix.series.repository }}
ref: ${{ matrix.series.branch }}

- name: Add SBT proxy repositories
run: cp -vf .github/workflows/repositories /root/.sbt/ ; true
Expand Down Expand Up @@ -832,7 +836,7 @@ jobs:
sha256sum "${msiInstaller}" > "${msiInstaller}.sha256"
- name: Install GH CLI
uses: dev-hanz-ops/[email protected].0
uses: dev-hanz-ops/[email protected].1
with:
gh-cli-version: 2.59.0

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/lts-backport.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
with:
fetch-depth: 0
- uses: coursier/cache-action@v6
- uses: VirtusLab/[email protected].1
- uses: VirtusLab/[email protected].2
- run: scala-cli ./project/scripts/addToBackportingProject.scala -- ${{ github.sha }}
env:
GRAPHQL_API_TOKEN: ${{ secrets.GRAPHQL_API_TOKEN }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/spec.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ jobs:
env:
USER_FOR_TEST: ${{ secrets.SPEC_DEPLOY_USER }}
if: ${{ env.USER_FOR_TEST != '' }}
uses: burnett01/[email protected].1
uses: burnett01/[email protected].2
with:
switches: -rzv
path: docs/_spec/_site/
Expand Down
2 changes: 1 addition & 1 deletion community-build/community-projects/intent
Submodule intent updated 2 files
+0 −3 build.sbt
+0 −1 consume/build.sbt
6 changes: 3 additions & 3 deletions compiler/src/dotty/tools/backend/jvm/BCodeSkelBuilder.scala
Original file line number Diff line number Diff line change
Expand Up @@ -818,7 +818,7 @@ trait BCodeSkelBuilder extends BCodeHelpers {

methSymbol = dd.symbol
jMethodName = methSymbol.javaSimpleName
returnType = asmMethodType(dd.symbol).returnType
returnType = asmMethodType(methSymbol).returnType
isMethSymStaticCtor = methSymbol.isStaticConstructor

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

if (isMethSymStaticCtor) { appendToStaticCtor(dd) }
if (isMethSymStaticCtor) { appendToStaticCtor() }
} // end of emitNormalMethodBody()

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

def insertBefore(
location: asm.tree.AbstractInsnNode,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ import java.util.zip.{CRC32, Deflater, ZipEntry, ZipOutputStream}

import dotty.tools.dotc.core.Contexts.*
import dotty.tools.dotc.core.Decorators.em
import dotty.tools.dotc.util.chaining.*
import dotty.tools.io.{AbstractFile, PlainFile, VirtualFile}
import dotty.tools.io.PlainFile.toPlainFile
import BTypes.InternalName
import scala.util.chaining.*
import dotty.tools.io.JarArchive

import scala.language.unsafeNulls
Expand Down
11 changes: 5 additions & 6 deletions compiler/src/dotty/tools/dotc/Compiler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,8 @@ import typer.{TyperPhase, RefChecks}
import parsing.Parser
import Phases.Phase
import transform.*
import dotty.tools.backend
import backend.jvm.{CollectSuperCalls, GenBCode}
import localopt.StringInterpolatorOpt
import localopt.{StringInterpolatorOpt, DropForMap}

/** The central class of the dotc compiler. The job of a compiler is to create
* runs, which process given `phases` in a given `rootContext`.
Expand All @@ -34,8 +33,7 @@ class Compiler {
protected def frontendPhases: List[List[Phase]] =
List(new Parser) :: // Compiler frontend: scanner, parser
List(new TyperPhase) :: // Compiler frontend: namer, typer
List(new CheckUnused.PostTyper) :: // Check for unused elements
List(new CheckShadowing) :: // Check shadowing elements
List(CheckUnused.PostTyper(), CheckShadowing()) :: // Check for unused, shadowed elements
List(new YCheckPositions) :: // YCheck positions
List(new sbt.ExtractDependencies) :: // Sends information on classes' dependencies to sbt via callbacks
List(new semanticdb.ExtractSemanticDB.ExtractSemanticInfo) :: // Extract info into .semanticdb files
Expand All @@ -51,10 +49,10 @@ class Compiler {
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 CheckUnused.PostInlining) :: // Check for unused elements
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 CheckUnused.PostInlining) :: // Check for unused elements
Nil

/** Phases dealing with the transformation from pickled trees to backend trees */
Expand All @@ -70,7 +68,8 @@ 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 RefChecks, // Various checks mostly related to abstract members and overriding
new DropForMap) :: // Drop unused trailing map calls in for comprehensions
List(new semanticdb.ExtractSemanticDB.AppendDiagnostics) :: // Attach warnings to extracted SemanticDB and write to .semanticdb file
List(new init.Checker) :: // Check initialization of objects
List(new ProtectedAccessors, // Add accessors for protected members
Expand Down
23 changes: 22 additions & 1 deletion compiler/src/dotty/tools/dotc/Run.scala
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import Run.Progress
import scala.compiletime.uninitialized
import dotty.tools.dotc.transform.MegaPhase
import dotty.tools.dotc.transform.Pickler.AsyncTastyHolder
import java.util.{Timer, TimerTask}

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

runPhases(allPhases = fusedPhases)(using runCtx)
showProgress(runPhases(allPhases = fusedPhases)(using runCtx))
cancelAsyncTasty()

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

/** If set to true, prints every 10 seconds the files currently being compiled.
* Turn this flag on if you want to find out which test among many takes more time
* to compile than the others or causes an infinite loop in the compiler.
*/
private inline val debugPrintProgress = false

/** Period between progress reports, in ms */
private inline val printProgressPeriod = 10000

/** Shows progress if debugPrintProgress is true */
private def showProgress(proc: => Unit)(using Context): Unit =
if !debugPrintProgress then proc
else
val watchdog = new TimerTask:
def run() = println(i"[compiling $units]")
try
new Timer().schedule(watchdog, printProgressPeriod, printProgressPeriod)
proc
finally watchdog.cancel()

private sealed trait PrintedTree
private /*final*/ case class SomePrintedTree(phase: String, tree: String) extends PrintedTree
private object NoPrintedTree extends PrintedTree
Expand Down
48 changes: 33 additions & 15 deletions compiler/src/dotty/tools/dotc/ast/Desugar.scala
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,14 @@ object desugar {
*/
val UntupledParam: Property.Key[Unit] = Property.StickyKey()

/** An attachment key to indicate that a ValDef originated from a pattern.
*/
val PatternVar: Property.Key[Unit] = Property.StickyKey()

/** An attachment key for Trees originating in for-comprehension, such as tupling of assignments.
*/
val ForArtifact: Property.Key[Unit] = Property.StickyKey()

/** An attachment key to indicate that a ValDef is an evidence parameter
* for a context bound.
*/
Expand All @@ -56,6 +64,11 @@ object desugar {
*/
val PolyFunctionApply: Property.Key[Unit] = Property.StickyKey()

/** An attachment key to indicate that an Apply is created as a last `map`
* scall in a for-comprehension.
*/
val TrailingForMap: Property.Key[Unit] = Property.StickyKey()

/** What static check should be applied to a Match? */
enum MatchCheck {
case None, Exhaustive, IrrefutablePatDef, IrrefutableGenFrom
Expand Down Expand Up @@ -410,6 +423,7 @@ object desugar {
.withMods(Modifiers(
meth.mods.flags & (AccessFlags | Synthetic) | (vparam.mods.flags & Inline),
meth.mods.privateWithin))
.withSpan(vparam.rhs.span)
val rest = defaultGetters(vparams :: paramss1, n + 1)
if vparam.rhs.isEmpty then rest else defaultGetter :: rest
case _ :: paramss1 => // skip empty parameter lists and type parameters
Expand Down Expand Up @@ -859,7 +873,7 @@ object desugar {
val nu = vparamss.foldLeft(makeNew(classTypeRef)) { (nu, vparams) =>
val app = Apply(nu, vparams.map(refOfDef))
vparams match {
case vparam :: _ if vparam.mods.is(Given) || vparam.name.is(ContextBoundParamName) =>
case vparam :: _ if vparam.mods.isOneOf(GivenOrImplicit) || vparam.name.is(ContextBoundParamName) =>
app.setApplyKind(ApplyKind.Using)
case _ => app
}
Expand Down Expand Up @@ -1507,7 +1521,7 @@ object desugar {
val matchExpr =
if (tupleOptimizable) rhs
else
val caseDef = CaseDef(pat, EmptyTree, makeTuple(ids))
val caseDef = CaseDef(pat, EmptyTree, makeTuple(ids).withAttachment(ForArtifact, ()))
Match(makeSelector(rhs, MatchCheck.IrrefutablePatDef), caseDef :: Nil)
vars match {
case Nil if !mods.is(Lazy) =>
Expand Down Expand Up @@ -1537,6 +1551,7 @@ object desugar {
ValDef(named.name.asTermName, tpt, selector(n))
.withMods(mods)
.withSpan(named.span)
.withAttachment(PatternVar, ())
)
flatTree(firstDef :: restDefs)
}
Expand Down Expand Up @@ -1922,6 +1937,7 @@ object desugar {
val vdef = ValDef(named.name.asTermName, tpt, rhs)
.withMods(mods)
.withSpan(original.span.withPoint(named.span.start))
.withAttachment(PatternVar, ())
val mayNeedSetter = valDef(vdef)
mayNeedSetter
}
Expand Down Expand Up @@ -1956,14 +1972,8 @@ object desugar {
*
* 3.
*
* for (P <- G) yield P ==> G
*
* If betterFors is enabled, P is a variable or a tuple of variables and G is not a withFilter.
*
* for (P <- G) yield E ==> G.map (P => E)
*
* Otherwise
*
* 4.
*
* for (P_1 <- G_1; P_2 <- G_2; ...) ...
Expand Down Expand Up @@ -2136,14 +2146,20 @@ object desugar {
case (Tuple(ts1), Tuple(ts2)) => ts1.corresponds(ts2)(deepEquals)
case _ => false

def markTrailingMap(aply: Apply, gen: GenFrom, selectName: TermName): Unit =
if betterForsEnabled
&& selectName == mapName
&& gen.checkMode != GenCheckMode.Filtered // results of withFilter have the wrong type
&& (deepEquals(gen.pat, body) || deepEquals(body, Tuple(Nil)))
then
aply.putAttachment(TrailingForMap, ())

enums match {
case Nil if betterForsEnabled => body
case (gen: GenFrom) :: Nil =>
if betterForsEnabled
&& gen.checkMode != GenCheckMode.Filtered // results of withFilter have the wrong type
&& deepEquals(gen.pat, body)
then gen.expr // avoid a redundant map with identity
else Apply(rhsSelect(gen, mapName), makeLambda(gen, body))
val aply = Apply(rhsSelect(gen, mapName), makeLambda(gen, body))
markTrailingMap(aply, gen, mapName)
aply
case (gen: GenFrom) :: (rest @ (GenFrom(_, _, _) :: _)) =>
val cont = makeFor(mapName, flatMapName, rest, body)
Apply(rhsSelect(gen, flatMapName), makeLambda(gen, cont))
Expand All @@ -2154,7 +2170,9 @@ object desugar {
val selectName =
if rest.exists(_.isInstanceOf[GenFrom]) then flatMapName
else mapName
Apply(rhsSelect(gen, selectName), makeLambda(gen, cont))
val aply = Apply(rhsSelect(gen, selectName), makeLambda(gen, cont))
markTrailingMap(aply, gen, selectName)
aply
case (gen: GenFrom) :: (rest @ GenAlias(_, _) :: _) =>
val (valeqs, rest1) = rest.span(_.isInstanceOf[GenAlias])
val pats = valeqs map { case GenAlias(pat, _) => pat }
Expand All @@ -2167,7 +2185,7 @@ object desugar {
case _ => Modifiers()
makePatDef(valeq, mods, defpat, rhs)
}
val rhs1 = makeFor(nme.map, nme.flatMap, GenFrom(defpat0, gen.expr, gen.checkMode) :: Nil, Block(pdefs, makeTuple(id0 :: ids)))
val rhs1 = makeFor(nme.map, nme.flatMap, GenFrom(defpat0, gen.expr, gen.checkMode) :: Nil, Block(pdefs, makeTuple(id0 :: ids).withAttachment(ForArtifact, ())))
val allpats = gen.pat :: pats
val vfrom1 = GenFrom(makeTuple(allpats), rhs1, GenCheckMode.Ignore)
makeFor(mapName, flatMapName, vfrom1 :: rest1, body)
Expand Down
16 changes: 8 additions & 8 deletions compiler/src/dotty/tools/dotc/ast/MainProxies.scala
Original file line number Diff line number Diff line change
Expand Up @@ -98,17 +98,17 @@ object MainProxies {
val body = Try(call, handler :: Nil, EmptyTree)
val mainArg = ValDef(nme.args, TypeTree(defn.ArrayType.appliedTo(defn.StringType)), EmptyTree)
.withFlags(Param)
/** Replace typed `Ident`s that have been typed with a TypeSplice with the reference to the symbol.
* The annotations will be retype-checked in another scope that may not have the same imports.

/** This context is used to create the `TypeSplices` wrapping annotations
* below. These should have `mainFun` as their owner (and not the
* enclosing package class that we would get otherwise) so that
* subsequent owner changes (for example in `Typer.typedTypedSplice`) are
* correct. See #22364 and associated tests.
*/
def insertTypeSplices = new TreeMap {
override def transform(tree: Tree)(using Context): Tree = tree match
case tree: tpd.Ident @unchecked => TypedSplice(tree)
case tree => super.transform(tree)
}
val annotsCtx = ctx.fresh.setOwner(mainFun)
val annots = mainFun.annotations
.filterNot(_.matches(defn.MainAnnot))
.map(annot => insertTypeSplices.transform(annot.tree))
.map(annot => TypedSplice(annot.tree)(using annotsCtx))
val mainMeth = DefDef(nme.main, (mainArg :: Nil) :: Nil, TypeTree(defn.UnitType), body)
.withFlags(JavaStatic | Synthetic)
.withAnnotations(annots)
Expand Down
4 changes: 4 additions & 0 deletions compiler/src/dotty/tools/dotc/ast/TreeInfo.scala
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,8 @@ trait UntypedTreeInfo extends TreeInfo[Untyped] { self: Trees.Instance[Untyped]
*/
private def defKind(tree: Tree)(using Context): FlagSet = unsplice(tree) match {
case EmptyTree | _: Import => NoInitsInterface
case tree: TypeDef if ctx.settings.YcompileScala2Library.value =>
if (tree.isClassDef) EmptyFlags else NoInitsInterface
case tree: TypeDef => if (tree.isClassDef) NoInits else NoInitsInterface
case tree: DefDef =>
if tree.unforcedRhs == EmptyTree
Expand All @@ -477,6 +479,8 @@ trait UntypedTreeInfo extends TreeInfo[Untyped] { self: Trees.Instance[Untyped]
NoInitsInterface
else if tree.mods.is(Given) && tree.paramss.isEmpty then
EmptyFlags // might become a lazy val: TODO: check whether we need to suppress NoInits once we have new lazy val impl
else if ctx.settings.YcompileScala2Library.value then
EmptyFlags
else
NoInits
case tree: ValDef => if (tree.unforcedRhs == EmptyTree) NoInitsInterface else EmptyFlags
Expand Down
7 changes: 5 additions & 2 deletions compiler/src/dotty/tools/dotc/ast/Trees.scala
Original file line number Diff line number Diff line change
Expand Up @@ -461,8 +461,11 @@ object Trees {
else if qualifier.span.exists && qualifier.span.start > span.point then // right associative
val realName = name.stripModuleClassSuffix.lastPart
Span(span.start, span.start + realName.length, point)
else
Span(point, span.end, point)
else if span.pointMayBeIncorrect then
val realName = name.stripModuleClassSuffix.lastPart
val probablyPoint = span.end - realName.length
Span(probablyPoint, span.end, probablyPoint)
else Span(point, span.end, point)
else span
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/cc/Setup.scala
Original file line number Diff line number Diff line change
Expand Up @@ -570,7 +570,7 @@ class Setup extends PreRecheck, SymTransformer, SetupAPI:
// For example, `(x: T, y: x.f.type) => Unit`. In this case, when we
// substitute `x.f.type`, `x` becomes a `TermParamRef`. But the new method
// type is still under initialization and `paramInfos` is still `null`,
// so the new `NamedType` will not have a denoation.
// so the new `NamedType` will not have a denotation.
def adaptedInfo(psym: Symbol, info: mt.PInfo): mt.PInfo = mt.companion match
case mtc: MethodTypeCompanion => mtc.adaptParamInfo(psym, info).asInstanceOf[mt.PInfo]
case _ => info
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/config/CliCommand.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import Settings.*
import core.Contexts.*
import printing.Highlighting

import scala.util.chaining.given
import dotty.tools.dotc.util.chaining.*
import scala.PartialFunction.cond

trait CliCommand:
Expand Down
Loading

0 comments on commit 7356a2c

Please sign in to comment.