Skip to content

Commit 2ffe816

Browse files
committed
Merge branch 'main' into fix-unsafe-null
2 parents 9fdf142 + f906270 commit 2ffe816

File tree

138 files changed

+2631
-1959
lines changed

Some content is hidden

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

138 files changed

+2631
-1959
lines changed

.github/ISSUE_TEMPLATE/bug.md

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,33 @@ assignees: ''
99

1010
## Compiler version
1111

12-
If you're not sure what version you're using, run `print scalaVersion` from sbt
13-
(if you're running scalac manually, use `scalac -version` instead).
12+
If you're not sure which version you're using, run `print scalaVersion` from sbt.
13+
(If you're running scalac manually, use `scalac -version` instead.)
14+
15+
If possible, check if your issue appears in the nightly version of the compiler! For example, in Scala CLI (the `scala`/`scala-cli` runner script), you can use `//> using scala 3.nightly` (or `-S 3.nightly` from the command line) to grab the latest one.
1416

1517
## Minimized code
1618

1719
<!--
1820
This code should be self contained, compilable (with possible failures) and as small as possible.
1921
20-
Ideally, we should be able to just copy this code in a file and run `scalac` (and maybe `scala`) to reproduce the issue.
22+
Ideally, we should be able to just copy this code to a file and run `scalac` (and maybe `scala`) to reproduce the issue.
23+
24+
If the code has external dependencies, please provide the Scala CLI directives (or SBT/other build tool configuration) that describe them.
25+
Also note that it's easier and faster for the maintenance team to address issues minimised to reproduce bugs without external dependencies.
26+
27+
It's most convenient to also include `using` directives for the Scala version that demonstrates the problem,
28+
any compiler command-line options, as well as dependencies. An example is provided.
29+
30+
It's also fine to paste the transcript of a REPL session. Note that some bugs may be specific to the REPL.
2131
-->
2232

23-
```Scala
24-
println("hello, world")
33+
```scala
34+
//> using scala 3.7.0
35+
//> using options -Wall -Werror
36+
//> using dep com.outr::scribe:3.16.1
37+
38+
@main def test = println("hello, world")
2539
```
2640

2741
## Output

compiler/src/dotty/tools/MainGenericRunner.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ object MainGenericRunner {
158158
.withScriptArgs(tail*)
159159
.noSave // -save not useful here
160160
case arg :: tail =>
161-
val line = Try(Source.fromFile(arg).getLines.toList).toOption.flatMap(_.headOption)
161+
val line = Try(Source.fromFile(arg).getLines().toList).toOption.flatMap(_.headOption)
162162
lazy val hasScalaHashbang = { val s = line.getOrElse("") ; s.startsWith("#!") && s.contains("scala") }
163163
if arg.endsWith(".scala") || arg.endsWith(".sc") || hasScalaHashbang then
164164
settings

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

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -150,13 +150,12 @@ object Primitives {
150150
case object XOR extends LogicalOp
151151

152152
/** Signals the beginning of a series of concatenations.
153-
* On the JVM platform, it should create a new StringBuffer
154-
*/
153+
* On the JVM platform, it should create a new StringBuilder.
154+
*/
155155
case object StartConcat extends Primitive
156156

157-
/**
158-
* type: (buf) => STR
159-
* jvm : It should turn the StringBuffer into a String.
157+
/** type: (buf) => STR
158+
* jvm : It should turn the StringBuilder into a String.
160159
*/
161160
case object EndConcat extends Primitive
162161

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

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -703,7 +703,7 @@ object desugar {
703703
def isNonEnumCase = !isEnumCase && (isCaseClass || isCaseObject)
704704
val isValueClass = parents.nonEmpty && isAnyVal(parents.head)
705705
// This is not watertight, but `extends AnyVal` will be replaced by `inline` later.
706-
val caseClassInScala2Library = isCaseClass && ctx.settings.YcompileScala2Library.value
706+
val caseClassInScala2Library = isCaseClass && Feature.shouldBehaveAsScala2
707707

708708
val originalTparams = constr1.leadingTypeParams
709709
val originalVparamss = asTermOnly(constr1.trailingParamss)
@@ -922,7 +922,7 @@ object desugar {
922922
val copyRestParamss = derivedVparamss.tail.nestedMap(vparam =>
923923
cpy.ValDef(vparam)(rhs = EmptyTree))
924924
var flags = Synthetic | constr1.mods.flags & copiedAccessFlags
925-
if ctx.settings.YcompileScala2Library.value then flags &~= Private
925+
if Feature.shouldBehaveAsScala2 then flags &~= Private
926926
DefDef(
927927
nme.copy,
928928
joinParams(derivedTparams, copyFirstParams :: copyRestParamss),
@@ -983,7 +983,7 @@ object desugar {
983983
else {
984984
val appMods =
985985
var flags = Synthetic | constr1.mods.flags & copiedAccessFlags
986-
if ctx.settings.YcompileScala2Library.value then flags &~= Private
986+
if Feature.shouldBehaveAsScala2 then flags &~= Private
987987
Modifiers(flags).withPrivateWithin(constr1.mods.privateWithin)
988988
val appParamss =
989989
derivedVparamss.nestedZipWithConserve(constrVparamss)((ap, cp) =>
@@ -1066,7 +1066,7 @@ object desugar {
10661066
paramss // drop leading () that got inserted by class
10671067
// TODO: drop this once we do not silently insert empty class parameters anymore
10681068
case paramss => paramss
1069-
val finalFlag = if ctx.settings.YcompileScala2Library.value then EmptyFlags else Final
1069+
val finalFlag = if Feature.shouldBehaveAsScala2 then EmptyFlags else Final
10701070
// implicit wrapper is typechecked in same scope as constructor, so
10711071
// we can reuse the constructor parameters; no derived params are needed.
10721072
DefDef(
@@ -1868,18 +1868,18 @@ object desugar {
18681868
/** Map n-ary function `(x1: T1, ..., xn: Tn) => body` where n != 1 to unary function as follows:
18691869
*
18701870
* (x$1: (T1, ..., Tn)) => {
1871-
* def x1: T1 = x$1._1
1871+
* val x1: T1 = x$1._1
18721872
* ...
1873-
* def xn: Tn = x$1._n
1873+
* val xn: Tn = x$1._n
18741874
* body
18751875
* }
18761876
*
18771877
* or if `isGenericTuple`
18781878
*
18791879
* (x$1: (T1, ... Tn) => {
1880-
* def x1: T1 = x$1.apply(0)
1880+
* val x1: T1 = x$1.apply(0)
18811881
* ...
1882-
* def xn: Tn = x$1.apply(n-1)
1882+
* val xn: Tn = x$1.apply(n-1)
18831883
* body
18841884
* }
18851885
*

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

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import Annotations.Annotation
99
import NameKinds.ContextBoundParamName
1010
import typer.ConstFold
1111
import reporting.trace
12+
import config.Feature
1213

1314
import Decorators.*
1415
import Constants.Constant
@@ -264,6 +265,19 @@ trait TreeInfo[T <: Untyped] { self: Trees.Instance[T] =>
264265
case _ => false
265266
}
266267

268+
/** Expression was written `e: Unit` to quell warnings. Looks into adapted tree. */
269+
def isAscribedToUnit(tree: Tree): Boolean =
270+
import typer.Typer.AscribedToUnit
271+
tree.hasAttachment(AscribedToUnit)
272+
|| {
273+
def loop(tree: Tree): Boolean = tree match
274+
case Apply(fn, _) => fn.hasAttachment(AscribedToUnit) || loop(fn)
275+
case TypeApply(fn, _) => fn.hasAttachment(AscribedToUnit) || loop(fn)
276+
case Block(_, expr) => expr.hasAttachment(AscribedToUnit) || loop(expr)
277+
case _ => false
278+
loop(tree)
279+
}
280+
267281
/** Does this CaseDef catch Throwable? */
268282
def catchesThrowable(cdef: CaseDef)(using Context): Boolean =
269283
catchesAllOf(cdef, defn.ThrowableType)
@@ -466,7 +480,7 @@ trait UntypedTreeInfo extends TreeInfo[Untyped] { self: Trees.Instance[Untyped]
466480
*/
467481
private def defKind(tree: Tree)(using Context): FlagSet = unsplice(tree) match {
468482
case EmptyTree | _: Import => NoInitsInterface
469-
case tree: TypeDef if ctx.settings.YcompileScala2Library.value =>
483+
case tree: TypeDef if Feature.shouldBehaveAsScala2 =>
470484
if (tree.isClassDef) EmptyFlags else NoInitsInterface
471485
case tree: TypeDef => if (tree.isClassDef) NoInits else NoInitsInterface
472486
case tree: DefDef =>
@@ -479,7 +493,7 @@ trait UntypedTreeInfo extends TreeInfo[Untyped] { self: Trees.Instance[Untyped]
479493
NoInitsInterface
480494
else if tree.mods.is(Given) && tree.paramss.isEmpty then
481495
EmptyFlags // might become a lazy val: TODO: check whether we need to suppress NoInits once we have new lazy val impl
482-
else if ctx.settings.YcompileScala2Library.value then
496+
else if Feature.shouldBehaveAsScala2 then
483497
EmptyFlags
484498
else
485499
NoInits

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

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ class CCState:
118118

119119
private var capIsRoot: Boolean = false
120120

121-
private var ignoreFreshLevels: Boolean = false
121+
private var collapseFresh: Boolean = false
122122

123123
object CCState:
124124

@@ -164,20 +164,21 @@ object CCState:
164164
/** Is `caps.cap` a root capability that is allowed to subsume other capabilities? */
165165
def capIsRoot(using Context): Boolean = ccState.capIsRoot
166166

167-
/** Run `op` under the assumption that all root.Fresh instances are equal.
167+
/** Run `op` under the assumption that all FreshCap instances are equal
168+
* to each other and to GlobalCap.
168169
* Needed to make override checking of types containing fresh work.
169170
* Asserted in override checking, tested in maxSubsumes.
170171
* Is this sound? Test case is neg-custom-args/captures/leaked-curried.scala.
171172
*/
172-
inline def ignoringFreshLevels[T](op: => T)(using Context): T =
173+
inline def withCollapsedFresh[T](op: => T)(using Context): T =
173174
if isCaptureCheckingOrSetup then
174175
val ccs = ccState
175-
val saved = ccs.ignoreFreshLevels
176-
ccs.ignoreFreshLevels = true
177-
try op finally ccs.ignoreFreshLevels = saved
176+
val saved = ccs.collapseFresh
177+
ccs.collapseFresh = true
178+
try op finally ccs.collapseFresh = saved
178179
else op
179180

180-
/** Should all root.Fresh instances be treated equal? */
181-
def ignoreFreshLevels(using Context): Boolean = ccState.ignoreFreshLevels
181+
/** Should all FreshCap instances be treated as equal to GlobalCap? */
182+
def collapseFresh(using Context): Boolean = ccState.collapseFresh
182183

183184
end CCState

0 commit comments

Comments
 (0)