Skip to content

Commit aa917ff

Browse files
authored
Merge branch 'main' into cb-newbuild
2 parents ca3bbdf + 88e43fa commit aa917ff

File tree

13 files changed

+116
-108
lines changed

13 files changed

+116
-108
lines changed

compiler/src/dotty/tools/dotc/cc/Capability.scala

Lines changed: 21 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -90,33 +90,33 @@ object Capabilities:
9090
*/
9191
case class Maybe(underlying: Capability) extends DerivedCapability
9292

93-
/** The readonly capability `x.rd`. We have {x.rd} <: {x}.
94-
*
95-
* Read-only capabilities cannot wrap maybe capabilities
96-
* but they can wrap reach capabilities. We have
97-
* (x?).readOnly = (x.rd)?
98-
*/
99-
case class ReadOnly(underlying: ObjectCapability | RootCapability | Reach | Restricted)
100-
extends DerivedCapability
101-
10293
/** The restricted capability `x.only[C]`. We have {x.only[C]} <: {x}.
10394
*
104-
* Restricted capabilities cannot wrap maybe capabilities or read-only capabilities
95+
* Restricted capabilities cannot wrap maybe capabilities
10596
* but they can wrap reach capabilities. We have
10697
* (x?).restrict[T] = (x.restrict[T])?
10798
* (x.rd).restrict[T] = (x.restrict[T]).rd
10899
*/
109-
case class Restricted(underlying: ObjectCapability | RootCapability | Reach, cls: ClassSymbol)
100+
case class Restricted(underlying: CoreCapability | RootCapability | Reach, cls: ClassSymbol)
110101
extends DerivedCapability
111102

103+
/** An extractor for the read-only capability `x.rd`. `x.rd` is represented as
104+
* `c.only[caps.Read]`.
105+
*/
106+
object ReadOnly:
107+
def apply(underlying: CoreCapability | RootCapability | Reach | Restricted)(using Context): Restricted =
108+
Restricted(underlying.stripRestricted.asInstanceOf, defn.Caps_Read)
109+
def unapply(ref: Restricted)(using Context): Option[CoreCapability | RootCapability | Reach] =
110+
if ref.cls == defn.Caps_Read then Some(ref.underlying) else None
111+
112112
/** If `x` is a capability, its reach capability `x*`. `x*` stands for all
113113
* capabilities reachable through `x`.
114114
* We have `{x} <: {x*} <: dcs(x)}` where the deep capture set `dcs(x)` of `x`
115115
* is the union of all capture sets that appear in covariant position in the
116116
* type of `x`. If `x` and `y` are different variables then `{x*}` and `{y*}`
117117
* are unrelated.
118118
*
119-
* Reach capabilities cannot wrap read-only capabilities or maybe capabilities.
119+
* Reach capabilities cannot wrap restricted capabilities or maybe capabilities.
120120
* We have
121121
* (x?).reach = (x.reach)?
122122
* (x.rd).reach = (x.reach).rd
@@ -132,7 +132,7 @@ object Capabilities:
132132
object GlobalCap extends RootCapability:
133133
def descr(using Context) = "the universal root capability"
134134
override val maybe = Maybe(this)
135-
override val readOnly = ReadOnly(this)
135+
override def readOnly(using Context) = ReadOnly(this)
136136
override def restrict(cls: ClassSymbol)(using Context) = Restricted(this, cls)
137137
override def reach = unsupported("cap.reach")
138138
override def singletonCaptureSet(using Context) = CaptureSet.universal
@@ -346,23 +346,21 @@ object Capabilities:
346346
case self: Maybe => self
347347
case _ => cached(Maybe(this))
348348

349-
def readOnly: ReadOnly | Maybe = this match
349+
def readOnly(using Context): Restricted | Maybe = this match
350350
case Maybe(ref1) => Maybe(ref1.readOnly)
351-
case self: ReadOnly => self
352-
case self: (ObjectCapability | RootCapability | Reach | Restricted) => cached(ReadOnly(self))
351+
case self @ ReadOnly(_) => self
352+
case self: (CoreCapability | RootCapability | Reach | Restricted) => cached(ReadOnly(self))
353353

354-
def restrict(cls: ClassSymbol)(using Context): Restricted | ReadOnly | Maybe = this match
354+
def restrict(cls: ClassSymbol)(using Context): Restricted | Maybe = this match
355355
case Maybe(ref1) => Maybe(ref1.restrict(cls))
356-
case ReadOnly(ref1) => ReadOnly(ref1.restrict(cls).asInstanceOf[Restricted])
357356
case self @ Restricted(ref1, prevCls) =>
358357
val combinedCls = leastClassifier(prevCls, cls)
359358
if combinedCls == prevCls then self
360359
else cached(Restricted(ref1, combinedCls))
361-
case self: (ObjectCapability | RootCapability | Reach) => cached(Restricted(self, cls))
360+
case self: (CoreCapability | RootCapability | Reach) => cached(Restricted(self, cls))
362361

363-
def reach: Reach | Restricted | ReadOnly | Maybe = this match
362+
def reach: Reach | Restricted | Maybe = this match
364363
case Maybe(ref1) => Maybe(ref1.reach)
365-
case ReadOnly(ref1) => ReadOnly(ref1.reach.asInstanceOf[Reach | Restricted])
366364
case Restricted(ref1, cls) => Restricted(ref1.reach.asInstanceOf[Reach], cls)
367365
case self: Reach => self
368366
case self: ObjectCapability => cached(Reach(self))
@@ -377,9 +375,9 @@ object Capabilities:
377375
case tp: SetCapability => tp.captureSetOfInfo.isReadOnly
378376
case _ => this ne stripReadOnly
379377

378+
/** The restriction of this capability or NoSymbol if there is none */
380379
final def restriction(using Context): Symbol = this match
381380
case Restricted(_, cls) => cls
382-
case ReadOnly(ref1) => ref1.restriction
383381
case Maybe(ref1) => ref1.restriction
384382
case _ => NoSymbol
385383

