Skip to content

Commit 3daeaa6

Browse files
committed
Merge branch 'main' into export-diagnostics
2 parents a6dfec2 + b1fc943 commit 3daeaa6

File tree

1,095 files changed

+10588
-3354
lines changed

Some content is hidden

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

1,095 files changed

+10588
-3354
lines changed

.github/workflows/ci.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,11 @@ jobs:
255255
run: |
256256
./project/scripts/sbt ";scala3-interfaces/mimaReportBinaryIssues ;scala3-library-bootstrapped/mimaReportBinaryIssues ;scala3-library-bootstrappedJS/mimaReportBinaryIssues; tasty-core-bootstrapped/mimaReportBinaryIssues; stdlib-bootstrapped/mimaReportBinaryIssues"
257257
258+
- name: TASTy MiMa
259+
run: |
260+
# This script cleans the compiler and recompiles it from scratch (keep as last run)
261+
./project/scripts/stdlib-bootstrapped-tasty-mima.sh
262+
258263
community_build_a:
259264
runs-on: [self-hosted, Linux]
260265
container:

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,3 +99,6 @@ docs/_spec/.jekyll-metadata
9999
# scaladoc related
100100
scaladoc/output/
101101

102+
#coverage
103+
coverage/
104+

.gitmodules

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,6 @@
2828
[submodule "community-build/community-projects/scala-xml"]
2929
path = community-build/community-projects/scala-xml
3030
url = https://github.com/dotty-staging/scala-xml
31-
[submodule "community-build/community-projects/shapeless"]
32-
path = community-build/community-projects/shapeless
33-
url = https://github.com/dotty-staging/shapeless
34-
branch = shapeless-3-staging
3531
[submodule "community-build/community-projects/xml-interpolator"]
3632
path = community-build/community-projects/xml-interpolator
3733
url = https://github.com/dotty-staging/xml-interpolator.git
@@ -222,3 +218,6 @@
222218
[submodule "community-build/community-projects/parboiled2"]
223219
path = community-build/community-projects/parboiled2
224220
url = https://github.com/dotty-staging/parboiled2.git
221+
[submodule "community-build/community-projects/shapeless-3"]
222+
path = community-build/community-projects/shapeless-3
223+
url = https://github.com/dotty-staging/shapeless-3.git
Submodule perspective updated 84 files
Lines changed: 0 additions & 1 deletion
This file was deleted.
Submodule shapeless-3 added at d27c5ba

