Skip to content

Commit 4cbf89f

Browse files
committed
Merge pull request scala#4784 from lrytz/merge-2.11-to-2.12-oct-5
Merge 2.11 to 2.12 oct 5
2 parents c390691 + e6917ac commit 4cbf89f

File tree

34 files changed

+291
-69
lines changed

34 files changed

+291
-69
lines changed

.gitattributes

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,24 @@
22
# this must be first so later entries will override it
33
* text=auto
44

5+
# check out text files with lf, not crlf, on Windows. (especially
6+
# important for Scala source files, since """ preserves line endings)
7+
text eol=lf
8+
59
# These files are text and should be normalized (convert crlf => lf)
6-
*.c text
7-
*.check text
8-
*.css text
9-
*.flags text
10-
*.html text
11-
*.java text
12-
*.js text
13-
*.policy text
14-
*.sbt text
15-
*.scala text
16-
*.sh text
17-
*.txt text
18-
*.xml text
10+
*.c eol=lf
11+
*.check eol=lf
12+
*.css eol=lf
13+
*.flags eol=lf
14+
*.html eol=lf
15+
*.java eol=lf
16+
*.js eol=lf
17+
*.policy eol=lf
18+
*.sbt eol=lf
19+
*.scala eol=lf
20+
*.sh eol=lf
21+
*.txt eol=lf
22+
*.xml eol=lf
1923

2024
# Windows-specific files get windows endings
2125
*.bat eol=crlf

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,10 @@ ideas and coordinate your effort with others.
154154

155155
NOTE: we are working on migrating the build to sbt.
156156

157+
If you are behind a HTTP proxy, include
158+
[`ANT_ARGS=-autoproxy`](https://ant.apache.org/manual/proxy.html) in
159+
your environment.
160+
157161
Run `ant build-opt` to build an optimized version of the compiler.
158162
Verify your build using `ant test-opt`.
159163

spec/08-pattern-matching.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -507,7 +507,7 @@ def f[B](t: Term[B]): B = t match {
507507
The expected type of the pattern `y: Number` is
508508
`Term[B]`. The type `Number` does not conform to
509509
`Term[B]`; hence Case 2 of the rules above
510-
applies. This means that `b` is treated as another type
510+
applies. This means that `B` is treated as another type
511511
variable for which subtype constraints are inferred. In our case the
512512
applicable constraint is `Number <: Term[B]`, which
513513
entails `B = Int`. Hence, `B` is treated in

src/compiler/scala/tools/ant/templates/tool-unix.tmpl

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,11 @@ if uname | grep -q ^MINGW; then
6767
mingw="$(uname)"
6868
fi
6969

70+
unset msys
71+
if uname | grep -q ^MSYS; then
72+
msys="$(uname)"
73+
fi
74+
7075
# Finding the root folder for this Scala distribution
7176
SCALA_HOME="$(findScalaHome)"
7277
SEP=":"
@@ -111,9 +116,9 @@ if [[ -n "$cygwin" ]]; then
111116
TOOL_CLASSPATH="$(cygpath --path --$format "$TOOL_CLASSPATH")"
112117
fi
113118

114-
if [[ -n "$cygwin$mingw" ]]; then
119+
if [[ -n "$cygwin$mingw$msys" ]]; then
115120
case "$TERM" in
116-
rxvt* | xterm*)
121+
rxvt* | xterm* | cygwin*)
117122
stty -icanon min 1 -echo
118123
WINDOWS_OPT="-Djline.terminal=unix"
119124
;;
@@ -182,10 +187,10 @@ fi
182187

183188
declare -a classpath_args
184189