@@ -397,10 +395,9 @@ object Capabilities:
397395
case Maybe(ref1) => ref1.stripReadOnly.maybe
398396
case _ => this
399397

400-
/** Drop restrictions with clss `cls` or a superclass of `cls` */
398+
/** Drop restrictions with class `cls` or a superclass of `cls` */
401399
final def stripRestricted(cls: ClassSymbol)(using Context): Capability = this match
402400
case Restricted(ref1, cls1) if cls.isSubClass(cls1) => ref1
403-
case ReadOnly(ref1) => ref1.stripRestricted(cls).readOnly
404401
case Maybe(ref1) => ref1.stripRestricted(cls).maybe
405402
case _ => this
406403

@@ -409,7 +406,6 @@ object Capabilities:
409406

410407
final def stripReach(using Context): Capability = this match
411408
case Reach(ref1) => ref1
412-
case ReadOnly(ref1) => ref1.stripReach.readOnly
413409
case Restricted(ref1, cls) => ref1.stripReach.restrict(cls)
414410
case Maybe(ref1) => ref1.stripReach.maybe
415411
case _ => this
@@ -591,7 +587,6 @@ object Capabilities:
591587
def computeHiddenSet(f: Refs => Refs)(using Context): Refs = this match
592588
case self: FreshCap => f(self.hiddenSet.elems)
593589
case Restricted(elem1, cls) => elem1.computeHiddenSet(f).map(_.restrict(cls))
594-
case ReadOnly(elem1) => elem1.computeHiddenSet(f).map(_.readOnly)
595590
case _ => emptyRefs
596591

597592
/** The transitive classifiers of this capability. */
@@ -609,8 +604,6 @@ object Capabilities:
609604
assert(cls != defn.AnyClass)
610605
if cls == defn.NothingClass then ClassifiedAs(Nil)
611606
else ClassifiedAs(cls :: Nil)
612-
case ReadOnly(ref1) =>
613-
ref1.transClassifiers
614607
case Maybe(ref1) =>
615608
ref1.transClassifiers
616609
case Reach(_) =>
@@ -634,8 +627,6 @@ object Capabilities:
634627
case Restricted(_, cls1) =>
635628
assert(cls != defn.AnyClass)
636629
cls1.isSubClass(cls)
637-
case ReadOnly(ref1) =>
638-
ref1.tryClassifyAs(cls)
639630
case Maybe(ref1) =>
640631
ref1.tryClassifyAs(cls)
641632
case Reach(_) =>
@@ -656,7 +647,6 @@ object Capabilities:
656647
cs.forall(c => leastClassifier(c, cls) == defn.NothingClass)
657648
case _ => false
658649
isEmpty || ref1.isKnownEmpty
659-
case ReadOnly(ref1) => ref1.isKnownEmpty
660650
case Maybe(ref1) => ref1.isKnownEmpty
661651
case _ => false
662652

