Skip to content

Commit 24ec8f1

Browse files
authored
Merge pull request scala#7009 from lrytz/merge-2.12-to-2.13-aug-7
Merge 2.12 to 2.13 aug 7 [ci: last-only]
2 parents e444958 + 005afb8 commit 24ec8f1

Some content is hidden

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

41 files changed

+563
-217
lines changed

build.sbt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -726,6 +726,8 @@ lazy val test = project
726726
// test sources are compiled in partest run, not here
727727
sources in IntegrationTest := Seq.empty,
728728
fork in IntegrationTest := true,
729+
// enable this in 2.13, when tests pass
730+
//scalacOptions in Compile += "-Yvalidate-pos:parser,typer",
729731
javaOptions in IntegrationTest ++= List("-Xmx2G", "-Dpartest.exec.in.process=true", "-Dfile.encoding=UTF-8", "-Duser.language=en", "-Duser.country=US"),
730732
testOptions in IntegrationTest += Tests.Argument("-Dfile.encoding=UTF-8", "-Duser.language=en", "-Duser.country=US"),
731733
testFrameworks += new TestFramework("scala.tools.partest.sbt.Framework"),

project/ScalaOptionParser.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ object ScalaOptionParser {
9797
"-Ypresentation-log", "-Ypresentation-replay", "-Yrepl-outdir", "-d", "-dependencyfile", "-encoding", "-Xscript")
9898
private def pathSettingNames = List("-bootclasspath", "-classpath", "-extdirs", "-javabootclasspath", "-javaextdirs", "-sourcepath", "-toolcp")
9999
private val phases = List("all", "parser", "namer", "packageobjects", "typer", "patmat", "superaccessors", "extmethods", "pickler", "refchecks", "uncurry", "tailcalls", "specialize", "explicitouter", "erasure", "posterasure", "fields", "lambdalift", "constructors", "flatten", "mixin", "cleanup", "delambdafy", "icode", "jvm", "terminal")
100-
private val phaseSettings = List("-Xprint-icode", "-Ystop-after", "-Yskip", "-Yshow", "-Ystop-before", "-Ybrowse", "-Ylog", "-Ycheck", "-Xprint")
100+
private val phaseSettings = List("-Xprint-icode", "-Ystop-after", "-Yskip", "-Yshow", "-Ystop-before", "-Ybrowse", "-Ylog", "-Ycheck", "-Xprint", "-Yvalidate-pos")
101101
private def multiStringSettingNames = List("-Xmacro-settings", "-Xplugin", "-Xplugin-disable", "-Xplugin-require", "-Ywarn-unused")
102102
private def intSettingNames = List("-Xmax-classfile-name", "-Xelide-below", "-Ypatmat-exhaust-depth", "-Ypresentation-delay", "-Yrecursion")
103103
private def choiceSettingNames = Map[String, List[String]](

src/compiler/scala/tools/nsc/Global.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1473,6 +1473,9 @@ class Global(var currentSettings: Settings, reporter0: LegacyReporter)
14731473
if (settings.browse containsPhase globalPhase)
14741474
treeBrowser browse (phase.name, units)
14751475

1476+
if ((settings.Yvalidatepos containsPhase globalPhase) && !reporter.hasErrors)
1477+
currentRun.units.foreach(unit => validatePositions(unit.body))
1478+
14761479
// move the pointer
14771480
globalPhase = globalPhase.next
14781481

src/compiler/scala/tools/nsc/ast/parser/SyntaxAnalyzer.scala

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,6 @@ abstract class SyntaxAnalyzer extends SubComponent with Parsers with MarkupParse
9898
if (unit.body == EmptyTree)
9999
unit.body = initialUnitBody(unit)
100100

101-
if (settings.Yrangepos && !reporter.hasErrors)
102-
validatePositions(unit.body)
103-
104101
if (settings.Ymemberpos.isSetByUser)
105102
new MemberPosReporter(unit) show (style = settings.Ymemberpos.value)
106103
}