community-build/src/scala/dotty/communitybuild/projects.scala

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ final case class SbtCommunityProject(
140140
case Some(ivyHome) => List(s"-Dsbt.ivy.home=$ivyHome")
141141
case _ => Nil
142142
extraSbtArgs ++ sbtProps ++ List(
143-
"-sbt-version", "1.9.0",
143+
"-sbt-version", "1.9.3",
144144
"-Dsbt.supershell=false",
145145
s"-Ddotty.communitybuild.dir=$communitybuildDir",
146146
s"--addPluginSbtFile=$sbtPluginFilePath"
@@ -366,12 +366,10 @@ object projects:
366366
// sbtDocCommand = "library/doc" // Does no compile? No idea :/
367367
)
368368

369-
370-
lazy val shapeless = SbtCommunityProject(
371-
project = "shapeless",
372-
sbtTestCommand = """set deriving/scalacOptions -= "-Xfatal-warnings"; set typeable/scalacOptions -= "-Xfatal-warnings"; test""",
373-
// selectively disable -Xfatal-warnings due to deprecations
374-
sbtDocCommand = forceDoc("typeable", "deriving", "data"),
369+
lazy val shapeless3 = SbtCommunityProject(
370+
project = "shapeless-3",
371+
sbtTestCommand = "testJVM; testJS",
372+
sbtDocCommand = forceDoc("typeable", "deriving"),
375373
scalacOptions = SbtCommunityProject.scalacOptions.filter(_ != "-Ysafe-init"), // due to -Xfatal-warnings
376374
)
377375

@@ -796,7 +794,7 @@ def allProjects = List(
796794
projects.minitest,
797795
projects.fastparse,
798796
projects.stdLib213,
799-
projects.shapeless,
797+
projects.shapeless3,
800798
projects.xmlInterpolator,
801799
projects.effpi,
802800
projects.sconfig,

community-build/test/scala/dotty/communitybuild/CommunityBuildTest.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ class CommunityBuildTestC:
9191
@Test def scalaz = projects.scalaz.run()
9292
@Test def scas = projects.scas.run()
9393
@Test def sconfig = projects.sconfig.run()
94-
@Test def shapeless = projects.shapeless.run()
94+
@Test def shapeless3 = projects.shapeless3.run()
9595
@Test def sourcecode = projects.sourcecode.run()
9696
@Test def specs2 = projects.specs2.run()
9797

compiler/src/dotty/tools/MainGenericRunner.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ object MainGenericRunner {
148148
case (o @ javaOption(striped)) :: tail =>
149149
processArgs(tail, settings.withJavaArgs(striped).withScalaArgs(o))
150150
case (o @ scalaOption(_*)) :: tail =>
151-
val remainingArgs = (CommandLineParser.expandArg(o) ++ tail).toList
151+
val remainingArgs = CommandLineParser.expandArg(o) ++ tail
152152
processArgs(remainingArgs, settings)
153153
case (o @ colorOption(_*)) :: tail =>
154154
processArgs(tail, settings.withScalaArgs(o))

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

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -763,9 +763,14 @@ trait BCodeSkelBuilder extends BCodeHelpers {
763763
for (p <- params) { locals.makeLocal(p.symbol) }
764764
// debug assert((params.map(p => locals(p.symbol).tk)) == asmMethodType(methSymbol).getArgumentTypes.toList, "debug")
765765

766-
if (params.size > MaximumJvmParameters) {
766+
val paramsSize = params.map { param =>
767+
val tpeTym = param.symbol.info.typeSymbol
768+
if tpeTym == defn.LongClass || tpeTym == defn.DoubleClass then 2 else 1
769+
}.sum
770+
if (paramsSize > MaximumJvmParameters) {
767771
// SI-7324
768-
report.error(em"Platform restriction: a parameter list's length cannot exceed $MaximumJvmParameters.", ctx.source.atSpan(methSymbol.span))
772+
val info = if paramsSize == params.length then "" else " (Long and Double count as 2)" // https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.3.3
773+
report.error(em"Platform restriction: a parameter list's length cannot exceed $MaximumJvmParameters$info.", ctx.source.atSpan(methSymbol.span))
769774
return
770775
}
771776

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,11 +73,20 @@ class CompilationUnit protected (val source: SourceFile) {
7373
/** List of all comments present in this compilation unit */
7474
var comments: List[Comment] = Nil
7575

76+
/** This is used to record dependencies to invalidate during incremental
77+
* compilation, but only if `ctx.runZincPhases` is true.
78+
*/
79+
val depRecorder: sbt.DependencyRecorder = sbt.DependencyRecorder()
80+
7681
/** Suspends the compilation unit by thowing a SuspendException
7782
* and recording the suspended compilation unit
7883
*/
7984
def suspend()(using Context): Nothing =
8085
assert(isSuspendable)
86+
// Clear references to symbols that may become stale. No need to call
87+
// `depRecorder.sendToZinc()` since all compilation phases will be rerun
88+
// when this unit is unsuspended.
89+
depRecorder.clear()
8190
if !suspended then
8291
if (ctx.settings.XprintSuspension.value)
8392
report.echo(i"suspended: $this")

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -240,15 +240,16 @@ class Run(comp: Compiler, ictx: Context) extends ImplicitRunInfo with Constraint
240240

241241
for (phase <- ctx.base.allPhases)
242242
if (phase.isRunnable)
243-
Stats.trackTime(s"$phase ms ") {
243+
Stats.trackTime(s"phase time ms/$phase") {
244244
val start = System.currentTimeMillis
245245
val profileBefore = profiler.beforePhase(phase)
246246
units = phase.runOn(units)
247247
profiler.afterPhase(phase, profileBefore)
248248
if (ctx.settings.Xprint.value.containsPhase(phase))
249249
for (unit <- units)
250-
lastPrintedTree =
251-
printTree(lastPrintedTree)(using ctx.fresh.setPhase(phase.next).setCompilationUnit(unit))
250+
def printCtx(unit: CompilationUnit) = phase.printingContext(
251+
ctx.fresh.setPhase(phase.next).setCompilationUnit(unit))
252+
lastPrintedTree = printTree(lastPrintedTree)(using printCtx(unit))
252253
report.informTime(s"$phase ", start)
253254
Stats.record(s"total trees at end of $phase", ast.Trees.ntrees)
254255
for (unit <- units)

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

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -205,12 +205,12 @@ object desugar {
205205

206206
def makeImplicitParameters(
207207
tpts: List[Tree], implicitFlag: FlagSet,
208-
mkParamName: () => TermName,
208+
mkParamName: Int => TermName,
209209
forPrimaryConstructor: Boolean = false
210210
)(using Context): List[ValDef] =
211211
for (tpt, i) <- tpts.zipWithIndex yield {
212212
val paramFlags: FlagSet = if (forPrimaryConstructor) LocalParamAccessor else Param
213-
val epname = mkParamName()
213+
val epname = mkParamName(i)
214214
ValDef(epname, tpt, EmptyTree).withFlags(paramFlags | implicitFlag)
215215
}
216216

@@ -254,7 +254,7 @@ object desugar {
254254
// using clauses, we only need names that are unique among the
255255
// parameters of the method since shadowing does not affect
256256
// implicit resolution in Scala 3.
257-
mkParamName = () =>
257+
mkParamName = i =>
258258
val index = seenContextBounds + 1 // Start at 1 like FreshNameCreator.
259259
val ret = ContextBoundParamName(EmptyTermName, index)
260260
seenContextBounds += 1
@@ -1602,9 +1602,12 @@ object desugar {
16021602
case vd: ValDef => vd
16031603
}
16041604

1605-
def makeContextualFunction(formals: List[Tree], body: Tree, erasedParams: List[Boolean])(using Context): Function = {
1605+
def makeContextualFunction(formals: List[Tree], paramNamesOrNil: List[TermName], body: Tree, erasedParams: List[Boolean])(using Context): Function = {
16061606
val mods = Given
1607-
val params = makeImplicitParameters(formals, mods, mkParamName = () => ContextFunctionParamName.fresh())
1607+
val params = makeImplicitParameters(formals, mods,
1608+
mkParamName = i =>
1609+
if paramNamesOrNil.isEmpty then ContextFunctionParamName.fresh()
1610+
else paramNamesOrNil(i))
16081611
FunctionWithMods(params, body, Modifiers(mods), erasedParams)
16091612
}
16101613

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

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,17 @@ trait TreeInfo[T <: Untyped] { self: Trees.Instance[T] =>
376376
case _ =>
377377
tree.tpe.isInstanceOf[ThisType]
378378
}
379+
380+
/** Under capture checking, an extractor for qualified roots `cap[Q]`.
381+
*/
382+
object QualifiedRoot:
383+
384+
def unapply(tree: Apply)(using Context): Option[String] = tree match
385+
case Apply(fn, Literal(lit) :: Nil) if fn.symbol == defn.Caps_capIn =>
386+
Some(lit.value.asInstanceOf[String])
387+
case _ =>
388+
None
389+
end QualifiedRoot
379390
}
380391

381392
trait UntypedTreeInfo extends TreeInfo[Untyped] { self: Trees.Instance[Untyped] =>
@@ -799,12 +810,37 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] =>
799810
}
800811
}
801812

813+
/** An extractor for def of a closure contained the block of the closure,
814+
* possibly with type ascriptions.
815+
*/
816+
object possiblyTypedClosureDef:
817+
def unapply(tree: Tree)(using Context): Option[DefDef] = tree match
818+
case Typed(expr, _) => unapply(expr)
819+
case _ => closureDef.unapply(tree)
820+
802821
/** If tree is a closure, its body, otherwise tree itself */
803822
def closureBody(tree: Tree)(using Context): Tree = tree match {
804823
case closureDef(meth) => meth.rhs
805824
case _ => tree
806825
}
807826

827+
/** Is `mdef` an eta-expansion of a method reference? To recognize this, we use
828+
* the following criterion: A method definition is an eta expansion, if
829+
* it contains at least one term paramter, the parameter has a zero extent span,
830+
* and the right hand side is either an application or a closure with'
831+
* an anonymous method that's itself characterized as an eta expansion.
832+
*/
833+
def isEtaExpansion(mdef: DefDef)(using Context): Boolean =
834+
!rhsOfEtaExpansion(mdef).isEmpty
835+
836+
def rhsOfEtaExpansion(mdef: DefDef)(using Context): Tree = mdef.paramss match
837+
case (param :: _) :: _ if param.asInstanceOf[Tree].span.isZeroExtent =>
838+
mdef.rhs match
839+
case rhs: Apply => rhs
840+
case closureDef(mdef1) => rhsOfEtaExpansion(mdef1)
841+
case _ => EmptyTree
842+
case _ => EmptyTree
843+
808844
/** The variables defined by a pattern, in reverse order of their appearance. */
809845
def patVars(tree: Tree)(using Context): List[Symbol] = {
810846
val acc = new TreeAccumulator[List[Symbol]] { outer =>
@@ -954,7 +990,7 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] =>
954990
def isStructuralTermSelectOrApply(tree: Tree)(using Context): Boolean = {
955991
def isStructuralTermSelect(tree: Select) =
956992
def hasRefinement(qualtpe: Type): Boolean = qualtpe.dealias match
957-
case defn.PolyOrErasedFunctionOf(_) =>
993+
case defn.PolyFunctionOf(_) =>
958994
false
959995
case RefinedType(parent, rname, rinfo) =>
960996
rname == tree.name || hasRefinement(parent)

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

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1344,10 +1344,17 @@ object Trees {
13441344
case tree: SeqLiteral if (elems eq tree.elems) && (elemtpt eq tree.elemtpt) => tree
13451345
case _ => finalize(tree, untpd.SeqLiteral(elems, elemtpt)(sourceFile(tree)))
13461346
}
1347-
def Inlined(tree: Tree)(call: tpd.Tree, bindings: List[MemberDef], expansion: Tree)(using Context): Inlined = tree match {
1348-
case tree: Inlined if (call eq tree.call) && (bindings eq tree.bindings) && (expansion eq tree.expansion) => tree
1349-
case _ => finalize(tree, untpd.Inlined(call, bindings, expansion)(sourceFile(tree)))
1350-
}
1347+
// Positions of trees are automatically pushed down except when we reach an Inlined tree. Therefore, we
1348+
// make sure the new expansion has a position by copying the one of the original Inlined tree.
1349+
def Inlined(tree: Inlined)(call: tpd.Tree, bindings: List[MemberDef], expansion: Tree)(using Context): Inlined =
1350+
if (call eq tree.call) && (bindings eq tree.bindings) && (expansion eq tree.expansion) then tree
1351+
else
1352+
// Copy the span from the original Inlined tree if the new expansion doesn't have a span.
1353+
val expansionWithSpan =
1354+
if expansion.span.exists then expansion
1355+
else expansion.withSpan(tree.expansion.span)
1356+
finalize(tree, untpd.Inlined(call, bindings, expansionWithSpan)(sourceFile(tree)))
1357+
13511358
def Quote(tree: Tree)(body: Tree, tags: List[Tree])(using Context): Quote = tree match {
13521359
case tree: Quote if (body eq tree.body) && (tags eq tree.tags) => tree
13531360
case _ => finalize(tree, untpd.Quote(body, tags)(sourceFile(tree)))
@@ -1589,6 +1596,9 @@ object Trees {
15891596
case tree @ TypeDef(name, rhs) =>
15901597
cpy.TypeDef(tree)(name, transform(rhs))
15911598
case tree @ Template(constr, parents, self, _) if tree.derived.isEmpty =>
1599+
// Currently we do not have cases where we expect `tree.derived` to contain trees for typed trees.
1600+
// If it is the case we will fall in `transformMoreCases` and throw an exception there.
1601+
// In the future we might keep the `derived` clause after typing, in that case we might want to start handling it here.
15921602
cpy.Template(tree)(transformSub(constr), transform(tree.parents), Nil, transformSub(self), transformStats(tree.body, tree.symbol))
15931603
case Import(expr, selectors) =>
15941604
cpy.Import(tree)(transform(expr), selectors)

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

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -349,24 +349,27 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
349349

350350
/** An anonymous class
351351
*
352-
* new parents { forwarders }
352+
* new parents { termForwarders; typeAliases }
353353
*
354-
* where `forwarders` contains forwarders for all functions in `fns`.
355-
* @param parents a non-empty list of class types
356-
* @param fns a non-empty of functions for which forwarders should be defined in the class.
357-
* The class has the same owner as the first function in `fns`.
358-
* Its position is the union of all functions in `fns`.
354+
* @param parents a non-empty list of class types
355+
* @param termForwarders a non-empty list of forwarding definitions specified by their name and the definition they forward to.
356+
* @param typeMembers a possibly-empty list of type members specified by their name and their right hand side.
357+
*
358+
* The class has the same owner as the first function in `termForwarders`.
359+
* Its position is the union of all symbols in `termForwarders`.
359360
*/
360-
def AnonClass(parents: List[Type], fns: List[TermSymbol], methNames: List[TermName])(using Context): Block = {
361-
AnonClass(fns.head.owner, parents, fns.map(_.span).reduceLeft(_ union _)) { cls =>
362-
def forwarder(fn: TermSymbol, name: TermName) = {
361+
def AnonClass(parents: List[Type], termForwarders: List[(TermName, TermSymbol)],
362+
typeMembers: List[(TypeName, TypeBounds)] = Nil)(using Context): Block = {
363+
AnonClass(termForwarders.head._2.owner, parents, termForwarders.map(_._2.span).reduceLeft(_ union _)) { cls =>
364+
def forwarder(name: TermName, fn: TermSymbol) = {
363365
val fwdMeth = fn.copy(cls, name, Synthetic | Method | Final).entered.asTerm
364366
for overridden <- fwdMeth.allOverriddenSymbols do
365367
if overridden.is(Extension) then fwdMeth.setFlag(Extension)
366368
if !overridden.is(Deferred) then fwdMeth.setFlag(Override)
367369
DefDef(fwdMeth, ref(fn).appliedToArgss(_))
368370
}
369-
fns.lazyZip(methNames).map(forwarder)
371+
termForwarders.map((name, sym) => forwarder(name, sym)) ++
372+
typeMembers.map((name, info) => TypeDef(newSymbol(cls, name, Synthetic, info).entered))
370373
}
371374
}
372375

@@ -748,7 +751,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
748751
}
749752
}
750753

751-
override def Inlined(tree: Tree)(call: Tree, bindings: List[MemberDef], expansion: Tree)(using Context): Inlined = {
754+
override def Inlined(tree: Inlined)(call: Tree, bindings: List[MemberDef], expansion: Tree)(using Context): Inlined = {
752755
val tree1 = untpdCpy.Inlined(tree)(call, bindings, expansion)
753756
tree match {
754757
case tree: Inlined if sameTypes(bindings, tree.bindings) && (expansion.tpe eq tree.expansion.tpe) =>
@@ -1149,7 +1152,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
11491152

11501153
def etaExpandCFT(using Context): Tree =
11511154
def expand(target: Tree, tp: Type)(using Context): Tree = tp match
1152-
case defn.ContextFunctionType(argTypes, resType, _) =>
1155+
case defn.ContextFunctionType(argTypes, resType) =>
11531156
val anonFun = newAnonFun(
11541157
ctx.owner,
11551158
MethodType.companion(isContextual = true)(argTypes, resType),

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,10 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
149149
case Floating
150150
}
151151

152-
/** {x1, ..., xN} T (only relevant under captureChecking) */
152+
/** {x1, ..., xN} T (only relevant under captureChecking)
153+
* Created when parsing function types so that capture set and result type
154+
* is combined in a single node.
155+
*/
153156
case class CapturesAndResult(refs: List[Tree], parent: Tree)(implicit @constructorOnly src: SourceFile) extends TypTree
154157

155158
/** A type tree appearing somewhere in the untyped DefDef of a lambda, it will be typed using `tpFun`.
@@ -512,6 +515,9 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
512515
def captureRoot(using Context): Select =
513516
Select(scalaDot(nme.caps), nme.CAPTURE_ROOT)
514517

518+
def captureRootIn(using Context): Select =
519+
Select(scalaDot(nme.caps), nme.capIn)
520+
515521
def makeRetaining(parent: Tree, refs: List[Tree], annotName: TypeName)(using Context): Annotated =
516522
Annotated(parent, New(scalaAnnotationDot(annotName), List(refs)))
517523

0 commit comments

Comments
 (0)