@@ -717,7 +707,6 @@ object Capabilities:
717707
case _ => false
718708
|| viaInfo(y.info)(subsumingRefs(this, _))
719709
case Maybe(y1) => this.stripMaybe.subsumes(y1)
720-
case ReadOnly(y1) => this.stripReadOnly.subsumes(y1)
721710
case Restricted(y1, cls) => this.stripRestricted(cls).subsumes(y1)
722711
case y: TypeRef if y.derivesFrom(defn.Caps_CapSet) =>
723712
// The upper and lower bounds don't have to be in the form of `CapSet^{...}`.
@@ -801,7 +790,6 @@ object Capabilities:
801790
y.isKnownClassifiedAs(cls) && x1.maxSubsumes(y, canAddHidden)
802791
case _ =>
803792
y match
804-
case ReadOnly(y1) => this.stripReadOnly.maxSubsumes(y1, canAddHidden)
805793
case Restricted(y1, cls) => this.stripRestricted(cls).maxSubsumes(y1, canAddHidden)
806794
case _ => false
807795

@@ -889,7 +877,6 @@ object Capabilities:
889877
case c: DerivedCapability =>
890878
val c1 = c.underlying.toType
891879
c match
892-
case _: ReadOnly => ReadOnlyCapability(c1)
893880
case Restricted(_, cls) => OnlyCapability(c1, cls)
894881
case _: Reach => ReachCapability(c1)
895882
case _: Maybe => MaybeCapability(c1)

compiler/src/dotty/tools/dotc/cc/CaptureSet.scala

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1615,8 +1615,6 @@ object CaptureSet:
16151615
case Restricted(c1, cls) =>
16161616
if cls == defn.NothingClass then CaptureSet.empty
16171617
else c1.captureSetOfInfo.restrict(cls) // todo: should we simplify using subsumption here?
1618-
case ReadOnly(c1) =>
1619-
c1.captureSetOfInfo.readOnly
16201618
case Maybe(c1) =>
16211619
c1.captureSetOfInfo.maybe
16221620
case c: RootCapability =>

compiler/src/dotty/tools/dotc/cc/SepCheck.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ object SepCheck:
180180
case newElem :: newElems1 =>
181181
if seen.contains(newElem) then
182182
recur(seen, acc, newElems1)
183-
else newElem.stripRestricted.stripReadOnly match
183+
else newElem.stripRestricted match
184184
case _: FreshCap if !newElem.isKnownClassifiedAs(defn.Caps_SharedCapability) =>
185185
val hiddens = if followHidden then newElem.hiddenSet.toList else Nil
186186
recur(seen + newElem, acc + newElem, hiddens ++ newElems1)
@@ -220,7 +220,7 @@ object SepCheck:
220220
refs1.foreach: ref =>
221221
if !ref.isReadOnly then
222222
val coreRef = ref.stripRestricted
223-
if refs2.exists(_.stripRestricted.stripReadOnly.coversFresh(coreRef)) then
223+
if refs2.exists(_.stripRestricted.coversFresh(coreRef)) then
224224
acc += coreRef
225225
acc
226226
assert(refs.forall(_.isTerminalCapability))

