diff options
42 files changed, 696 insertions, 111 deletions
@@ -743,7 +743,14 @@ QUICK BUILD (QUICK) <stopwatch name="quick.plugins.timer" action="total"/> </target> - <target name="quick.scalacheck" depends="quick.plugins"> + <target name="quick.pre-scalacheck" depends="quick.plugins"> + <uptodate property="quick.scalacheck.available" targetfile="${build-quick.dir}/scalacheck.complete"> + <srcfiles dir="${src.dir}/scalacheck"/> + </uptodate> + </target> + + <target name="quick.scalacheck" depends="quick.pre-scalacheck" unless="quick.scalacheck.available"> + <stopwatch name="quick.scalacheck.timer"/> <mkdir dir="${build-quick.dir}/classes/scalacheck"/> <scalacfork destdir="${build-quick.dir}/classes/scalacheck" @@ -757,6 +764,8 @@ QUICK BUILD (QUICK) <pathelement location="${build-quick.dir}/classes/scalacheck"/> </compilationpath> </scalacfork> + <touch file="${build-quick.dir}/scalacheck.complete" verbose="no"/> + <stopwatch name="quick.scalacheck.timer" action="total"/> </target> <target name="quick.pre-scalap" depends="quick.scalacheck"> diff --git a/src/compiler/scala/reflect/internal/Definitions.scala b/src/compiler/scala/reflect/internal/Definitions.scala index 15f89e1382..fe20613c22 100644 --- a/src/compiler/scala/reflect/internal/Definitions.scala +++ b/src/compiler/scala/reflect/internal/Definitions.scala @@ -386,6 +386,30 @@ trait Definitions extends reflect.api.StandardDefinitions { lazy val NoneModule: Symbol = getModule("scala.None") lazy val SomeModule: Symbol = getModule("scala.Some") + /** Note: don't use this manifest/type function for anything important, + * as it is incomplete. Would love to have things like existential types + * working, but very unfortunately the manifests just stuff the relevant + * information into the toString method. + */ + def manifestToType(m: OptManifest[_]): Type = m match { + case x: AnyValManifest[_] => + getClassIfDefined("scala." + x).tpe + case m: ClassManifest[_] => + val name = m.erasure.getName + if (name endsWith nme.MODULE_SUFFIX_STRING) + getModuleIfDefined(name stripSuffix nme.MODULE_SUFFIX_STRING).tpe + else { + val sym = getClassIfDefined(name) + val args = m.typeArguments + + if (sym eq NoSymbol) NoType + else if (args.isEmpty) sym.tpe + else appliedType(sym.typeConstructor, args map manifestToType) + } + case _ => + NoType + } + // The given symbol represents either String.+ or StringAdd.+ def isStringAddition(sym: Symbol) = sym == String_+ || sym == StringAdd_+ def isArrowAssoc(sym: Symbol) = ArrowAssocClass.tpe.decls.toList contains sym diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala index 47184eee51..38f51b1459 100644 --- a/src/compiler/scala/reflect/internal/Types.scala +++ b/src/compiler/scala/reflect/internal/Types.scala @@ -5487,6 +5487,10 @@ A type's typeSymbol should never be inspected directly. case _ => t } + def elimRefinement(t: Type) = t match { + case RefinedType(parents, decls) if !decls.isEmpty => intersectionType(parents) + case _ => t + } /** A collector that tests for existential types appearing at given variance in a type */ class ContainsVariantExistentialCollector(v: Int) extends TypeCollector(false) { diff --git a/src/compiler/scala/tools/nsc/PhaseAssembly.scala b/src/compiler/scala/tools/nsc/PhaseAssembly.scala index f25ea6fe5e..a627b982b6 100644 --- a/src/compiler/scala/tools/nsc/PhaseAssembly.scala +++ b/src/compiler/scala/tools/nsc/PhaseAssembly.scala @@ -185,7 +185,7 @@ trait PhaseAssembly { * dependency on something that is dropped. */ def removeDanglingNodes() { - for (node <- nodes.valuesIterator filter (_.phaseobj.isEmpty)) { + for (node <- nodes.values filter (_.phaseobj.isEmpty)) { val msg = "dropping dependency on node with no phase object: "+node.phasename informProgress(msg) nodes -= node.phasename diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index e27d5cacda..00ac3976a9 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -1534,9 +1534,10 @@ self => val t1 = stripParens(t) t1 match { case Ident(_) | Select(_, _) => - val tapp = atPos(t1.pos.startOrPoint, in.offset) { - TypeApply(t1, exprTypeArgs()) - } + var tapp: Tree = t1 + while (in.token == LBRACKET) + tapp = atPos(tapp.pos.startOrPoint, in.offset)(TypeApply(tapp, exprTypeArgs())) + simpleExprRest(tapp, true) case _ => t1 diff --git a/src/compiler/scala/tools/nsc/interpreter/ILoop.scala b/src/compiler/scala/tools/nsc/interpreter/ILoop.scala index 391d5ab8ee..3ddbffa75e 100644 --- a/src/compiler/scala/tools/nsc/interpreter/ILoop.scala +++ b/src/compiler/scala/tools/nsc/interpreter/ILoop.scala @@ -51,7 +51,7 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter) intp.reporter.printMessage(msg) def isAsync = !settings.Yreplsync.value - lazy val power = Power(this) + lazy val power = new Power(intp, new StdReplVals(this)) // TODO // object opt extends AestheticSettings @@ -253,6 +253,7 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter) /** Power user commands */ lazy val powerCommands: List[LoopCommand] = List( nullary("dump", "displays a view of the interpreter's internal state", dumpCommand), + nullary("vals", "gives information about the power mode repl vals", valsCommand), cmd("phase", "<phase>", "set the implicit phase for power commands", phaseCommand), cmd("wrap", "<method>", "name of method to wrap around each repl line", wrapCommand) withLongHelp (""" |:wrap @@ -283,6 +284,7 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter) history.asStrings takeRight 30 foreach echo in.redrawLine() } + private def valsCommand(): Result = power.valsDescription private val typeTransforms = List( "scala.collection.immutable." -> "immutable.", diff --git a/src/compiler/scala/tools/nsc/interpreter/Power.scala b/src/compiler/scala/tools/nsc/interpreter/Power.scala index ac7c2b1ecc..82a466a7e5 100644 --- a/src/compiler/scala/tools/nsc/interpreter/Power.scala +++ b/src/compiler/scala/tools/nsc/interpreter/Power.scala @@ -15,54 +15,12 @@ import scala.io.Codec import java.net.{ URL, MalformedURLException } import io.{ Path } -trait SharesGlobal { - type GlobalType <: Global - val global: GlobalType - - // This business gets really old: - // - // found : power.intp.global.Symbol - // required: global.Symbol - // - // Have tried many ways to cast it aside, this is the current winner. - // Todo: figure out a way to abstract over all the type members. - type AnySymbol = Global#Symbol - type AnyType = Global#Type - type AnyName = Global#Name - type AnyTree = Global#Tree - - type Symbol = global.Symbol - type Type = global.Type - type Name = global.Name - type Tree = global.Tree - - implicit def upDependentSymbol(x: AnySymbol): Symbol = x.asInstanceOf[Symbol] - implicit def upDependentType(x: AnyType): Type = x.asInstanceOf[Type] - implicit def upDependentName(x: AnyName): Name = x.asInstanceOf[Name] - implicit def upDependentTree(x: AnyTree): Tree = x.asInstanceOf[Tree] -} - -object Power { - def apply(intp: IMain): Power = apply(null, intp) - def apply(repl: ILoop): Power = apply(repl, repl.intp) - def apply(repl: ILoop, intp: IMain): Power = - new Power(repl, intp) { - type GlobalType = intp.global.type - final val global: intp.global.type = intp.global - } -} - /** A class for methods to be injected into the intp in power mode. */ -abstract class Power( - val repl: ILoop, - val intp: IMain -) extends SharesGlobal { - import intp.{ - beQuietDuring, typeOfExpression, interpret, parse - } - import global._ - import definitions.{ getClassIfDefined, getModuleIfDefined } +class Power[ReplValsImpl <: ReplVals : Manifest](val intp: IMain, replVals: ReplValsImpl) { + import intp.{ beQuietDuring, typeOfExpression, interpret, parse } + import intp.global._ + import definitions.{ manifestToType, getClassIfDefined, getModuleIfDefined } abstract class SymSlurper { def isKeep(sym: Symbol): Boolean @@ -130,11 +88,11 @@ abstract class Power( private def customInit = replProps.powerInitCode.option flatMap (f => io.File(f).safeSlurp()) def banner = customBanner getOrElse """ - |** Power User mode enabled - BEEP BOOP SPIZ ** + |** Power User mode enabled - BEEP WHIR GYVE ** |** :phase has been set to 'typer'. ** |** scala.tools.nsc._ has been imported ** - |** global._ and definitions._ also imported ** - |** Try :help, vals.<tab>, power.<tab> ** + |** global._, definitions._ also imported ** + |** Try :help, :vals, power.<tab> ** """.stripMargin.trim private def initImports = List( @@ -142,8 +100,9 @@ abstract class Power( "scala.collection.JavaConverters._", "intp.global.{ error => _, _ }", "definitions.{ getClass => _, _ }", - "power.Implicits._", - "power.rutil._" + "power.rutil._", + "replImplicits._", + "treedsl.CODE._" ) def init = customInit match { @@ -155,12 +114,23 @@ abstract class Power( */ def unleash(): Unit = beQuietDuring { // First we create the ReplVals instance and bind it to $r - intp.bind("$r", new ReplVals(repl)) + intp.bind("$r", replVals) // Then we import everything from $r. intp interpret ("import " + intp.pathToTerm("$r") + "._") // And whatever else there is to do. init.lines foreach (intp interpret _) } + def valsDescription: String = { + def to_str(m: Symbol) = "%12s %s".format( + m.decodedName, "" + elimRefinement(m.accessedOrSelf.tpe) stripPrefix "scala.tools.nsc.") + + ( rutil.info[ReplValsImpl].declares + filter (m => m.isPublic && !m.hasModuleFlag && !m.isConstructor) + sortBy (_.decodedName) + map to_str + mkString ("Name and type of values imported into the repl in power mode.\n\n", "\n", "") + ) + } trait LowPriorityInternalInfo { implicit def apply[T: Manifest] : InternalInfo[T] = new InternalInfo[T](None) @@ -180,25 +150,6 @@ abstract class Power( private def symbol = symbol_ private def name = name_ - // Would love to have stuff like existential types working, - // but very unfortunately those manifests just stuff the relevant - // information into the toString method. Boo. - private def manifestToType(m: Manifest[_]): Type = m match { - case x: AnyValManifest[_] => - getClassIfDefined("scala." + x).tpe - case _ => - val name = m.erasure.getName - if (name endsWith nme.MODULE_SUFFIX_STRING) - getModuleIfDefined(name stripSuffix nme.MODULE_SUFFIX_STRING).tpe - else { - val sym = getClassIfDefined(name) - val args = m.typeArguments - - if (args.isEmpty) sym.tpe - else typeRef(NoPrefix, sym, args map manifestToType) - } - } - def symbol_ : Symbol = getClassIfDefined(erasure.getName) def tpe_ : Type = manifestToType(man) def name_ : Name = symbol.name @@ -208,9 +159,10 @@ abstract class Power( def owner = symbol.owner def owners = symbol.ownerChain drop 1 def defn = symbol.defString + def decls = symbol.info.decls - def declares = members filter (_.owner == symbol) - def inherits = members filterNot (_.owner == symbol) + def declares = decls.toList + def inherits = members filterNot (declares contains _) def types = members filter (_.name.isTypeName) def methods = members filter (_.isMethod) def overrides = declares filter (_.isOverride) @@ -233,8 +185,8 @@ abstract class Power( def whoHas(name: String) = bts filter (_.decls exists (_.name.toString == name)) def <:<[U: Manifest](other: U) = tpe <:< InternalInfo[U].tpe - def lub[U: Manifest](other: U) = global.lub(List(tpe, InternalInfo[U].tpe)) - def glb[U: Manifest](other: U) = global.glb(List(tpe, InternalInfo[U].tpe)) + def lub[U: Manifest](other: U) = intp.global.lub(List(tpe, InternalInfo[U].tpe)) + def glb[U: Manifest](other: U) = intp.global.glb(List(tpe, InternalInfo[U].tpe)) def shortClass = erasure.getName split "[$.]" last override def toString = value match { @@ -337,7 +289,7 @@ abstract class Power( def pp() { intp prettyPrint slurp() } } - protected trait Implicits1 { + trait Implicits1 { // fallback implicit def replPrinting[T](x: T)(implicit pretty: Prettifier[T] = Prettifier.default[T]) = new SinglePrettifierClass[T](x) @@ -367,7 +319,6 @@ abstract class Power( implicit def replInputStream(in: InputStream)(implicit codec: Codec) = new RichInputStream(in) implicit def replEnhancedURLs(url: URL)(implicit codec: Codec): RichReplURL = new RichReplURL(url)(codec) } - object Implicits extends Implicits2 { } trait ReplUtilities { def module[T: Manifest] = getModuleIfDefined(manifest[T].erasure.getName stripSuffix nme.MODULE_SUFFIX_STRING) @@ -396,11 +347,7 @@ abstract class Power( } lazy val rutil: ReplUtilities = new ReplUtilities { } - - lazy val phased: Phased = new Phased with SharesGlobal { - type GlobalType = Power.this.global.type - final val global: Power.this.global.type = Power.this.global - } + lazy val phased: Phased = new { val global: intp.global.type = intp.global } with Phased { } def context(code: String) = analyzer.rootContext(unit(code)) def source(code: String) = new BatchSourceFile("<console>", code) diff --git a/src/compiler/scala/tools/nsc/interpreter/ReplVals.scala b/src/compiler/scala/tools/nsc/interpreter/ReplVals.scala index 2f2489b242..6e5dec4205 100644 --- a/src/compiler/scala/tools/nsc/interpreter/ReplVals.scala +++ b/src/compiler/scala/tools/nsc/interpreter/ReplVals.scala @@ -6,15 +6,68 @@ package scala.tools.nsc package interpreter -final class ReplVals(r: ILoop) { - lazy val repl = r - lazy val intp = r.intp - lazy val power = r.power - lazy val reader = r.in - lazy val vals = this - lazy val global = intp.global - lazy val isettings = intp.isettings - lazy val completion = reader.completion - lazy val history = reader.history - lazy val phased = power.phased +/** A class which the repl utilizes to expose predefined objects. + * The base implementation is empty; the standard repl implementation + * is StdReplVals. + */ +abstract class ReplVals { } + +class StdReplVals(final val r: ILoop) extends ReplVals { + final lazy val repl = r + final lazy val intp = r.intp + final lazy val power = r.power + final lazy val reader = r.in + final lazy val vals = this + final lazy val global: intp.global.type = intp.global + final lazy val isettings = intp.isettings + final lazy val completion = reader.completion + final lazy val history = reader.history + final lazy val phased = power.phased + final lazy val analyzer = global.analyzer + + final lazy val treedsl = new { val global: intp.global.type = intp.global } with ast.TreeDSL { } + final lazy val typer = analyzer.newTyper( + analyzer.rootContext( + power.unit("").asInstanceOf[analyzer.global.CompilationUnit] + ) + ) + + final lazy val replImplicits = new power.Implicits2 { + import intp.global._ + + private val manifestFn = ReplVals.mkManifestToType[intp.global.type](global) + implicit def mkManifestToType(sym: Symbol) = manifestFn(sym) + } + + def typed[T <: analyzer.global.Tree](tree: T): T = typer.typed(tree).asInstanceOf[T] +} + +object ReplVals { + /** Latest attempt to work around the challenge of foo.global.Type + * not being seen as the same type as bar.global.Type even though + * the globals are the same. Dependent method types to the rescue. + */ + def mkManifestToType[T <: Global](global: T) = { + import global._ + import definitions._ + + /** We can't use definitions.manifestToType directly because we're passing + * it to map and the compiler refuses to perform eta expansion on a method + * with a dependent return type. (Can this be relaxed?) To get around this + * I have this forwarder which widens the type and then cast the result back + * to the dependent type. + */ + def manifestToType(m: OptManifest[_]): Global#Type = + definitions.manifestToType(m) + + class AppliedTypeFromManifests(sym: Symbol) { + def apply[M](implicit m1: Manifest[M]): Type = + appliedType(sym.typeConstructor, List(m1) map (x => manifestToType(x).asInstanceOf[Type])) + + def apply[M1, M2](implicit m1: Manifest[M1], m2: Manifest[M2]): Type = + appliedType(sym.typeConstructor, List(m1, m2) map (x => manifestToType(x).asInstanceOf[Type])) + } + + (sym: Symbol) => new AppliedTypeFromManifests(sym) + } } diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index 98f1c96cad..f920f3c135 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -1092,7 +1092,7 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R } // possibleNumericCount is insufficient or this will warn on e.g. Boolean == j.l.Boolean - if (nullCount == 0 && !(isSpecial(receiver) && isSpecial(actual))) { + if (isWarnable && nullCount == 0 && !(isSpecial(receiver) && isSpecial(actual))) { if (actual isSubClass receiver) () else if (receiver isSubClass actual) () // warn only if they have no common supertype below Object diff --git a/src/compiler/scala/tools/reflect/Mock.scala b/src/compiler/scala/tools/reflect/Mock.scala index 5301816b4b..52c052b8a2 100644 --- a/src/compiler/scala/tools/reflect/Mock.scala +++ b/src/compiler/scala/tools/reflect/Mock.scala @@ -25,7 +25,8 @@ trait Mock extends (Invoked => AnyRef) { def newInvocationHandler() = new InvocationHandler { def invoke(proxy: AnyRef, method: Method, args: Array[AnyRef]) = - mock(Invoked(proxy, method, args)) + try { mock(Invoked(proxy, method, args)) } + catch { case _: NoClassDefFoundError => sys.exit(1) } } } diff --git a/src/library/scala/math/Ordering.scala b/src/library/scala/math/Ordering.scala index d007ae3780..8fc74a9d5d 100644 --- a/src/library/scala/math/Ordering.scala +++ b/src/library/scala/math/Ordering.scala @@ -262,12 +262,52 @@ object Ordering extends LowPriorityOrderingImplicits { implicit object Long extends LongOrdering trait FloatOrdering extends Ordering[Float] { + outer => + def compare(x: Float, y: Float) = java.lang.Float.compare(x, y) + + override def lteq(x: Float, y: Float): Boolean = x <= y + override def gteq(x: Float, y: Float): Boolean = x >= y + override def lt(x: Float, y: Float): Boolean = x < y + override def gt(x: Float, y: Float): Boolean = x > y + override def equiv(x: Float, y: Float): Boolean = x == y + override def max(x: Float, y: Float): Float = math.max(x, y) + override def min(x: Float, y: Float): Float = math.min(x, y) + + override def reverse: Ordering[Float] = new FloatOrdering { + override def reverse = outer + override def compare(x: Float, y: Float) = outer.compare(y, x) + + override def lteq(x: Float, y: Float): Boolean = outer.lteq(y, x) + override def gteq(x: Float, y: Float): Boolean = outer.gteq(y, x) + override def lt(x: Float, y: Float): Boolean = outer.lt(y, x) + override def gt(x: Float, y: Float): Boolean = outer.gt(y, x) + } } implicit object Float extends FloatOrdering trait DoubleOrdering extends Ordering[Double] { + outer => + def compare(x: Double, y: Double) = java.lang.Double.compare(x, y) + + override def lteq(x: Double, y: Double): Boolean = x <= y + override def gteq(x: Double, y: Double): Boolean = x >= y + override def lt(x: Double, y: Double): Boolean = x < y + override def gt(x: Double, y: Double): Boolean = x > y + override def equiv(x: Double, y: Double): Boolean = x == y + override def max(x: Double, y: Double): Double = math.max(x, y) + override def min(x: Double, y: Double): Double = math.min(x, y) + + override def reverse: Ordering[Double] = new DoubleOrdering { + override def reverse = outer + override def compare(x: Double, y: Double) = outer.compare(y, x) + + override def lteq(x: Double, y: Double): Boolean = outer.lteq(y, x) + override def gteq(x: Double, y: Double): Boolean = outer.gteq(y, x) + override def lt(x: Double, y: Double): Boolean = outer.lt(y, x) + override def gt(x: Double, y: Double): Boolean = outer.gt(y, x) + } } implicit object Double extends DoubleOrdering diff --git a/src/library/scala/reflect/api/Trees.scala b/src/library/scala/reflect/api/Trees.scala index 752319d9a4..e5502acb20 100644 --- a/src/library/scala/reflect/api/Trees.scala +++ b/src/library/scala/reflect/api/Trees.scala @@ -625,6 +625,11 @@ trait Trees /*extends reflect.generic.Trees*/ { self: Universe => def TypeTree(tp: Type): TypeTree = TypeTree() setType tp + /** An empty deferred value definition corresponding to: + * val _: _ + * This is used as a placeholder in the `self` parameter Template if there is + * no definition of a self value of self type. + */ def emptyValDef: ValDef // ------ traversers, copiers, and transformers --------------------------------------------- diff --git a/test/files/neg/checksensible.check b/test/files/neg/checksensible.check index d45d16165f..0881205bb4 100644 --- a/test/files/neg/checksensible.check +++ b/test/files/neg/checksensible.check @@ -28,12 +28,6 @@ checksensible.scala:27: error: comparing values of types Int and Unit using `==' checksensible.scala:29: error: comparing values of types Int and String using `==' will always yield false 1 == "abc" ^ -checksensible.scala:32: error: String and Int are unrelated: they will most likely never compare equal - "abc" == 1 // warns because the lub of String and Int is Any - ^ -checksensible.scala:33: error: Some[Int] and Int are unrelated: they will most likely never compare equal - Some(1) == 1 // as above - ^ checksensible.scala:38: error: comparing a fresh object using `==' will always yield false new AnyRef == 1 ^ @@ -100,4 +94,4 @@ checksensible.scala:84: error: comparing values of types EqEqRefTest.this.C3 and checksensible.scala:95: error: comparing values of types Unit and Int using `!=' will always yield true while ((c = in.read) != -1) ^ -34 errors found +32 errors found diff --git a/test/files/pos/t5175.flags b/test/files/pos/t5175.flags new file mode 100644 index 0000000000..e8fb65d50c --- /dev/null +++ b/test/files/pos/t5175.flags @@ -0,0 +1 @@ +-Xfatal-warnings
\ No newline at end of file diff --git a/test/files/pos/t5175.scala b/test/files/pos/t5175.scala new file mode 100644 index 0000000000..e15cc3affd --- /dev/null +++ b/test/files/pos/t5175.scala @@ -0,0 +1,9 @@ +object Test { + def ==(p: Phase): Int = 0 + + def foo { + ==(new Phase()) + } +} + +class Phase diff --git a/test/files/run/repl-power.check b/test/files/run/repl-power.check index 38e7532133..1e7b6f0cd8 100644 --- a/test/files/run/repl-power.check +++ b/test/files/run/repl-power.check @@ -2,15 +2,31 @@ Type in expressions to have them evaluated. Type :help for more information. scala> :power -** Power User mode enabled - BEEP BOOP SPIZ ** +** Power User mode enabled - BEEP WHIR GYVE ** ** :phase has been set to 'typer'. ** ** scala.tools.nsc._ has been imported ** -** global._ and definitions._ also imported ** -** Try :help, vals.<tab>, power.<tab> ** +** global._, definitions._ also imported ** +** Try :help, :vals, power.<tab> ** scala> // guarding against "error: reference to global is ambiguous" scala> global.emptyValDef // "it is imported twice in the same scope by ..." res0: $r.global.emptyValDef.type = private val _ = _ +scala> val tp = ArrayClass[scala.util.Random] // magic with manifests +tp: $r.global.Type = Array[scala.util.Random] + +scala> tp.memberType(Array_apply) // evidence +res1: $r.global.Type = (i: Int)scala.util.Random + +scala> val m = LIT(10) MATCH (CASE(LIT(5)) ==> FALSE, DEFAULT ==> TRUE) // treedsl +m: $r.treedsl.global.Match = +10 match { + case 5 => false + case _ => true +} + +scala> typed(m).tpe // typed is in scope +res2: $r.treedsl.global.Type = Boolean + scala> diff --git a/test/files/run/repl-power.scala b/test/files/run/repl-power.scala index 9f70ac4b68..27da3df106 100644 --- a/test/files/run/repl-power.scala +++ b/test/files/run/repl-power.scala @@ -5,6 +5,10 @@ object Test extends ReplTest { :power // guarding against "error: reference to global is ambiguous" global.emptyValDef // "it is imported twice in the same scope by ..." +val tp = ArrayClass[scala.util.Random] // magic with manifests +tp.memberType(Array_apply) // evidence +val m = LIT(10) MATCH (CASE(LIT(5)) ==> FALSE, DEFAULT ==> TRUE) // treedsl +typed(m).tpe // typed is in scope """.trim } diff --git a/test/files/run/type-currying.check b/test/files/run/type-currying.check new file mode 100644 index 0000000000..e5db238ca5 --- /dev/null +++ b/test/files/run/type-currying.check @@ -0,0 +1,27 @@ +Map(abc -> 55) +(a,0) +(b,1) +(c,2) +(d,3) +(e,4) +(f,5) +(g,6) +(h,7) +(i,8) +(j,9) +(k,10) +(l,11) +(m,12) +(n,13) +(o,14) +(p,15) +(q,16) +(r,17) +(s,18) +(t,19) +(u,20) +(v,21) +(w,22) +(x,23) +(y,24) +(z,25) diff --git a/test/files/run/type-currying.scala b/test/files/run/type-currying.scala new file mode 100644 index 0000000000..717e0763a3 --- /dev/null +++ b/test/files/run/type-currying.scala @@ -0,0 +1,45 @@ +import scala.collection.{ mutable, immutable, generic } +import generic.CanBuildFrom + +object Partial { + type KnownContainer[CC[K, V] <: collection.Map[K, V]] = { + def values[V] : KnownValues[CC, V] + def apply[K] : KnownKeys[CC, K] + } + type KnownKeys[CC[K, V] <: collection.Map[K, V], K] = { + def apply[V](implicit cbf: CanBuildFrom[_, (K, V), CC[K, V]]): CC[K, V] + } + type KnownValues[CC[K, V] <: collection.Map[K, V], V] = { + def apply[K](implicit cbf: CanBuildFrom[_, (K, V), CC[K, V]]): CC[K, V] + } + + def apply[CC[K, V] <: collection.Map[K, V]] : KnownContainer[CC] = new { + def values[V] : KnownValues[CC, V] = new { + def apply[K](implicit cbf: CanBuildFrom[_, (K, V), CC[K, V]]) = cbf().result + } + def apply[K] = new { + def apply[V](implicit cbf: CanBuildFrom[_, (K, V), CC[K, V]]) = cbf().result + } + } +} + +object Test { + val m = Partial[immutable.TreeMap] + val m1 = m[String] + val m2 = m[Int][Int] + + val mutableBippy = Partial[mutable.HashMap][String][Int] + mutableBippy("abc") = 55 + + val immutableBippy = Partial[immutable.HashMap].values[Int] + def make[T](xs: T*) = immutableBippy[T] ++ xs.zipWithIndex + + val n0 = Partial[immutable.HashMap][String][Int] ++ Seq(("a", 1)) + val n1 = Partial.apply[immutable.HashMap].apply[String].apply[Int] ++ Seq(("a", 1)) + + def main(args: Array[String]): Unit = { + println(mutableBippy) + make('a' to 'z': _*).toList.sorted foreach println + assert(n0 == n1) + } +} diff --git a/test/files/scalacheck/nan-ordering.scala b/test/files/scalacheck/nan-ordering.scala new file mode 100644 index 0000000000..2094a46e37 --- /dev/null +++ b/test/files/scalacheck/nan-ordering.scala @@ -0,0 +1,130 @@ +import org.scalacheck._ +import Gen._ +import Prop._ + +object Test extends Properties("NaN-Ordering") { + + val specFloats: Gen[Float] = oneOf( + Float.MaxValue, + Float.MinPositiveValue, + Float.MinValue, + Float.NaN, + Float.NegativeInfinity, + Float.PositiveInfinity, + -0.0f, + +0.0f + ) + + property("Float min") = forAll(specFloats, specFloats) { (d1, d2) => { + val mathmin = math.min(d1, d2) + val numericmin = d1 min d2 + mathmin == numericmin || mathmin.isNaN && numericmin.isNaN + } + } + + property("Float max") = forAll(specFloats, specFloats) { (d1, d2) => { + val mathmax = math.max(d1, d2) + val numericmax = d1 max d2 + mathmax == numericmax || mathmax.isNaN && numericmax.isNaN + } + } + + val numFloat = implicitly[Numeric[Float]] + + property("Float lt") = forAll(specFloats, specFloats) { (d1, d2) => numFloat.lt(d1, d2) == d1 < d2 } + + property("Float lteq") = forAll(specFloats, specFloats) { (d1, d2) => numFloat.lteq(d1, d2) == d1 <= d2 } + + property("Float gt") = forAll(specFloats, specFloats) { (d1, d2) => numFloat.gt(d1, d2) == d1 > d2 } + + property("Float gteq") = forAll(specFloats, specFloats) { (d1, d2) => numFloat.gteq(d1, d2) == d1 >= d2 } + + property("Float equiv") = forAll(specFloats, specFloats) { (d1, d2) => numFloat.equiv(d1, d2) == (d1 == d2) } + + property("Float reverse.min") = forAll(specFloats, specFloats) { (d1, d2) => { + val mathmin = math.min(d1, d2) + val numericmin = numFloat.reverse.min(d1, d2) + mathmin == numericmin || mathmin.isNaN && numericmin.isNaN + } + } + + property("Float reverse.max") = forAll(specFloats, specFloats) { (d1, d2) => { + val mathmax = math.max(d1, d2) + val numericmax = numFloat.reverse.max(d1, d2) + mathmax == numericmax || mathmax.isNaN && numericmax.isNaN + } + } + + property("Float reverse.lt") = forAll(specFloats, specFloats) { (d1, d2) => numFloat.reverse.lt(d1, d2) == d2 < d1 } + + property("Float reverse.lteq") = forAll(specFloats, specFloats) { (d1, d2) => numFloat.reverse.lteq(d1, d2) == d2 <= d1 } + + property("Float reverse.gt") = forAll(specFloats, specFloats) { (d1, d2) => numFloat.reverse.gt(d1, d2) == d2 > d1 } + + property("Float reverse.gteq") = forAll(specFloats, specFloats) { (d1, d2) => numFloat.reverse.gteq(d1, d2) == d2 >= d1 } + + property("Float reverse.equiv") = forAll(specFloats, specFloats) { (d1, d2) => numFloat.reverse.equiv(d1, d2) == (d1 == d2) } + + + val specDoubles: Gen[Double] = oneOf( + Double.MaxValue, + Double.MinPositiveValue, + Double.MinValue, + Double.NaN, + Double.NegativeInfinity, + Double.PositiveInfinity, + -0.0, + +0.0 + ) + + // ticket #5104 + property("Double min") = forAll(specDoubles, specDoubles) { (d1, d2) => { + val mathmin = math.min(d1, d2) + val numericmin = d1 min d2 + mathmin == numericmin || mathmin.isNaN && numericmin.isNaN + } + } + + property("Double max") = forAll(specDoubles, specDoubles) { (d1, d2) => { + val mathmax = math.max(d1, d2) + val numericmax = d1 max d2 + mathmax == numericmax || mathmax.isNaN && numericmax.isNaN + } + } + + val numDouble = implicitly[Numeric[Double]] + + property("Double lt") = forAll(specDoubles, specDoubles) { (d1, d2) => numDouble.lt(d1, d2) == d1 < d2 } + + property("Double lteq") = forAll(specDoubles, specDoubles) { (d1, d2) => numDouble.lteq(d1, d2) == d1 <= d2 } + + property("Double gt") = forAll(specDoubles, specDoubles) { (d1, d2) => numDouble.gt(d1, d2) == d1 > d2 } + + property("Double gteq") = forAll(specDoubles, specDoubles) { (d1, d2) => numDouble.gteq(d1, d2) == d1 >= d2 } + + property("Double equiv") = forAll(specDoubles, specDoubles) { (d1, d2) => numDouble.equiv(d1, d2) == (d1 == d2) } + + property("Double reverse.min") = forAll(specDoubles, specDoubles) { (d1, d2) => { + val mathmin = math.min(d1, d2) + val numericmin = numDouble.reverse.min(d1, d2) + mathmin == numericmin || mathmin.isNaN && numericmin.isNaN + } + } + + property("Double reverse.max") = forAll(specDoubles, specDoubles) { (d1, d2) => { + val mathmax = math.max(d1, d2) + val numericmax = numDouble.reverse.max(d1, d2) + mathmax == numericmax || mathmax.isNaN && numericmax.isNaN + } + } + + property("Double reverse.lt") = forAll(specDoubles, specDoubles) { (d1, d2) => numDouble.reverse.lt(d1, d2) == d2 < d1 } + + property("Double reverse.lteq") = forAll(specDoubles, specDoubles) { (d1, d2) => numDouble.reverse.lteq(d1, d2) == d2 <= d1 } + + property("Double reverse.gt") = forAll(specDoubles, specDoubles) { (d1, d2) => numDouble.reverse.gt(d1, d2) == d2 > d1 } + + property("Double reverse.gteq") = forAll(specDoubles, specDoubles) { (d1, d2) => numDouble.reverse.gteq(d1, d2) == d2 >= d1 } + + property("Double reverse.equiv") = forAll(specDoubles, specDoubles) { (d1, d2) => numDouble.reverse.equiv(d1, d2) == (d1 == d2) } +} diff --git a/test/pending/run/reify_closure1.check b/test/pending/run/reify_closure1.check new file mode 100644 index 0000000000..b2f7f08c17 --- /dev/null +++ b/test/pending/run/reify_closure1.check @@ -0,0 +1,2 @@ +10 +10 diff --git a/test/pending/run/reify_closure1.scala b/test/pending/run/reify_closure1.scala new file mode 100644 index 0000000000..825a38dc1d --- /dev/null +++ b/test/pending/run/reify_closure1.scala @@ -0,0 +1,20 @@ +import scala.tools.nsc.reporters._ +import scala.tools.nsc.Settings +import reflect.runtime.Mirror.ToolBox + +object Test extends App { + def foo[T](ys: List[T]): Int => Int = { + val fun: reflect.Code[Int => Int] = x => { + x + } + + val reporter = new ConsoleReporter(new Settings) + val toolbox = new ToolBox(reporter) + val ttree = toolbox.typeCheck(fun.tree) + val dyn = toolbox.runExpr(ttree) + dyn.asInstanceOf[Int => Int] + } + + println(foo(List(1, 2, 3))(10)) + println(foo(List(1, 2, 3, 4))(10)) +} diff --git a/test/pending/run/reify_closure2a.check b/test/pending/run/reify_closure2a.check new file mode 100644 index 0000000000..c1f3abd7e6 --- /dev/null +++ b/test/pending/run/reify_closure2a.check @@ -0,0 +1,2 @@ +11 +12 diff --git a/test/pending/run/reify_closure2a.scala b/test/pending/run/reify_closure2a.scala new file mode 100644 index 0000000000..b88bec005d --- /dev/null +++ b/test/pending/run/reify_closure2a.scala @@ -0,0 +1,20 @@ +import scala.tools.nsc.reporters._ +import scala.tools.nsc.Settings +import reflect.runtime.Mirror.ToolBox + +object Test extends App { + def foo(y: Int): Int => Int = { + val fun: reflect.Code[Int => Int] = x => { + x + y + } + + val reporter = new ConsoleReporter(new Settings) + val toolbox = new ToolBox(reporter) + val ttree = toolbox.typeCheck(fun.tree) + val dyn = toolbox.runExpr(ttree) + dyn.asInstanceOf[Int => Int] + } + + println(foo(1)(10)) + println(foo(2)(10)) +} diff --git a/test/pending/run/reify_closure2b.check b/test/pending/run/reify_closure2b.check new file mode 100644 index 0000000000..c1f3abd7e6 --- /dev/null +++ b/test/pending/run/reify_closure2b.check @@ -0,0 +1,2 @@ +11 +12 diff --git a/test/pending/run/reify_closure2b.scala b/test/pending/run/reify_closure2b.scala new file mode 100644 index 0000000000..e9fb40bede --- /dev/null +++ b/test/pending/run/reify_closure2b.scala @@ -0,0 +1,22 @@ +import scala.tools.nsc.reporters._ +import scala.tools.nsc.Settings +import reflect.runtime.Mirror.ToolBox + +object Test extends App { + def foo(y: Int): Int => Int = { + class Foo(y: Int) { + val fun: reflect.Code[Int => Int] = x => { + x + y + } + } + + val reporter = new ConsoleReporter(new Settings) + val toolbox = new ToolBox(reporter) + val ttree = toolbox.typeCheck(new Foo(y).fun.tree) + val dyn = toolbox.runExpr(ttree) + dyn.asInstanceOf[Int => Int] + } + + println(foo(1)(10)) + println(foo(2)(10)) +} diff --git a/test/pending/run/reify_closure3a.check b/test/pending/run/reify_closure3a.check new file mode 100644 index 0000000000..c1f3abd7e6 --- /dev/null +++ b/test/pending/run/reify_closure3a.check @@ -0,0 +1,2 @@ +11 +12 diff --git a/test/pending/run/reify_closure3a.scala b/test/pending/run/reify_closure3a.scala new file mode 100644 index 0000000000..6414fa58a3 --- /dev/null +++ b/test/pending/run/reify_closure3a.scala @@ -0,0 +1,22 @@ +import scala.tools.nsc.reporters._ +import scala.tools.nsc.Settings +import reflect.runtime.Mirror.ToolBox + +object Test extends App { + def foo(y: Int): Int => Int = { + def y1 = y + + val fun: reflect.Code[Int => Int] = x => { + x + y1 + } + + val reporter = new ConsoleReporter(new Settings) + val toolbox = new ToolBox(reporter) + val ttree = toolbox.typeCheck(fun.tree) + val dyn = toolbox.runExpr(ttree) + dyn.asInstanceOf[Int => Int] + } + + println(foo(1)(10)) + println(foo(2)(10)) +} diff --git a/test/pending/run/reify_closure3b.check b/test/pending/run/reify_closure3b.check new file mode 100644 index 0000000000..c1f3abd7e6 --- /dev/null +++ b/test/pending/run/reify_closure3b.check @@ -0,0 +1,2 @@ +11 +12 diff --git a/test/pending/run/reify_closure3b.scala b/test/pending/run/reify_closure3b.scala new file mode 100644 index 0000000000..5c4f3c81b9 --- /dev/null +++ b/test/pending/run/reify_closure3b.scala @@ -0,0 +1,24 @@ +import scala.tools.nsc.reporters._ +import scala.tools.nsc.Settings +import reflect.runtime.Mirror.ToolBox + +object Test extends App { + def foo(y: Int): Int => Int = { + class Foo(y: Int) { + def y1 = y + + val fun: reflect.Code[Int => Int] = x => { + x + y1 + } + } + + val reporter = new ConsoleReporter(new Settings) + val toolbox = new ToolBox(reporter) + val ttree = toolbox.typeCheck(new Foo(y).fun.tree) + val dyn = toolbox.runExpr(ttree) + dyn.asInstanceOf[Int => Int] + } + + println(foo(1)(10)) + println(foo(2)(10)) +} diff --git a/test/pending/run/reify_closure4a.check b/test/pending/run/reify_closure4a.check new file mode 100644 index 0000000000..c1f3abd7e6 --- /dev/null +++ b/test/pending/run/reify_closure4a.check @@ -0,0 +1,2 @@ +11 +12 diff --git a/test/pending/run/reify_closure4a.scala b/test/pending/run/reify_closure4a.scala new file mode 100644 index 0000000000..99e9d82706 --- /dev/null +++ b/test/pending/run/reify_closure4a.scala @@ -0,0 +1,22 @@ +import scala.tools.nsc.reporters._ +import scala.tools.nsc.Settings +import reflect.runtime.Mirror.ToolBox + +object Test extends App { + def foo(y: Int): Int => Int = { + val y1 = y + + val fun: reflect.Code[Int => Int] = x => { + x + y1 + } + + val reporter = new ConsoleReporter(new Settings) + val toolbox = new ToolBox(reporter) + val ttree = toolbox.typeCheck(fun.tree) + val dyn = toolbox.runExpr(ttree) + dyn.asInstanceOf[Int => Int] + } + + println(foo(1)(10)) + println(foo(2)(10)) +} diff --git a/test/pending/run/reify_closure4b.check b/test/pending/run/reify_closure4b.check new file mode 100644 index 0000000000..c1f3abd7e6 --- /dev/null +++ b/test/pending/run/reify_closure4b.check @@ -0,0 +1,2 @@ +11 +12 diff --git a/test/pending/run/reify_closure4b.scala b/test/pending/run/reify_closure4b.scala new file mode 100644 index 0000000000..24dfa9fe17 --- /dev/null +++ b/test/pending/run/reify_closure4b.scala @@ -0,0 +1,24 @@ +import scala.tools.nsc.reporters._ +import scala.tools.nsc.Settings +import reflect.runtime.Mirror.ToolBox + +object Test extends App { + def foo(y: Int): Int => Int = { + class Foo(y: Int) { + val y1 = y + + val fun: reflect.Code[Int => Int] = x => { + x + y1 + } + } + + val reporter = new ConsoleReporter(new Settings) + val toolbox = new ToolBox(reporter) + val ttree = toolbox.typeCheck(new Foo(y).fun.tree) + val dyn = toolbox.runExpr(ttree) + dyn.asInstanceOf[Int => Int] + } + + println(foo(1)(10)) + println(foo(2)(10)) +} diff --git a/test/pending/run/reify_closure5a.check b/test/pending/run/reify_closure5a.check new file mode 100644 index 0000000000..df9e19c591 --- /dev/null +++ b/test/pending/run/reify_closure5a.check @@ -0,0 +1,2 @@ +13 +14 diff --git a/test/pending/run/reify_closure5a.scala b/test/pending/run/reify_closure5a.scala new file mode 100644 index 0000000000..0ac53d5479 --- /dev/null +++ b/test/pending/run/reify_closure5a.scala @@ -0,0 +1,20 @@ +import scala.tools.nsc.reporters._ +import scala.tools.nsc.Settings +import reflect.runtime.Mirror.ToolBox + +object Test extends App { + def foo[T](ys: List[T]): Int => Int = { + val fun: reflect.Code[Int => Int] = x => { + x + ys.length + } + + val reporter = new ConsoleReporter(new Settings) + val toolbox = new ToolBox(reporter) + val ttree = toolbox.typeCheck(fun.tree) + val dyn = toolbox.runExpr(ttree) + dyn.asInstanceOf[Int => Int] + } + + println(foo(List(1, 2, 3))(10)) + println(foo(List(1, 2, 3, 4))(10)) +} diff --git a/test/pending/run/reify_closure5b.check b/test/pending/run/reify_closure5b.check new file mode 100644 index 0000000000..df9e19c591 --- /dev/null +++ b/test/pending/run/reify_closure5b.check @@ -0,0 +1,2 @@ +13 +14 diff --git a/test/pending/run/reify_closure5b.scala b/test/pending/run/reify_closure5b.scala new file mode 100644 index 0000000000..02eb771f0c --- /dev/null +++ b/test/pending/run/reify_closure5b.scala @@ -0,0 +1,22 @@ +import scala.tools.nsc.reporters._ +import scala.tools.nsc.Settings +import reflect.runtime.Mirror.ToolBox + +object Test extends App { + def foo[T](ys: List[T]): Int => Int = { + class Foo[T](ys: List[T]) { + val fun: reflect.Code[Int => Int] = x => { + x + ys.length + } + } + + val reporter = new ConsoleReporter(new Settings) + val toolbox = new ToolBox(reporter) + val ttree = toolbox.typeCheck(new Foo(ys).fun.tree) + val dyn = toolbox.runExpr(ttree) + dyn.asInstanceOf[Int => Int] + } + + println(foo(List(1, 2, 3))(10)) + println(foo(List(1, 2, 3, 4))(10)) +} diff --git a/test/pending/run/reify_closure6.check b/test/pending/run/reify_closure6.check new file mode 100644 index 0000000000..3526d04b0e --- /dev/null +++ b/test/pending/run/reify_closure6.check @@ -0,0 +1,3 @@ +first invocation = 15 +second invocation = 18 +q after second invocation = 2 diff --git a/test/pending/run/reify_closure6.scala b/test/pending/run/reify_closure6.scala new file mode 100644 index 0000000000..909071aa44 --- /dev/null +++ b/test/pending/run/reify_closure6.scala @@ -0,0 +1,26 @@ +import scala.tools.nsc.reporters._ +import scala.tools.nsc.Settings +import reflect.runtime.Mirror.ToolBox + +object Test extends App { + var q = 0 + def foo[T](ys: List[T]): Int => Int = { + val z = 1 + var y = 0 + val fun: reflect.Code[Int => Int] = x => { + y += 1 + q += 1 + x + ys.length * z + q + y + } + + val reporter = new ConsoleReporter(new Settings) + val toolbox = new ToolBox(reporter) + val ttree = toolbox.typeCheck(fun.tree) + val dyn = toolbox.runExpr(ttree) + dyn.asInstanceOf[Int => Int] + } + + println("first invocation = " + foo(List(1, 2, 3))(10)) + println("second invocation = " + foo(List(1, 2, 3, 4))(10)) + println("q after second invocation = " + q) +} diff --git a/test/pending/run/t5334_1.scala b/test/pending/run/t5334_1.scala new file mode 100644 index 0000000000..c1eba89c2b --- /dev/null +++ b/test/pending/run/t5334_1.scala @@ -0,0 +1,15 @@ +import scala.tools.nsc.reporters._ +import scala.tools.nsc.Settings +import reflect.runtime.Mirror.ToolBox + +object Test extends App { + val code = scala.reflect.Code.lift{ + class C + new C + }; + + val reporter = new ConsoleReporter(new Settings) + val toolbox = new ToolBox(reporter) + val ttree = toolbox.typeCheck(code.tree) + toolbox.runExpr(ttree) +} diff --git a/test/pending/run/t5334_2.scala b/test/pending/run/t5334_2.scala new file mode 100644 index 0000000000..361b8c85f2 --- /dev/null +++ b/test/pending/run/t5334_2.scala @@ -0,0 +1,15 @@ +import scala.tools.nsc.reporters._ +import scala.tools.nsc.Settings +import reflect.runtime.Mirror.ToolBox + +object Test extends App { + val code = scala.reflect.Code.lift{ + class C + List((new C, new C)) + }; + + val reporter = new ConsoleReporter(new Settings) + val toolbox = new ToolBox(reporter) + val ttree = toolbox.typeCheck(code.tree) + toolbox.runExpr(ttree) +} |