185-
# default to the boot classpath for speed, except on cygwin/mingw because
190+
# default to the boot classpath for speed, except on cygwin/mingw/msys because
186191
# JLine on Windows requires a custom DLL to be loaded.
187192
unset usebootcp
188-
if [[ -z "$cygwin$mingw" ]]; then
193+
if [[ -z "$cygwin$mingw$msys" ]]; then
189194
usebootcp="true"
190195
fi
191196

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1690,7 +1690,10 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
16901690
try {
16911691
val stream = new FileOutputStream(file)
16921692
printer.setWriter(new PrintWriter(stream, true))
1693-
printer.printClass(cls)
1693+
try
1694+
printer.printClass(cls)
1695+
finally
1696+
stream.close()
16941697
informProgress(s"wrote $file")
16951698
} catch {
16961699
case e: IOException =>

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

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2692,7 +2692,10 @@ self =>
26922692
case t if t == SUPERTYPE || t == SUBTYPE || t == COMMA || t == RBRACE || isStatSep(t) =>
26932693
TypeDef(mods | Flags.DEFERRED, name, tparams, typeBounds())
26942694
case _ =>
2695-
syntaxErrorOrIncompleteAnd("`=', `>:', or `<:' expected", skipIt = true)(EmptyTree)
2695+
syntaxErrorOrIncompleteAnd("`=', `>:', or `<:' expected", skipIt = true)(
2696+
// assume a dummy type def so as to have somewhere to stash the annotations
2697+
TypeDef(mods, tpnme.ERROR, Nil, EmptyTree)
2698+
)
26962699
}
26972700
}
26982701
}
@@ -2725,7 +2728,10 @@ self =>
27252728
case CASEOBJECT =>
27262729
objectDef(pos, (mods | Flags.CASE) withPosition (Flags.CASE, tokenRange(in.prev /*scanner skips on 'case' to 'object', thus take prev*/)))
27272730
case _ =>
2728-
syntaxErrorOrIncompleteAnd("expected start of definition", skipIt = true)(EmptyTree)
2731+
syntaxErrorOrIncompleteAnd("expected start of definition", skipIt = true)(
2732+
// assume a class definition so as to have somewhere to stash the annotations
2733+
atPos(pos)(gen.mkClassDef(mods, tpnme.ERROR, Nil, Template(Nil, noSelfType, Nil)))
2734+
)
27292735
}
27302736
}
27312737

src/compiler/scala/tools/nsc/backend/jvm/analysis/ProdConsAnalyzerImpl.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -459,4 +459,4 @@ class InitialProducerSourceInterpreter extends SourceInterpreter {
459459
override def newExceptionValue(tryCatchBlockNode: TryCatchBlockNode, handlerFrame: Frame[_ <: Value], exceptionType: Type): SourceValue = {
460460
new SourceValue(1, ExceptionProducer(handlerFrame))
461461
}
462-
}
462+
}

src/compiler/scala/tools/nsc/transform/UnCurry.scala

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -475,13 +475,6 @@ abstract class UnCurry extends InfoTransform
475475
withNeedLift(needLift = true) { super.transform(tree) }
476476
else
477477
super.transform(tree)
478-
case UnApply(fn, args) =>
479-
val fn1 = transform(fn)
480-
val args1 = fn.symbol.name match {
481-
case nme.unapplySeq => transformArgs(tree.pos, fn.symbol, args, patmat.alignPatterns(global.typer.context, tree).expectedTypes)
482-
case _ => args
483-
}
484-
treeCopy.UnApply(tree, fn1, args1)
485478

486479
case Apply(fn, args) =>
487480
val needLift = needTryLift || !fn.symbol.isLabel // SI-6749, no need to lift in args to label jumps.