compiler/src/dotty/tools/dotc/core/Types.scala

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6402,11 +6402,6 @@ object Types extends TypeUtils {
64026402
mapCapability(c1) match
64036403
case c2: Capability => c2.restrict(cls)
64046404
case (cs: CaptureSet, exact) => (cs.restrict(cls), exact)
6405-
case ReadOnly(c1) =>
6406-
assert(!deep)
6407-
mapCapability(c1) match
6408-
case c2: Capability => c2.readOnly
6409-
case (cs: CaptureSet, exact) => (cs.readOnly, exact)
64106405
case Maybe(c1) =>
64116406
assert(!deep)
64126407
mapCapability(c1) match

compiler/src/dotty/tools/dotc/typer/Dynamic.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,9 @@ object DynamicUnapply {
4343
def unapply(tree: tpd.Tree): Option[List[tpd.Tree]] = tree match
4444
case TypeApply(Select(qual, name), _) if name == nme.asInstanceOfPM =>
4545
unapply(qual)
46-
case Apply(Apply(Select(selectable, fname), Literal(Constant(name)) :: ctag :: Nil), _ :: implicits)
46+
case Apply(Apply(Select(selectable, fname), Literal(Constant(name)) :: restArgs), _ :: implicits)
4747
if fname == nme.applyDynamic && (name == "unapply" || name == "unapplySeq") =>
48-
Some(selectable :: ctag :: implicits)
48+
Some(selectable :: (restArgs ::: implicits))
4949
case _ =>
5050
None
5151
}

project/Build.scala

Lines changed: 56 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ object Build {
5959
*
6060
* Warning: Change of this variable needs to be consulted with `expectedTastyVersion`
6161
*/
62-
val referenceVersion = "3.7.4-RC3"
62+
val referenceVersion = "3.7.4"
6363

6464
/** Version of the Scala compiler targeted in the current release cycle
6565
* Contains a version without RC/SNAPSHOT/NIGHTLY specific suffixes
@@ -433,6 +433,54 @@ object Build {
433433

434434
private lazy val currentYear: String = java.util.Calendar.getInstance().get(java.util.Calendar.YEAR).toString
435435

436+
private val shellBanner: String =
437+
"""%n ________ ___ / / ___
438+
|%n / __/ __// _ | / / / _ |
439+
|%n __\\ \\/ /__/ __ |/ /__/ __ |
440+
|%n /____/\\___/_/ |_/____/_/ | |
441+
|%n |/ %s""".stripMargin.replace("\n", "")
442+
443+
// Common generator for properties files
444+
lazy val generatePropertiesFile = (fileName: String, contents: Def.Initialize[String]) => Def.task {
445+
val file = (Compile / resourceManaged).value / fileName
446+
val data = contents.value
447+
if (!(file.exists && IO.read(file) == data)) {
448+
IO.write(file, data)
449+
}
450+
Seq(file)
451+
}
452+
453+
// Generate compiler.properties consumed by sbt
454+
lazy val generateCompilerProperties: Def.Initialize[Task[Seq[File]]] = {
455+
import java.util._
456+
import java.text._
457+
val dateFormat = new SimpleDateFormat("yyyyMMdd-HHmmss")
458+
dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"))
459+
460+
val fileName = "compiler.properties"
461+
val contents = Def.setting {
462+
s"""version.number=${version.value}
463+
|maven.version.number=${version.value}
464+
|git.hash=${VersionUtil.gitHash}
465+
|copyright.string=Copyright 2002-$currentYear, LAMP/EPFL
466+
|""".stripMargin
467+
}
468+
generatePropertiesFile(fileName, contents)
469+
}
470+
471+
// Generate library.properties consumed by scala.util.Properties
472+
lazy val generateLibraryProperties: Def.Initialize[Task[Seq[File]]] = {
473+
val fileName = "library.properties"
474+
val contents = Def.setting {
475+
s"""version.number=${version.value}
476+
|maven.version.number=${version.value}
477+
|copyright.string=Copyright 2002-$currentYear, LAMP/EPFL
478+
|shell.banner=${shellBanner}
479+
|""".stripMargin
480+
}
481+
generatePropertiesFile(fileName, contents)
482+
}
483+
436484
def scalacOptionsDocSettings(includeExternalMappings: Boolean = true) = {
437485
val extMap = Seq("-external-mappings:" +
438486
(if (includeExternalMappings) ".*scala/.*::scaladoc3::https://dotty.epfl.ch/api/," else "") +
@@ -700,25 +748,7 @@ object Build {
700748
scalacOptions += "-Wconf:cat=deprecation&origin=scala\\.collection\\.mutable\\.AnyRefMap.*:s",
701749

702750
// Generate compiler.properties, used by sbt
703-
(Compile / resourceGenerators) += Def.task {
704-
import java.util._
705-
import java.text._
706-
val file = (Compile / resourceManaged).value / "compiler.properties"
707-
val dateFormat = new SimpleDateFormat("yyyyMMdd-HHmmss")
708-
dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"))
709-
val contents = //2.11.11.v20170413-090219-8a413ba7cc
710-
s"""version.number=${version.value}
711-
|maven.version.number=${version.value}
712-
|git.hash=${VersionUtil.gitHash}
713-
|copyright.string=Copyright 2002-$currentYear, LAMP/EPFL
714-
""".stripMargin
715-
716-
if (!(file.exists && IO.read(file) == contents)) {
717-
IO.write(file, contents)
718-
}
719-
720-
Seq(file)
721-
}.taskValue,
751+
(Compile / resourceGenerators) += generateCompilerProperties.taskValue,
722752

723753
// get libraries onboard
724754
libraryDependencies ++= Seq(
@@ -1916,6 +1946,8 @@ object Build {
19161946
customMimaReportBinaryIssues("MiMaFilters.Scala3Library"),
19171947
// Should we also patch .sjsir files
19181948
keepSJSIR := false,
1949+
// Generate library.properties, used by scala.util.Properties
1950+
Compile / resourceGenerators += generateLibraryProperties.taskValue
19191951
)
19201952

19211953
/* Configuration of the org.scala-lang:scala3-library_3:*.**.**-nonbootstrapped project */
@@ -2041,6 +2073,8 @@ object Build {
20412073
customMimaReportBinaryIssues("MiMaFilters.Scala3Library"),
20422074
// Should we also patch .sjsir files
20432075
keepSJSIR := false,
2076+
// Generate Scala 3 runtime properties overlay
2077+
Compile / resourceGenerators += generateLibraryProperties.taskValue,
20442078
)
20452079

20462080
/* Configuration of the org.scala-lang:scala3-library_3:*.**.**-bootstrapped project */
@@ -2444,25 +2478,7 @@ object Build {
24442478
// Project specific target folder. sbt doesn't like having two projects using the same target folder
24452479
target := target.value / "scala3-compiler-nonbootstrapped",
24462480
// Generate compiler.properties, used by sbt
2447-
Compile / resourceGenerators += Def.task {
2448-
import java.util._
2449-
import java.text._
2450-
val file = (Compile / resourceManaged).value / "compiler.properties"
2451-
val dateFormat = new SimpleDateFormat("yyyyMMdd-HHmmss")
2452-
dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"))
2453-
val contents = //2.11.11.v20170413-090219-8a413ba7cc
2454-
s"""version.number=${version.value}
2455-
|maven.version.number=${version.value}
2456-
|git.hash=${VersionUtil.gitHash}
2457-
|copyright.string=Copyright 2002-$currentYear, LAMP/EPFL
2458-
""".stripMargin
2459-
2460-
if (!(file.exists && IO.read(file) == contents)) {
2461-
IO.write(file, contents)
2462-
}
2463-
2464-
Seq(file)
2465-
}.taskValue,
2481+
Compile / resourceGenerators += generateCompilerProperties.taskValue,
24662482
// sbt adds all the projects to scala-tool config which breaks building the scalaInstance
24672483
// as a workaround, I build it manually by only adding the compiler
24682484
managedScalaInstance := false,
@@ -2612,25 +2628,7 @@ object Build {
26122628
// Project specific target folder. sbt doesn't like having two projects using the same target folder
26132629
target := target.value / "scala3-compiler-bootstrapped",
26142630
// Generate compiler.properties, used by sbt
2615-
Compile / resourceGenerators += Def.task {
2616-
import java.util._
2617-
import java.text._
2618-
val file = (Compile / resourceManaged).value / "compiler.properties"
2619-
val dateFormat = new SimpleDateFormat("yyyyMMdd-HHmmss")
2620-
dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"))
2621-
val contents = //2.11.11.v20170413-090219-8a413ba7cc
2622-
s"""version.number=${version.value}
2623-
|maven.version.number=${version.value}
2624-
|git.hash=${VersionUtil.gitHash}
2625-
|copyright.string=Copyright 2002-$currentYear, LAMP/EPFL
2626-
""".stripMargin
2627-
2628-
if (!(file.exists && IO.read(file) == contents)) {
2629-
IO.write(file, contents)
2630-
}
2631-
2632-
Seq(file)
2633-
}.taskValue,
2631+
Compile / resourceGenerators += generateCompilerProperties.taskValue,
26342632
// Configure to use the non-bootstrapped compiler
26352633
managedScalaInstance := false,
26362634
scalaInstance := {

repl/src/dotty/tools/repl/JLineTerminal.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ class JLineTerminal extends java.io.Closeable {
3838
else str
3939
protected def promptStr = "scala"
4040
private def prompt(using Context) = blue(s"\n$promptStr> ")
41-
private def newLinePrompt(using Context) = blue(" | ")
41+
private def newLinePrompt(using Context) = " "
4242

4343
/** Blockingly read line from `System.in`
4444
*

0 commit comments

Comments
 (0)