diff options
author | Lukas Rytz <lukas.rytz@typesafe.com> | 2014-11-05 16:27:40 +0100 |
---|---|---|
committer | Lukas Rytz <lukas.rytz@typesafe.com> | 2014-11-05 16:27:40 +0100 |
commit | 494914346ed6f27b44283f4850383582a7a7f6d1 (patch) | |
tree | 711a30c845dea425c0879552082f88ddcddeec96 /src | |
parent | ae70f020cdd22d155882191ca60d40542615b606 (diff) | |
parent | 3f77202a0167f30454b3cc059a675cc9230ff603 (diff) | |
download | scala-494914346ed6f27b44283f4850383582a7a7f6d1.tar.gz scala-494914346ed6f27b44283f4850383582a7a7f6d1.tar.bz2 scala-494914346ed6f27b44283f4850383582a7a7f6d1.zip |
Merge pull request #4017 from lrytz/t6541
SI-6541 valid wildcard existentials for case-module-unapply
Diffstat (limited to 'src')
4 files changed, 41 insertions, 18 deletions
diff --git a/src/compiler/scala/tools/nsc/settings/MutableSettings.scala b/src/compiler/scala/tools/nsc/settings/MutableSettings.scala index 23611bb629..b4987e1240 100644 --- a/src/compiler/scala/tools/nsc/settings/MutableSettings.scala +++ b/src/compiler/scala/tools/nsc/settings/MutableSettings.scala @@ -229,7 +229,8 @@ class MutableSettings(val errorFn: String => Unit) def OutputSetting(outputDirs: OutputDirs, default: String) = add(new OutputSetting(outputDirs, default)) def PhasesSetting(name: String, descr: String, default: String = "") = add(new PhasesSetting(name, descr, default)) def StringSetting(name: String, arg: String, descr: String, default: String) = add(new StringSetting(name, arg, descr, default)) - def ScalaVersionSetting(name: String, arg: String, descr: String, default: ScalaVersion) = add(new ScalaVersionSetting(name, arg, descr, default)) + def ScalaVersionSetting(name: String, arg: String, descr: String, initial: ScalaVersion, default: Option[ScalaVersion] = None) = + add(new ScalaVersionSetting(name, arg, descr, initial, default)) def PathSetting(name: String, descr: String, default: String): PathSetting = { val prepend = StringSetting(name + "/p", "", "", "").internalOnly() val append = StringSetting(name + "/a", "", "", "").internalOnly() @@ -506,28 +507,35 @@ class MutableSettings(val errorFn: String => Unit) withHelpSyntax(name + " <" + arg + ">") } - /** A setting represented by a Scala version, (`default` unless set) */ + /** A setting represented by a Scala version. + * The `initial` value is used if the setting is not specified. + * The `default` value is used if the option is specified without argument (e.g., `-Xmigration`). + */ class ScalaVersionSetting private[nsc]( name: String, val arg: String, descr: String, - default: ScalaVersion) + initial: ScalaVersion, + default: Option[ScalaVersion]) extends Setting(name, descr) { type T = ScalaVersion - protected var v: T = NoScalaVersion + protected var v: T = initial + // This method is invoked if there are no colonated args. In this case the default value is + // used. No arguments are consumed. override def tryToSet(args: List[String]) = { - value = default + default match { + case Some(d) => value = d + case None => errorFn(s"$name requires an argument, the syntax is $helpSyntax") + } Some(args) } override def tryToSetColon(args: List[String]) = args match { - case Nil => value = default; Some(Nil) - case x :: xs => value = ScalaVersion(x, errorFn) ; Some(xs) + case x :: xs => value = ScalaVersion(x, errorFn); Some(xs) + case nil => Some(nil) } - override def tryToSetFromPropertyValue(s: String) = tryToSet(List(s)) - def unparse: List[String] = if (value == NoScalaVersion) Nil else List(s"${name}:${value.unparse}") withHelpSyntax(s"${name}:<${arg}>") diff --git a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala index 850534f2cc..c59d56d8f8 100644 --- a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala +++ b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala @@ -92,7 +92,8 @@ trait ScalaSettings extends AbsScalaSettings * The previous "-source" option is intended to be used mainly * though this helper. */ - lazy val isScala211: Boolean = (source.value >= ScalaVersion("2.11.0")) + def isScala211: Boolean = source.value >= ScalaVersion("2.11.0") + def isScala212: Boolean = source.value >= ScalaVersion("2.12.0") /** * -X "Advanced" settings @@ -111,7 +112,7 @@ trait ScalaSettings extends AbsScalaSettings val logFreeTerms = BooleanSetting ("-Xlog-free-terms", "Print a message when reification creates a free term.") val logFreeTypes = BooleanSetting ("-Xlog-free-types", "Print a message when reification resorts to generating a free type.") val maxClassfileName = IntSetting ("-Xmax-classfile-name", "Maximum filename length for generated classes", 255, Some((72, 255)), _ => None) - val Xmigration = ScalaVersionSetting ("-Xmigration", "version", "Warn about constructs whose behavior may have changed since version.", AnyScalaVersion) + val Xmigration = ScalaVersionSetting ("-Xmigration", "version", "Warn about constructs whose behavior may have changed since version.", initial = NoScalaVersion, default = Some(AnyScalaVersion)) val nouescape = BooleanSetting ("-Xno-uescape", "Disable handling of \\u unicode escapes.") val Xnojline = BooleanSetting ("-Xnojline", "Do not use JLine for editing.") val Xverify = BooleanSetting ("-Xverify", "Verify generic signatures in generated bytecode (asm backend only.)") @@ -133,7 +134,7 @@ trait ScalaSettings extends AbsScalaSettings val showPhases = BooleanSetting ("-Xshow-phases", "Print a synopsis of compiler phases.") val sourceReader = StringSetting ("-Xsource-reader", "classname", "Specify a custom method for reading source files.", "") val strictInference = BooleanSetting ("-Xstrict-inference", "Don't infer known-unsound types") - val source = ScalaVersionSetting ("-Xsource", "version", "Treat compiler input as Scala source for the specified version, see SI-8126.", ScalaVersion("2.11")) withPostSetHook ( _ => isScala211) + val source = ScalaVersionSetting ("-Xsource", "version", "Treat compiler input as Scala source for the specified version, see SI-8126.", initial = ScalaVersion("2.11")) val XnoPatmatAnalysis = BooleanSetting ("-Xno-patmat-analysis", "Don't perform exhaustivity/unreachability analysis. Also, ignore @switch annotation.") val XfullLubs = BooleanSetting ("-Xfull-lubs", "Retains pre 2.10 behavior of less aggressive truncation of least upper bounds.") diff --git a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala index cc2d9141ce..fc1f45e358 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala @@ -142,17 +142,30 @@ trait Unapplies extends ast.TreeDSL { /** The unapply method corresponding to a case class */ def caseModuleUnapplyMeth(cdef: ClassDef): DefDef = { - val tparams = constrTparamsInvariant(cdef) - val method = constrParamss(cdef) match { + val tparams = constrTparamsInvariant(cdef) + val method = constrParamss(cdef) match { case xs :: _ if xs.nonEmpty && isRepeatedParamType(xs.last.tpt) => nme.unapplySeq case _ => nme.unapply } - val cparams = List(ValDef(Modifiers(PARAM | SYNTHETIC), unapplyParamName, classType(cdef, tparams), EmptyTree)) - val ifNull = if (constrParamss(cdef).head.isEmpty) FALSE else REF(NoneModule) - val body = nullSafe({ case Ident(x) => caseClassUnapplyReturnValue(x, cdef) }, ifNull)(Ident(unapplyParamName)) + val cparams = List(ValDef(Modifiers(PARAM | SYNTHETIC), unapplyParamName, classType(cdef, tparams), EmptyTree)) + val resultType = if (!settings.isScala212) TypeTree() else { // fix for SI-6541 under -Xsource:2.12 + def repeatedToSeq(tp: Tree) = tp match { + case AppliedTypeTree(Select(_, tpnme.REPEATED_PARAM_CLASS_NAME), tps) => AppliedTypeTree(gen.rootScalaDot(tpnme.Seq), tps) + case _ => tp + } + constrParamss(cdef) match { + case Nil | Nil :: _ => + gen.rootScalaDot(tpnme.Boolean) + case params :: _ => + val constrParamTypes = params.map(param => repeatedToSeq(param.tpt)) + AppliedTypeTree(gen.rootScalaDot(tpnme.Option), List(treeBuilder.makeTupleType(constrParamTypes))) + } + } + val ifNull = if (constrParamss(cdef).head.isEmpty) FALSE else REF(NoneModule) + val body = nullSafe({ case Ident(x) => caseClassUnapplyReturnValue(x, cdef) }, ifNull)(Ident(unapplyParamName)) atPos(cdef.pos.focus)( - DefDef(caseMods, method, tparams, List(cparams), TypeTree(), body) + DefDef(caseMods, method, tparams, List(cparams), resultType, body) ) } diff --git a/src/reflect/scala/reflect/internal/StdNames.scala b/src/reflect/scala/reflect/internal/StdNames.scala index 99ff6a10b4..f2517fff54 100644 --- a/src/reflect/scala/reflect/internal/StdNames.scala +++ b/src/reflect/scala/reflect/internal/StdNames.scala @@ -128,6 +128,7 @@ trait StdNames { final val AnyRef: NameType = "AnyRef" final val Array: NameType = "Array" final val List: NameType = "List" + final val Option: NameType = "Option" final val Seq: NameType = "Seq" final val Symbol: NameType = "Symbol" final val WeakTypeTag: NameType = "WeakTypeTag" |