src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@ abstract class BCodeHelpers extends BCodeIdiomatic {
3131
* True for classes generated by the Scala compiler that are considered top-level in terms of
3232
* the InnerClass / EnclosingMethod classfile attributes. See comment in BTypes.
3333
*/
34-
def considerAsTopLevelImplementationArtifact(classSym: Symbol) = classSym.isSpecialized
34+
def considerAsTopLevelImplementationArtifact(classSym: Symbol) =
35+
classSym.isSpecialized ||
36+
classSym.isSynthetic && classSym.name.containsName(nme.delayedInitArg.toTypeName)
3537

3638
/**
3739
* Cache the value of delambdafy == "inline" for each run. We need to query this value many

src/compiler/scala/tools/nsc/settings/ScalaSettings.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,8 @@ trait ScalaSettings extends AbsScalaSettings
217217
val stopAfter = PhasesSetting ("-Ystop-after", "Stop after") withAbbreviation ("-stop") // backward compat
218218
val stopBefore = PhasesSetting ("-Ystop-before", "Stop before")
219219
val Yrangepos = BooleanSetting ("-Yrangepos", "Use range positions for syntax trees.")
220-
val Ymemberpos = StringSetting ("-Yshow-member-pos", "output style", "Show start and end positions of members", "") withPostSetHook (_ => Yrangepos.value = true)
220+
val Yvalidatepos = PhasesSetting ("-Yvalidate-pos", s"Validate positions after the given phases (implies ${Yrangepos.name})") withPostSetHook (_ => Yrangepos.value = true)
221+
val Ymemberpos = StringSetting ("-Yshow-member-pos", "output style", s"Show start and end positions of members (implies ${Yrangepos.name})", "") withPostSetHook (_ => Yrangepos.value = true)
221222
val Yreifycopypaste = BooleanSetting ("-Yreify-copypaste", "Dump the reified trees in copypasteable representation.")
222223
val Ymacroexpand = ChoiceSetting ("-Ymacro-expand", "policy", "Control expansion of macros, useful for scaladoc and presentation compiler.", List(MacroExpand.Normal, MacroExpand.None, MacroExpand.Discard), MacroExpand.Normal)
223224
val Ymacronoexpand = BooleanSetting ("-Ymacro-no-expand", "Don't expand macros. Might be useful for scaladoc and presentation compiler, but will crash anything which uses macros and gets past typer.") withDeprecationMessage(s"Use ${Ymacroexpand.name}:${MacroExpand.None}") withPostSetHook(_ => Ymacroexpand.value = MacroExpand.None)

src/compiler/scala/tools/nsc/typechecker/Analyzer.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,6 @@ trait Analyzer extends AnyRef
104104
try {
105105
val typer = newTyper(rootContext(unit))
106106
unit.body = typer.typed(unit.body)
107-
if (global.settings.Yrangepos && !global.reporter.hasErrors) global.validatePositions(unit.body)
108107
for (workItem <- unit.toCheck) workItem()
109108
if (settings.warnUnusedImport)
110109
warnUnusedImports(unit)

src/compiler/scala/tools/nsc/typechecker/Implicits.scala

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -402,10 +402,12 @@ trait Implicits {
402402
/** The type parameters to instantiate */
403403
val undetParams = if (isView) Nil else context.outer.undetparams
404404
val wildPt = approximate(pt)
405-
private val ptFunctionArity: Int = {
406-
val dealiased = pt.dealiasWiden
405+
private[this] def functionArityOf(tp: Type): Int = {
406+
val dealiased = tp.dealiasWiden
407407
if (isFunctionTypeDirect(dealiased)) dealiased.typeArgs.length - 1 else -1
408408
}
409+
private val cachedPtFunctionArity: Int = functionArityOf(pt)
410+
final def functionArity(tp: Type): Int = if (tp eq pt) cachedPtFunctionArity else functionArityOf(tp)
409411

410412
private val stableRunDefsForImport = currentRun.runDefinitions
411413
import stableRunDefsForImport._
@@ -661,6 +663,7 @@ trait Implicits {
661663
if (sym.isAliasType) loop(tp, pt.dealias)
662664
else if (sym.isAbstractType) loop(tp, pt.bounds.lo)
663665
else {
666+
val ptFunctionArity = functionArity(pt)
664667
ptFunctionArity > 0 && hasLength(params, ptFunctionArity) && {
665668
var ps = params
666669
var as = args
@@ -1177,11 +1180,12 @@ trait Implicits {
11771180
* bound, the implicits infos which are members of these companion objects.
11781181
*/
11791182
private def companionImplicitMap(tp: Type): InfoMap = {
1183+
val isScala213 = settings.isScala213
11801184

11811185
/* Populate implicit info map by traversing all parts of type `tp`.
11821186
* Parameters as for `getParts`.
11831187
*/
1184-
def getClassParts(tp: Type)(implicit infoMap: InfoMap, seen: mutable.Set[Type], pending: Set[Symbol]) = tp match {
1188+
def getClassParts(tp: Type)(implicit infoMap: InfoMap, seen: mutable.HashSet[Type], pending: Set[Symbol]) = tp match {
11851189
case TypeRef(pre, sym, args) =>
11861190
val infos1 = infoMap.get(sym).getOrElse(Nil)
11871191
if(!infos1.exists(pre =:= _.pre.prefix)) {
@@ -1201,9 +1205,9 @@ trait Implicits {
12011205
infos1.filter(_.dependsOnPrefix) ++ infos.filter(_.dependsOnPrefix)
12021206
}
12031207
if(mergedInfos.isEmpty)
1204-
infoMap += (sym -> List(SearchedPrefixImplicitInfo(pre)))
1208+
infoMap(sym) = List(SearchedPrefixImplicitInfo(pre))
12051209
else
1206-
infoMap += (sym -> mergedInfos)
1210+
infoMap(sym) = mergedInfos
12071211
}
12081212
// Only strip annotations on the infrequent path
12091213
val bts = (if(infos1.isEmpty) tp else tp.map(_.withoutAnnotations)).baseTypeSeq
@@ -1224,14 +1228,11 @@ trait Implicits {
12241228
* @param pending The set of static symbols for which we are currently trying to collect their parts
12251229
* in order to cache them in infoMapCache
12261230
*/
1227-
def getParts(tp: Type)(implicit infoMap: InfoMap, seen: mutable.Set[Type], pending: Set[Symbol]): Unit = {
1228-
if (seen(tp))
1229-
return
1230-
seen += tp
1231-
tp match {
1231+
def getParts(tp: Type)(implicit infoMap: InfoMap, seen: mutable.HashSet[Type], pending: Set[Symbol]): Unit = {
1232+
if (seen add tp) tp match {
12321233
case TypeRef(pre, sym, args) =>
12331234
if (sym.isClass && !sym.isRoot &&
1234-
(settings.isScala213 || !sym.isAnonOrRefinementClass)) {
1235+
(isScala213 || !sym.isAnonOrRefinementClass)) {
12351236
if (sym.isStatic && !(pending contains sym))
12361237
infoMap ++= {
12371238
infoMapCache get sym match {
@@ -1254,7 +1255,7 @@ trait Implicits {
12541255
// - if `T` is an abstract type, the parts of its upper bound;
12551256
getParts(tp.bounds.hi)
12561257

1257-
if(settings.isScala213) {
1258+
if (isScala213) {
12581259
// - if `T` is a parameterized type `S[T1,…,Tn]`, the union of the parts of `S` and `T1,…,Tn`
12591260
args foreach getParts
12601261

src/compiler/scala/tools/nsc/typechecker/RefChecks.scala

Lines changed: 45 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1391,18 +1391,46 @@ abstract class RefChecks extends Transform {
13911391
}
13921392
}
13931393

1394-
private def checkAnnotations(tpes: List[Type], tree: Tree) = tpes foreach { tp =>
1395-
checkTypeRef(tp, tree, skipBounds = false)
1396-
checkTypeRefBounds(tp, tree)
1397-
}
1398-
private def doTypeTraversal(tree: Tree)(f: Type => Unit) = if (!inPattern) tree.tpe foreach f
1399-
14001394
private def applyRefchecksToAnnotations(tree: Tree): Unit = {
1401-
def applyChecks(annots: List[AnnotationInfo]) = {
1402-
checkAnnotations(annots map (_.atp), tree)
1403-
transformTrees(annots flatMap (_.args))
1395+
def applyChecks(annots: List[AnnotationInfo]): List[AnnotationInfo] = {
1396+
annots.foreach { ann =>
1397+
checkTypeRef(ann.tpe, tree, skipBounds = false)
1398+
checkTypeRefBounds(ann.tpe, tree)
1399+
}
1400+
1401+
annots
1402+
.map(_.transformArgs(transformTrees))
1403+
.groupBy(_.symbol)
1404+
.flatMap((groupRepeatableAnnotations _).tupled)
1405+
.toList
14041406
}
14051407

1408+
// assumes non-empty `anns`
1409+
def groupRepeatableAnnotations(sym: Symbol, anns: List[AnnotationInfo]): List[AnnotationInfo] =
1410+
if (!sym.isJavaDefined) anns else anns match {
1411+
case single :: Nil => anns
1412+
case multiple =>
1413+
sym.getAnnotation(AnnotationRepeatableAttr) match {
1414+
case Some(repeatable) =>
1415+
repeatable.assocs.collectFirst {
1416+
case (nme.value, LiteralAnnotArg(Constant(c: Type))) => c
1417+
} match {
1418+
case Some(container) =>
1419+
val assocs = List(
1420+
nme.value -> ArrayAnnotArg(multiple.map(NestedAnnotArg(_)).toArray)
1421+
)
1422+
AnnotationInfo(container, args = Nil, assocs = assocs) :: Nil
1423+
case None =>
1424+
devWarning(s"@Repeatable $sym had no containing class")
1425+
multiple
1426+
}
1427+
1428+
case None =>
1429+
reporter.error(tree.pos, s"$sym may not appear multiple times on ${tree.symbol}")
1430+
multiple
1431+
}
1432+
}
1433+
14061434
def checkIsElidable(sym: Symbol): Unit = if (sym ne null) sym.elisionLevel.foreach { level =>
14071435
if (!sym.isMethod || sym.isAccessor || sym.isLazy || sym.isDeferred) {
14081436
val rest = if (sym.isDeferred) " The annotation affects only the annotated method, not overriding methods in subclasses." else ""
@@ -1414,7 +1442,7 @@ abstract class RefChecks extends Transform {
14141442
tree match {
14151443
case m: MemberDef =>
14161444
val sym = m.symbol
1417-
applyChecks(sym.annotations)
1445+
sym.setAnnotations(applyChecks(sym.annotations))
14181446

14191447
// validate implicitNotFoundMessage and implicitAmbiguousMessage
14201448
if (settings.lintImplicitNotFound) {
@@ -1441,11 +1469,12 @@ abstract class RefChecks extends Transform {
14411469
}
14421470
}
14431471

1444-
doTypeTraversal(tree) {
1445-
case tp @ AnnotatedType(annots, _) =>
1446-
applyChecks(annots)
1447-
case tp =>
1448-
}
1472+
if (!inPattern)
1473+
tree.setType(tree.tpe map {
1474+
case AnnotatedType(anns, ul) =>
1475+
AnnotatedType(applyChecks(anns), ul)
1476+
case tp => tp
1477+
})
14491478
case _ =>
14501479
}
14511480
}
@@ -1706,7 +1735,7 @@ abstract class RefChecks extends Transform {
17061735
var skipBounds = false
17071736
// check all bounds, except those that are existential type parameters
17081737
// or those within typed annotated with @uncheckedBounds
1709-
doTypeTraversal(tree) {
1738+
if (!inPattern) tree.tpe foreach {
17101739
case tp @ ExistentialType(tparams, tpe) =>
17111740
existentialParams ++= tparams
17121741
case ann: AnnotatedType if ann.hasAnnotation(UncheckedBoundsClass) =>

src/interactive/scala/tools/nsc/interactive/ContextTrees.scala

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -108,10 +108,14 @@ trait ContextTrees { self: Global =>
108108
*/
109109
def addContext(contexts: Contexts, context: Context): Unit = {
110110
val cpos = context.tree.pos
111-
if (cpos.isTransparent)
112-
for (t <- context.tree.children flatMap solidDescendants)
113-
addContext(contexts, context, t.pos)
114-
else
111+
if (cpos.isTransparent) {
112+
val traverser = new ChildSolidDescendantsCollector() {
113+
override def traverseSolidChild(t: Tree): Unit = {
114+
addContext(contexts, context, t.pos)
115+
}
116+
}
117+
traverser.apply(context.tree)
118+
} else
115119
addContext(contexts, context, cpos)
116120
}
117121

src/library/scala/Enumeration.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ import scala.util.matching.Regex
2727
* `Value` type member of the enumeration (`Value` selected on the stable
2828
* identifier path of the enumeration instance).
2929
*
30+
* Values SHOULD NOT be added to an enumeration after its construction;
31+
* doing so makes the enumeration thread-unsafe. If values are added to an
32+
* enumeration from multiple threads (in a non-synchronized fashion) after
33+
* construction, the behavior of the enumeration is undefined.
34+
*
3035
* @example {{{
3136
* // Define a new enumeration with a type alias and work with the full set of enumerated values
3237
* object WeekDay extends Enumeration {

src/library/scala/collection/immutable/HashMap.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ object HashMap extends MapFactory[HashMap] {
312312
protected def merge0[V1 >: V](that: HashMap[K, V1], level: Int, merger: Merger[K, V1]): HashMap[K, V1] = {
313313
// this can be made more efficient by passing the entire ListMap at once
314314
var m = that
315-
for (p <- kvs) m = m.updated0(p._1, this.hash, level, p._2, p, merger)
315+
for (p <- kvs) m = m.updated0(p._1, this.hash, level, p._2, p, merger.invert)
316316
m
317317
}
318318

src/library/scala/collection/mutable/ArrayBuilder.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,9 @@ object ArrayBuilder {
9898
protected var elems: Array[T] = _
9999

100100
private def mkArray(size: Int): Array[T] = {
101-
val newelems = new Array[T](size)
102-
if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size)
103-
newelems
101+
if (capacity == size && capacity > 0) elems
102+
else if (elems eq null) new Array[T](size)
103+
else java.util.Arrays.copyOf[T](elems, size)
104104
}
105105

106106
protected[this] def resize(size: Int): Unit = {

src/reflect/scala/reflect/internal/AnnotationInfos.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,9 @@ trait AnnotationInfos extends api.Annotations { self: SymbolTable =>
291291
def argAtIndex(index: Int): Option[Tree] =
292292
if (index < args.size) Some(args(index)) else None
293293

294+
def transformArgs(f: List[Tree] => List[Tree]): AnnotationInfo =
295+
new CompleteAnnotationInfo(atp, f(args), assocs)
296+
294297
override def hashCode = atp.## + args.## + assocs.##
295298
override def equals(other: Any) = other match {
296299
case x: AnnotationInfo => (atp == x.atp) && (args == x.args) && (assocs == x.assocs)

src/reflect/scala/reflect/internal/Definitions.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1152,9 +1152,10 @@ trait Definitions extends api.StandardDefinitions {
11521152
lazy val ConstantAnnotationClass = getClassIfDefined("scala.annotation.ConstantAnnotation")
11531153
lazy val StaticAnnotationClass = requiredClass[scala.annotation.StaticAnnotation]
11541154

1155-
// Java retention annotations
1155+
// Java annotation annotations
11561156
lazy val AnnotationRetentionAttr = requiredClass[java.lang.annotation.Retention]
11571157
lazy val AnnotationRetentionPolicyAttr = requiredClass[java.lang.annotation.RetentionPolicy]
1158+
lazy val AnnotationRepeatableAttr = requiredClass[java.lang.annotation.Repeatable]
11581159

11591160
// Annotations
11601161
lazy val ElidableMethodClass = requiredClass[scala.annotation.elidable]

0 commit comments

Comments
 (0)