src/compiler/scala/tools/nsc/transform/patmat/PatternExpander.scala

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,25 @@ trait PatternExpander[Pattern, Type] {
8686
* @param fixed The non-sequence types which are extracted
8787
* @param repeated The sequence type which is extracted
8888
*/
89-
final case class Extractor(whole: Type, fixed: List[Type], repeated: Repeated) {
89+
final case class Extractor(whole: Type, fixed: List[Type], repeated: Repeated, typeOfSinglePattern: Type) {
9090
require(whole != NoType, s"expandTypes($whole, $fixed, $repeated)")
9191

92+
/** A pattern with arity-1 that doesn't match the arity of the Product-like result of the `get` method,
93+
* will match that result in its entirety. Example:
94+
*
95+
* {{{
96+
* warning: there was one deprecation warning; re-run with -deprecation for details
97+
* scala> object Extractor { def unapply(a: Any): Option[(Int, String)] = Some((1, "2")) }
98+
* defined object Extractor
99+
*
100+
* scala> "" match { case Extractor(x: Int, y: String) => }
101+
*
102+
* scala> "" match { case Extractor(xy : (Int, String)) => }
103+
* warning: there was one deprecation warning; re-run with -deprecation for details
104+
* }}}
105+
* */
106+
def asSinglePattern: Extractor = copy(fixed = List(typeOfSinglePattern))
107+
92108
def productArity = fixed.length
93109
def hasSeq = repeated.exists
94110
def elementType = repeated.elementType

src/compiler/scala/tools/nsc/transform/patmat/ScalacPatternExpanders.scala

Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,9 @@ trait ScalacPatternExpanders {
4343
orElse definitions.elementType(ArrayClass, seq)
4444
)
4545
}
46-
def newExtractor(whole: Type, fixed: List[Type], repeated: Repeated): Extractor =
47-
logResult(s"newExtractor($whole, $fixed, $repeated")(Extractor(whole, fixed, repeated))
46+
def newExtractor(whole: Type, fixed: List[Type], repeated: Repeated, typeOfSinglePattern: Type): Extractor =
47+
logResult(s"newExtractor($whole, $fixed, $repeated, $typeOfSinglePattern")(Extractor(whole, fixed, repeated, typeOfSinglePattern))
48+
def newExtractor(whole: Type, fixed: List[Type], repeated: Repeated): Extractor = newExtractor(whole, fixed, repeated, tupleType(fixed))
4849

4950
// Turn Seq[A] into Repeated(Seq[A], A, A*)
5051
def repeatedFromSeq(seqType: Type): Repeated = {
@@ -73,26 +74,27 @@ trait ScalacPatternExpanders {
7374
* Unfortunately the MethodType does not carry the information of whether
7475
* it was unapplySeq, so we have to funnel that information in separately.
7576
*/
76-
def unapplyMethodTypes(whole: Type, result: Type, isSeq: Boolean): Extractor = {
77-
val expanded = (
78-
if (result =:= BooleanTpe) Nil
79-
else typeOfMemberNamedGet(result) match {
77+
def unapplyMethodTypes(context: Context, whole: Type, result: Type, isSeq: Boolean): Extractor = {
78+
if (result =:= BooleanTpe) newExtractor(whole, Nil, NoRepeated)
79+
else {
80+
val getResult = typeOfMemberNamedGet(result)
81+
def noGetError() = {
82+
val name = "unapply" + (if (isSeq) "Seq" else "")
83+
context.error(context.tree.pos, s"The result type of an $name method must contain a member `get` to be used as an extractor pattern, no such member exists in ${result}")
84+
}
85+
val expanded = getResult match {
86+
case global.NoType => noGetError(); Nil
8087
case rawGet if !hasSelectors(rawGet) => rawGet :: Nil
8188
case rawGet => typesOfSelectors(rawGet)
8289
}
83-
)
84-
expanded match {
85-
case init :+ last if isSeq => newExtractor(whole, init, repeatedFromSeq(last))
86-
case tps => newExtractor(whole, tps, NoRepeated)
90+
expanded match {
91+
case init :+ last if isSeq => newExtractor(whole, init, repeatedFromSeq(last), getResult)
92+
case tps => newExtractor(whole, tps, NoRepeated, getResult)
93+
}
8794
}
8895
}
8996
}
9097
object alignPatterns extends ScalacPatternExpander {
91-
/** Converts a T => (A, B, C) extractor to a T => ((A, B, CC)) extractor.
92-
*/
93-
def tupleExtractor(extractor: Extractor): Extractor =
94-
extractor.copy(fixed = tupleType(extractor.fixed) :: Nil)
95-
9698
private def validateAligned(context: Context, tree: Tree, aligned: Aligned): Aligned = {
9799
import aligned._
98100

@@ -129,8 +131,8 @@ trait ScalacPatternExpanders {
129131
val isUnapply = sel.symbol.name == nme.unapply
130132

131133
val extractor = sel.symbol.name match {
132-
case nme.unapply => unapplyMethodTypes(firstParamType(fn.tpe), sel.tpe, isSeq = false)
133-
case nme.unapplySeq => unapplyMethodTypes(firstParamType(fn.tpe), sel.tpe, isSeq = true)
134+
case nme.unapply => unapplyMethodTypes(context, firstParamType(fn.tpe), sel.tpe, isSeq = false)
135+
case nme.unapplySeq => unapplyMethodTypes(context, firstParamType(fn.tpe), sel.tpe, isSeq = true)
134136
case _ => applyMethodTypes(fn.tpe)
135137
}
136138

@@ -142,12 +144,14 @@ trait ScalacPatternExpanders {
142144
def acceptMessage = if (extractor.isErroneous) "" else s" to hold ${extractor.offeringString}"
143145
val requiresTupling = isUnapply && patterns.totalArity == 1 && productArity > 1
144146

145-
if (requiresTupling && effectivePatternArity(args) == 1) {
146-
val sym = sel.symbol.owner
147-
currentRun.reporting.deprecationWarning(sel.pos, sym, s"${sym} expects $productArity patterns$acceptMessage but crushing into $productArity-tuple to fit single pattern (SI-6675)")
148-
}
149-
150-
val normalizedExtractor = if (requiresTupling) tupleExtractor(extractor) else extractor
147+
val normalizedExtractor = if (requiresTupling) {
148+
val tupled = extractor.asSinglePattern
149+
if (effectivePatternArity(args) == 1 && isTupleType(extractor.typeOfSinglePattern)) {
150+
val sym = sel.symbol.owner
151+
currentRun.reporting.deprecationWarning(sel.pos, sym, s"${sym} expects $productArity patterns$acceptMessage but crushing into $productArity-tuple to fit single pattern (SI-6675)")
152+
}
153+
tupled
154+
} else extractor
151155
validateAligned(context, fn, Aligned(patterns, normalizedExtractor))
152156
}
153157

0 commit comments

Comments
 (0)