diff options
34 files changed, 505 insertions, 121 deletions
diff --git a/src/compiler/scala/reflect/internal/Definitions.scala b/src/compiler/scala/reflect/internal/Definitions.scala index 1c3e11b040..edafde1346 100644 --- a/src/compiler/scala/reflect/internal/Definitions.scala +++ b/src/compiler/scala/reflect/internal/Definitions.scala @@ -896,6 +896,7 @@ trait Definitions extends reflect.api.StandardDefinitions { // boxed classes lazy val ObjectRefClass = requiredClass[scala.runtime.ObjectRef[_]] lazy val VolatileObjectRefClass = requiredClass[scala.runtime.VolatileObjectRef[_]] + lazy val RuntimeStaticsModule = getRequiredModule("scala.runtime.Statics") lazy val BoxesRunTimeModule = getRequiredModule("scala.runtime.BoxesRunTime") lazy val BoxesRunTimeClass = BoxesRunTimeModule.moduleClass lazy val BoxedNumberClass = getClass(sn.BoxedNumber) diff --git a/src/compiler/scala/tools/nsc/interactive/Global.scala b/src/compiler/scala/tools/nsc/interactive/Global.scala index ec73af4dca..cf80570563 100644 --- a/src/compiler/scala/tools/nsc/interactive/Global.scala +++ b/src/compiler/scala/tools/nsc/interactive/Global.scala @@ -352,6 +352,10 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "") case item: WorkItem => Some(item.raiseMissing()) case _ => Some(()) } + + // don't forget to service interrupt requests + val iqs = scheduler.dequeueAllInterrupts(_.execute()) + debugLog("ShutdownReq: cleaning work queue (%d items)".format(units.size)) debugLog("Cleanup up responses (%d loadedType pending, %d parsedEntered pending)" .format(waitLoadedTypeResponses.size, getParsedEnteredResponses.size)) diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala index fb0616c890..5534cd179c 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala @@ -499,7 +499,8 @@ trait Infer { else Some( if (targ.typeSymbol == RepeatedParamClass) targ.baseType(SeqClass) else if (targ.typeSymbol == JavaRepeatedParamClass) targ.baseType(ArrayClass) - else if ((opt.experimental || opt.virtPatmat) && tvar.constr.avoidWiden) targ + // this infers Foo.type instead of "object Foo" (see also widenIfNecessary) + else if (targ.typeSymbol.isModuleClass || ((opt.experimental || opt.virtPatmat) && tvar.constr.avoidWiden)) targ else targ.widen ) )) diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala index 6620ef7347..ca4b1d3de8 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala @@ -765,7 +765,10 @@ trait Namers extends MethodSynthesis { val tpe1 = dropRepeatedParamType(tpe.deconst) val tpe2 = tpe1.widen - if (sym.isVariable || sym.isMethod && !sym.hasAccessorFlag) + // This infers Foo.type instead of "object Foo" + // See Infer#adjustTypeArgs for the polymorphic case. + if (tpe.typeSymbolDirect.isModuleClass) tpe1 + else if (sym.isVariable || sym.isMethod && !sym.hasAccessorFlag) if (tpe2 <:< pt) tpe2 else tpe1 else if (isHidden(tpe)) tpe2 // In an attempt to make pattern matches involving method local vals @@ -784,8 +787,8 @@ trait Namers extends MethodSynthesis { val typedBody = if (tree.symbol.isTermMacro) defnTyper.computeMacroDefType(tree, pt) else defnTyper.computeType(tree.rhs, pt) - val sym = if (owner.isMethod) owner else tree.symbol - val typedDefn = widenIfNecessary(sym, typedBody, pt) + + val typedDefn = widenIfNecessary(tree.symbol, typedBody, pt) assignTypeToTree(tree, typedDefn) } diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index e60cda6af7..6bed0b1228 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -386,8 +386,9 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R overrideError("cannot be used here - classes can only override abstract types"); } else if (other.isEffectivelyFinal) { // (1.2) overrideError("cannot override final member"); - // synthetic exclusion needed for (at least) default getters. - } else if (!other.isDeferred && !member.isAnyOverride && !member.isSynthetic) { + } else if (!other.isDeferred && !member.isAnyOverride && !member.isSynthetic) { // (*) + // (*) Synthetic exclusion for (at least) default getters, fixes SI-5178. We cannot assign the OVERRIDE flag to + // the default getter: one default getter might sometimes override, sometimes not. Example in comment on ticket. if (isNeitherInClass && !(other.owner isSubClass member.owner)) emitOverrideError( clazz + " inherits conflicting members:\n " diff --git a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala index 57e82ed706..484c8beb1b 100644 --- a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala +++ b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala @@ -89,6 +89,11 @@ trait SyntheticMethods extends ast.TreeDSL { def forwardToRuntime(method: Symbol): Tree = forwardMethod(method, getMember(ScalaRunTimeModule, method.name prepend "_"))(mkThis :: _) + def callStaticsMethod(name: String)(args: Tree*): Tree = { + val method = termMember(RuntimeStaticsModule, name) + Apply(gen.mkAttributedRef(method), args.toList) + } + // Any member, including private def hasConcreteImpl(name: Name) = clazz.info.member(name).alternatives exists (m => !m.isDeferred && !m.isSynthetic) @@ -222,13 +227,41 @@ trait SyntheticMethods extends ast.TreeDSL { ) } + def hashcodeImplementation(sym: Symbol): Tree = { + sym.tpe.finalResultType.typeSymbol match { + case UnitClass | NullClass => Literal(Constant(0)) + case BooleanClass => If(Ident(sym), Literal(Constant(1231)), Literal(Constant(1237))) + case IntClass | ShortClass | ByteClass | CharClass => Ident(sym) + case LongClass => callStaticsMethod("longHash")(Ident(sym)) + case DoubleClass => callStaticsMethod("doubleHash")(Ident(sym)) + case FloatClass => callStaticsMethod("floatHash")(Ident(sym)) + case _ => callStaticsMethod("anyHash")(Ident(sym)) + } + } + + def specializedHashcode = { + createMethod(nme.hashCode_, Nil, IntClass.tpe) { m => + val accumulator = m.newVariable(newTermName("acc"), m.pos, SYNTHETIC) setInfo IntClass.tpe + val valdef = ValDef(accumulator, Literal(Constant(0xcafebabe))) + val mixes = accessors map (acc => + Assign( + Ident(accumulator), + callStaticsMethod("mix")(Ident(accumulator), hashcodeImplementation(acc)) + ) + ) + val finish = callStaticsMethod("finalizeHash")(Ident(accumulator), Literal(Constant(arity))) + + Block(valdef :: mixes, finish) + } + } + def valueClassMethods = List( Any_hashCode -> (() => hashCodeDerivedValueClassMethod), Any_equals -> (() => equalsDerivedValueClassMethod) ) def caseClassMethods = productMethods ++ productNMethods ++ Seq( - Object_hashCode -> (() => forwardToRuntime(Object_hashCode)), + Object_hashCode -> (() => specializedHashcode), Object_toString -> (() => forwardToRuntime(Object_toString)), Object_equals -> (() => equalsCaseClassMethod) ) diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 08d6bd7226..343636ff1e 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -2297,7 +2297,7 @@ trait Typers extends Modes with Adaptations with Taggings { import CODE._ // need to duplicate the cases before typing them to generate the apply method, or the symbols will be all messed up - val casesTrue = if (isPartial) cases map (c => deriveCaseDef(c)(x => TRUE_typed).duplicate) else Nil + val casesTrue = if (isPartial) cases map (c => deriveCaseDef(c)(x => atPos(x.pos.focus)(TRUE_typed)).duplicate) else Nil // println("casesTrue "+ casesTrue) def parentsPartial(targs: List[Type]) = addSerializable(appliedType(AbstractPartialFunctionClass.typeConstructor, targs)) @@ -2372,7 +2372,7 @@ trait Typers extends Modes with Adaptations with Taggings { } def isDefinedAtMethod = { - val methodSym = anonClass.newMethod(nme.isDefinedAt, tree.pos, FINAL) + val methodSym = anonClass.newMethod(nme.isDefinedAt, tree.pos.makeTransparent, FINAL) val paramSyms = mkParams(methodSym) val selector = mkSel(paramSyms) @@ -2398,7 +2398,7 @@ trait Typers extends Modes with Adaptations with Taggings { def translated = if (members.head eq EmptyTree) setError(tree) - else typed(Block(List(ClassDef(anonClass, NoMods, List(List()), List(List()), members, tree.pos)), New(anonClass.tpe)), mode, pt) + else typed(atPos(tree.pos)(Block(List(ClassDef(anonClass, NoMods, List(List()), List(List()), members, tree.pos.focus)), atPos(tree.pos.focus)(New(anonClass.tpe)))), mode, pt) } // Function(params, Match(sel, cases)) ==> new <Partial>Function { def apply<OrElse>(params) = `translateMatch('sel match { cases }')` } diff --git a/src/compiler/scala/tools/nsc/util/WorkScheduler.scala b/src/compiler/scala/tools/nsc/util/WorkScheduler.scala index 2534e1192d..8c037cbda5 100644 --- a/src/compiler/scala/tools/nsc/util/WorkScheduler.scala +++ b/src/compiler/scala/tools/nsc/util/WorkScheduler.scala @@ -30,6 +30,10 @@ class WorkScheduler { todo.dequeueAll(a => f(a).isDefined).map(a => f(a).get) } + def dequeueAllInterrupts(f: InterruptReq => Unit): Unit = synchronized { + interruptReqs.dequeueAll { iq => f(iq); true } + } + /** Called from server: return optional exception posted by client * Reset to no exception. */ diff --git a/src/library/scala/collection/Iterator.scala b/src/library/scala/collection/Iterator.scala index e9a7906527..7d5cd9989c 100644 --- a/src/library/scala/collection/Iterator.scala +++ b/src/library/scala/collection/Iterator.scala @@ -1079,11 +1079,12 @@ trait Iterator[+A] extends TraversableOnce[A] { if (i < from) origElems.hasNext else patchElems.hasNext || origElems.hasNext def next(): B = { + // We have to do this *first* just in case from = 0. + if (i == from) origElems = origElems drop replaced val result: B = if (i < from || !patchElems.hasNext) origElems.next() else patchElems.next() i += 1 - if (i == from) origElems = origElems drop replaced result } } diff --git a/src/library/scala/collection/TraversableViewLike.scala b/src/library/scala/collection/TraversableViewLike.scala index 5ca038fd2e..eb2091a5f3 100644 --- a/src/library/scala/collection/TraversableViewLike.scala +++ b/src/library/scala/collection/TraversableViewLike.scala @@ -162,6 +162,8 @@ trait TraversableViewLike[+A, // if (b.isInstanceOf[NoBuilder[_]]) newFlatMapped(f).asInstanceOf[That] // else super.flatMap[B, That](f)(bf) } + override def flatten[B](implicit asTraversable: A => /*<:<!!!*/ GenTraversableOnce[B]) = + newFlatMapped(asTraversable) private[this] implicit def asThis(xs: Transformed[A]): This = xs.asInstanceOf[This] /** Boilerplate method, to override in each subclass diff --git a/src/library/scala/runtime/BoxesRunTime.java b/src/library/scala/runtime/BoxesRunTime.java index 258a176671..8fe9a017d0 100644 --- a/src/library/scala/runtime/BoxesRunTime.java +++ b/src/library/scala/runtime/BoxesRunTime.java @@ -228,7 +228,7 @@ public final class BoxesRunTime * as yet have not. * * Note: Among primitives, Float.NaN != Float.NaN, but the boxed - * verisons are equal. This still needs reconciliation. + * versions are equal. This still needs reconciliation. */ public static int hashFromLong(java.lang.Long n) { int iv = n.intValue(); @@ -242,6 +242,9 @@ public final class BoxesRunTime long lv = n.longValue(); if (lv == dv) return java.lang.Long.valueOf(lv).hashCode(); + + float fv = n.floatValue(); + if (fv == dv) return java.lang.Float.valueOf(fv).hashCode(); else return n.hashCode(); } public static int hashFromFloat(java.lang.Float n) { diff --git a/src/library/scala/runtime/ScalaRunTime.scala b/src/library/scala/runtime/ScalaRunTime.scala index a04fd23710..4c5e0e408b 100644 --- a/src/library/scala/runtime/ScalaRunTime.scala +++ b/src/library/scala/runtime/ScalaRunTime.scala @@ -234,13 +234,10 @@ object ScalaRunTime { // Note that these are the implementations called by ##, so they // must not call ## themselves. - @inline def hash(x: Any): Int = x match { - case null => 0 - case x: Double => hash(x) - case x: Float => hash(x) - case x: java.lang.Number => hash(x) - case _ => x.hashCode - } + @inline def hash(x: Any): Int = + if (x == null) 0 + else if (x.isInstanceOf[java.lang.Number]) BoxesRunTime.hashFromNumber(x.asInstanceOf[java.lang.Number]) + else x.hashCode @inline def hash(dv: Double): Int = { val iv = dv.toInt diff --git a/src/library/scala/runtime/Statics.java b/src/library/scala/runtime/Statics.java new file mode 100644 index 0000000000..485511ecbb --- /dev/null +++ b/src/library/scala/runtime/Statics.java @@ -0,0 +1,89 @@ +package scala.runtime; + +/** Not for public consumption. Usage by the runtime only. + */ + +public final class Statics { + public static int mix(int hash, int data) { + int h = mixLast(hash, data); + h = Integer.rotateLeft(h, 13); + return h * 5 + 0xe6546b64; + } + + public static int mixLast(int hash, int data) { + int k = data; + + k *= 0xcc9e2d51; + k = Integer.rotateLeft(k, 15); + k *= 0x1b873593; + + return hash ^ k; + } + + public static int finalizeHash(int hash, int length) { + return avalanche(hash ^ length); + } + + /** Force all bits of the hash to avalanche. Used for finalizing the hash. */ + public static int avalanche(int h) { + h ^= h >>> 16; + h *= 0x85ebca6b; + h ^= h >>> 13; + h *= 0xc2b2ae35; + h ^= h >>> 16; + + return h; + } + + public static int longHash(long lv) { + if ((int)lv == lv) + return (int)lv; + else + return (int)(lv ^ (lv >>> 32)); + } + + public static int doubleHash(double dv) { + int iv = (int)dv; + if (iv == dv) + return iv; + + float fv = (float)dv; + if (fv == dv) + return java.lang.Float.floatToIntBits(fv); + + long lv = (long)dv; + if (lv == dv) + return (int)lv; + + lv = Double.doubleToLongBits(dv); + return (int)(lv ^ (lv >>> 32)); + } + + public static int floatHash(float fv) { + int iv = (int)fv; + if (iv == fv) + return iv; + + long lv = (long)fv; + if (lv == fv) + return (int)(lv^(lv>>>32)); + + return java.lang.Float.floatToIntBits(fv); + } + + public static int anyHash(Object x) { + if (x == null) + return 0; + + if (x instanceof java.lang.Long) + return longHash(((java.lang.Long)x).longValue()); + + if (x instanceof java.lang.Double) + return doubleHash(((java.lang.Double)x).doubleValue()); + + if (x instanceof java.lang.Float) + return floatHash(((java.lang.Float)x).floatValue()); + + return x.hashCode(); + } +} diff --git a/test/files/jvm/manifests-new.check b/test/files/jvm/manifests-new.check index 9fca856970..896a5c1cef 100644 --- a/test/files/jvm/manifests-new.check +++ b/test/files/jvm/manifests-new.check @@ -1,58 +1,58 @@ -x=(), t=ConcreteTypeTag[Unit], k=TypeRef, s=class Unit
-x=true, t=ConcreteTypeTag[Boolean], k=TypeRef, s=class Boolean
-x=a, t=ConcreteTypeTag[Char], k=TypeRef, s=class Char
-x=1, t=ConcreteTypeTag[Int], k=TypeRef, s=class Int
-x=abc, t=ConcreteTypeTag[String], k=TypeRef, s=class String
-x='abc, t=ConcreteTypeTag[Symbol], k=TypeRef, s=class Symbol
-
-x=List(()), t=ConcreteTypeTag[List[Unit]], k=TypeRef, s=class List
-x=List(true), t=ConcreteTypeTag[List[Boolean]], k=TypeRef, s=class List
-x=List(1), t=ConcreteTypeTag[List[Int]], k=TypeRef, s=class List
-x=List(abc), t=ConcreteTypeTag[List[String]], k=TypeRef, s=class List
-x=List('abc), t=ConcreteTypeTag[List[Symbol]], k=TypeRef, s=class List
-
-x=[Z, t=ConcreteTypeTag[Array[Boolean]], k=TypeRef, s=class Array
-x=[C, t=ConcreteTypeTag[Array[Char]], k=TypeRef, s=class Array
-x=[I, t=ConcreteTypeTag[Array[Int]], k=TypeRef, s=class Array
-x=[Ljava.lang.String;, t=ConcreteTypeTag[Array[String]], k=TypeRef, s=class Array
-x=[Lscala.Symbol;, t=ConcreteTypeTag[Array[Symbol]], k=TypeRef, s=class Array
-
-x=((),()), t=ConcreteTypeTag[(Unit, Unit)], k=TypeRef, s=class Tuple2
-x=(true,false), t=ConcreteTypeTag[(Boolean, Boolean)], k=TypeRef, s=class Tuple2
-x=(1,2), t=ConcreteTypeTag[(Int, Int)], k=TypeRef, s=class Tuple2
-x=(abc,xyz), t=ConcreteTypeTag[(String, String)], k=TypeRef, s=class Tuple2
-x=('abc,'xyz), t=ConcreteTypeTag[(Symbol, Symbol)], k=TypeRef, s=class Tuple2
-
-x=Test$, t=ConcreteTypeTag[Test.type], k=TypeRef, s=object Test
-x=scala.collection.immutable.List$, t=ConcreteTypeTag[scala.collection.immutable.List.type], k=TypeRef, s=object List
-
-x=Foo, t=ConcreteTypeTag[Foo[Int]], k=TypeRef, s=class Foo
-x=Foo, t=ConcreteTypeTag[Foo[List[Int]]], k=TypeRef, s=class Foo
-x=Foo, t=ConcreteTypeTag[Foo[Foo[Int]]], k=TypeRef, s=class Foo
-x=Foo, t=ConcreteTypeTag[Foo[List[Foo[Int]]]], k=TypeRef, s=class Foo
-
-x=Test1$$anon$1, t=ConcreteTypeTag[Bar[String]], k=RefinedType, s=<local Test1>
-x=Test1$$anon$2, t=ConcreteTypeTag[Bar[String]], k=RefinedType, s=<local Test1>
-
-()=()
-true=true
-a=a
-1=1
-'abc='abc
-
-List(())=List(())
-List(true)=List(true)
-List('abc)=List('abc)
-
-Array()=Array()
-Array(true)=Array(true)
-Array(a)=Array(a)
-Array(1)=Array(1)
-
-((),())=((),())
-(true,false)=(true,false)
-
-List(List(1), List(2))=List(List(1), List(2))
-
-Array(Array(1), Array(2))=Array(Array(1), Array(2))
-
+x=(), t=ConcreteTypeTag[Unit], k=TypeRef, s=class Unit +x=true, t=ConcreteTypeTag[Boolean], k=TypeRef, s=class Boolean +x=a, t=ConcreteTypeTag[Char], k=TypeRef, s=class Char +x=1, t=ConcreteTypeTag[Int], k=TypeRef, s=class Int +x=abc, t=ConcreteTypeTag[String], k=TypeRef, s=class String +x='abc, t=ConcreteTypeTag[Symbol], k=TypeRef, s=class Symbol + +x=List(()), t=ConcreteTypeTag[List[Unit]], k=TypeRef, s=class List +x=List(true), t=ConcreteTypeTag[List[Boolean]], k=TypeRef, s=class List +x=List(1), t=ConcreteTypeTag[List[Int]], k=TypeRef, s=class List +x=List(abc), t=ConcreteTypeTag[List[String]], k=TypeRef, s=class List +x=List('abc), t=ConcreteTypeTag[List[Symbol]], k=TypeRef, s=class List + +x=[Z, t=ConcreteTypeTag[Array[Boolean]], k=TypeRef, s=class Array +x=[C, t=ConcreteTypeTag[Array[Char]], k=TypeRef, s=class Array +x=[I, t=ConcreteTypeTag[Array[Int]], k=TypeRef, s=class Array +x=[Ljava.lang.String;, t=ConcreteTypeTag[Array[String]], k=TypeRef, s=class Array +x=[Lscala.Symbol;, t=ConcreteTypeTag[Array[Symbol]], k=TypeRef, s=class Array + +x=((),()), t=ConcreteTypeTag[(Unit, Unit)], k=TypeRef, s=class Tuple2 +x=(true,false), t=ConcreteTypeTag[(Boolean, Boolean)], k=TypeRef, s=class Tuple2 +x=(1,2), t=ConcreteTypeTag[(Int, Int)], k=TypeRef, s=class Tuple2 +x=(abc,xyz), t=ConcreteTypeTag[(String, String)], k=TypeRef, s=class Tuple2 +x=('abc,'xyz), t=ConcreteTypeTag[(Symbol, Symbol)], k=TypeRef, s=class Tuple2 + +x=Test$, t=ConcreteTypeTag[Test.type], k=SingleType, s=object Test +x=scala.collection.immutable.List$, t=ConcreteTypeTag[scala.collection.immutable.List.type], k=SingleType, s=object List + +x=Foo, t=ConcreteTypeTag[Foo[Int]], k=TypeRef, s=class Foo +x=Foo, t=ConcreteTypeTag[Foo[List[Int]]], k=TypeRef, s=class Foo +x=Foo, t=ConcreteTypeTag[Foo[Foo[Int]]], k=TypeRef, s=class Foo +x=Foo, t=ConcreteTypeTag[Foo[List[Foo[Int]]]], k=TypeRef, s=class Foo + +x=Test1$$anon$1, t=ConcreteTypeTag[Bar[String]], k=RefinedType, s=<local Test1> +x=Test1$$anon$2, t=ConcreteTypeTag[Bar[String]], k=RefinedType, s=<local Test1> + +()=() +true=true +a=a +1=1 +'abc='abc + +List(())=List(()) +List(true)=List(true) +List('abc)=List('abc) + +Array()=Array() +Array(true)=Array(true) +Array(a)=Array(a) +Array(1)=Array(1) + +((),())=((),()) +(true,false)=(true,false) + +List(List(1), List(2))=List(List(1), List(2)) + +Array(Array(1), Array(2))=Array(Array(1), Array(2)) + diff --git a/test/files/pos/rangepos-patmat.flags b/test/files/pos/rangepos-patmat.flags new file mode 100644 index 0000000000..281f0a10cd --- /dev/null +++ b/test/files/pos/rangepos-patmat.flags @@ -0,0 +1 @@ +-Yrangepos diff --git a/test/files/pos/rangepos-patmat.scala b/test/files/pos/rangepos-patmat.scala new file mode 100644 index 0000000000..98c842aaf8 --- /dev/null +++ b/test/files/pos/rangepos-patmat.scala @@ -0,0 +1,4 @@ +class Foo { + def test: PartialFunction[Any, String] = { case _ => "ok" } + +} diff --git a/test/files/pos/t5210.scala b/test/files/pos/t5210.scala new file mode 100644 index 0000000000..e85037a902 --- /dev/null +++ b/test/files/pos/t5210.scala @@ -0,0 +1,10 @@ +object WithOpTest { + trait WithOp extends Cloneable { + def f: this.type = this + def g1: this.type = f + def g2: this.type = { + val t = f + t + } + } +} diff --git a/test/files/pos/t5777.scala b/test/files/pos/t5777.scala new file mode 100644 index 0000000000..24cea36163 --- /dev/null +++ b/test/files/pos/t5777.scala @@ -0,0 +1,45 @@ +// /scala/trac/5777/a.scala +// Wed May 9 08:44:57 PDT 2012 + +trait Ring { + trait E +} + +class Poly[C <: Ring](val ring: C) extends Ring +// This definition of Poly triggers the same failure on *both* versions +// class Poly(val ring: Ring) extends Ring + +object BigInt extends Ring + +object MyApp { + val r = new Poly(BigInt) + + implicitly[r.ring.E <:< BigInt.E] + + // fail on 2.10, works on 2.9.2 + (null.asInstanceOf[BigInt.E] : r.ring.E) + + // works on both versions + val r1 = new Poly[BigInt.type](BigInt) + (null.asInstanceOf[BigInt.E] : r1.ring.E) + + // Oddly, -Xprint:typer reports that r and r1 have the same inferred type. + // + // private[this] val r: Poly[BigInt.type] = new Poly[BigInt.type](BigInt); + // <stable> <accessor> def r: Poly[BigInt.type] = MyApp.this.r; + // (null.asInstanceOf[BigInt.E]: MyApp.r.ring.E); + // private[this] val r1: Poly[BigInt.type] = new Poly[BigInt.type](BigInt); + // <stable> <accessor> def r1: Poly[BigInt.type] = MyApp.this.r1; + // (null.asInstanceOf[BigInt.E]: MyApp.r1.ring.E) + + // diff typer-2.9.2.txt typer-2.10.txt + // ... + // --- + // > object MyApp extends scala.AnyRef { + // > def <init>(): MyApp.type = { + // > MyApp.super.<init>(); + // 30c30 + // < scala.this.Predef.implicitly[<:<[BigInt.E,MyApp.r.ring.E]](scala.this.Predef.conforms[BigInt.E]); + // --- + // > scala.this.Predef.implicitly[<:<[BigInt.E,MyApp.r.ring.E]](); +} diff --git a/test/files/run/caseClassHash.check b/test/files/run/caseClassHash.check new file mode 100644 index 0000000000..b5a6f08e99 --- /dev/null +++ b/test/files/run/caseClassHash.check @@ -0,0 +1,9 @@ +Foo(true,-1,-1,d,-5,-10,500.0,500.0,List(),5.0) +Foo(true,-1,-1,d,-5,-10,500.0,500.0,List(),5) +1383698062 +1383698062 +true +## method 1: 1383698062 +## method 2: 1383698062 + Murmur 1: 1383698062 + Murmur 2: 1383698062 diff --git a/test/files/run/caseClassHash.scala b/test/files/run/caseClassHash.scala new file mode 100644 index 0000000000..7adfddedf8 --- /dev/null +++ b/test/files/run/caseClassHash.scala @@ -0,0 +1,37 @@ +case class Foo[T](a: Boolean, b: Byte, c: Short, d: Char, e: Int, f: Long, g: Double, h: Float, i: AnyRef, j: T) { } + +object Test { + def mkFoo[T](x: T) = Foo[T](true, -1, -1, 100, -5, -10, 500d, 500f, Nil, x) + + def main(args: Array[String]): Unit = { + val foo1 = mkFoo[Double](5.0d) + val foo2 = mkFoo[Long](5l) + + List(foo1, foo2, foo1.##, foo2.##, foo1 == foo2) foreach println + + println("## method 1: " + foo1.##) + println("## method 2: " + foo2.##) + println(" Murmur 1: " + scala.util.MurmurHash3.productHash(foo1)) + println(" Murmur 2: " + scala.util.MurmurHash3.productHash(foo2)) + } +} + +object Timing { + var hash = 0 + def mkFoo(i: Int) = Foo(i % 2 == 0, i.toByte, i.toShort, i.toChar, i, i, 1.1, 1.1f, this, this) + + def main(args: Array[String]): Unit = { + val reps = if (args.isEmpty) 100000000 else args(0).toInt + val start = System.nanoTime + + println("Warmup.") + 1 to 10000 foreach mkFoo + + hash = 0 + 1 to reps foreach (i => hash += mkFoo(i).##) + + val end = System.nanoTime + println("hash = " + hash) + println("Elapsed: " + ((end - start) / 1e6) + " ms.") + } +} diff --git a/test/files/run/hashhash.scala b/test/files/run/hashhash.scala index dc31df8cfa..f9fc067398 100644 --- a/test/files/run/hashhash.scala +++ b/test/files/run/hashhash.scala @@ -9,7 +9,15 @@ object Test { val x = (BigInt(1) << 64).toDouble val y: Any = x + val f: Float = x.toFloat + val jn: java.lang.Number = x + val jf: java.lang.Float = x.toFloat + val jd: java.lang.Double = x assert(x.## == y.##, ((x, y))) + assert(x.## == f.##, ((x, f))) + assert(x.## == jn.##, ((x, jn))) + assert(x.## == jf.##, ((x, jf))) + assert(x.## == jd.##, ((x, jd))) } } diff --git a/test/files/run/inline-ex-handlers.check b/test/files/run/inline-ex-handlers.check index a5d7e93334..dbd778d8b1 100644 --- a/test/files/run/inline-ex-handlers.check +++ b/test/files/run/inline-ex-handlers.check @@ -17,11 +17,11 @@ 204a199,200 > 92 STORE_LOCAL(variable boxed1) > 92 LOAD_LOCAL(variable boxed1) -395c391 +405c401 < blocks: [1,2,3,4,5,8,11,13,14,16] --- > blocks: [1,2,3,5,8,11,13,14,16,17] -419c415,424 +429c425,434 < 103 THROW(MyException) --- > ? STORE_LOCAL(value ex5) @@ -34,15 +34,15 @@ > 106 LOAD_LOCAL(value x3) > 106 IS_INSTANCE REF(class MyException) > 106 CZJUMP (BOOL)NE ? 5 : 11 -432,434d436 +442,444d446 < 101 JUMP 4 < < 4: -522c524 +532c534 < blocks: [1,2,3,4,6,7,8,9,10] --- > blocks: [1,2,3,4,6,7,8,9,10,11,12,13] -551c553,558 +561c563,568 < 306 THROW(MyException) --- > ? JUMP 11 @@ -51,7 +51,7 @@ > ? LOAD_LOCAL(variable monitor4) > 305 MONITOR_EXIT > ? JUMP 12 -557c564,570 +567c574,580 < ? THROW(Throwable) --- > ? JUMP 12 @@ -61,7 +61,7 @@ > 304 MONITOR_EXIT > ? STORE_LOCAL(value t) > ? JUMP 13 -563c576,589 +573c586,599 < ? THROW(Throwable) --- > ? STORE_LOCAL(value t) @@ -78,30 +78,30 @@ > 310 CALL_PRIMITIVE(EndConcat) > 310 CALL_METHOD scala.Predef.println (dynamic) > 310 JUMP 2 -587c613 +597c623 < catch (Throwable) in ArrayBuffer(7, 8, 9, 10) starting at: 6 --- > catch (Throwable) in ArrayBuffer(7, 8, 9, 10, 11) starting at: 6 -590c616 +600c626 < catch (Throwable) in ArrayBuffer(4, 6, 7, 8, 9, 10) starting at: 3 --- > catch (Throwable) in ArrayBuffer(4, 6, 7, 8, 9, 10, 11, 12) starting at: 3 -622c648 +632c658 < blocks: [1,2,3,4,5,6,7,9,10] --- > blocks: [1,2,3,4,5,6,7,9,10,11,12] -646c672,673 +656c682,683 < 78 THROW(IllegalArgumentException) --- > ? STORE_LOCAL(value e) > ? JUMP 11 -647a675,679 +657a685,689 > 11: > 81 LOAD_LOCAL(value e) > ? STORE_LOCAL(variable exc1) > ? JUMP 12 > -675c707,721 +685c717,731 < 81 THROW(Exception) --- > ? STORE_LOCAL(variable exc1) @@ -119,15 +119,15 @@ > 84 STORE_LOCAL(variable result) > 84 LOAD_LOCAL(variable exc1) > 84 THROW(Throwable) -697c743 +707c753 < catch (<none>) in ArrayBuffer(4, 6, 7, 9) starting at: 3 --- > catch (<none>) in ArrayBuffer(4, 6, 7, 9, 11) starting at: 3 -723c769 +733c779 < blocks: [1,2,3,4,5,6,9,12,14,17,18,19,22,25,27,28,30,31] --- > blocks: [1,2,3,4,5,6,9,12,14,17,18,19,22,25,27,28,30,31,32,33,34] -747c793,800 +757c803,810 < 172 THROW(MyException) --- > ? STORE_LOCAL(value ex5) @@ -138,12 +138,12 @@ > 170 STORE_LOCAL(value x3) > 170 SCOPE_ENTER value x3 > 170 JUMP 18 -803c856,857 +813c866,867 < 177 THROW(MyException) --- > ? STORE_LOCAL(value ex5) > ? JUMP 33 -807c861,868 +817c871,878 < 170 THROW(Throwable) --- > ? STORE_LOCAL(value ex5) @@ -154,17 +154,17 @@ > 169 STORE_LOCAL(value x3) > 169 SCOPE_ENTER value x3 > 169 JUMP 5 -840c901,902 +850c911,912 < 182 THROW(MyException) --- > ? STORE_LOCAL(variable exc2) > ? JUMP 34 -844c906,907 +854c916,917 < 169 THROW(Throwable) --- > ? STORE_LOCAL(variable exc2) > ? JUMP 34 -845a909,921 +855a919,931 > 34: > 184 LOAD_MODULE object Predef > 184 CONSTANT("finally") @@ -178,19 +178,19 @@ > 185 LOAD_LOCAL(variable exc2) > 185 THROW(Throwable) > -866c942 +876c952 < catch (Throwable) in ArrayBuffer(17, 18, 19, 22, 25, 27, 28, 30) starting at: 4 --- > catch (Throwable) in ArrayBuffer(17, 18, 19, 22, 25, 27, 28, 30, 32) starting at: 4 -869c945 +879c955 < catch (<none>) in ArrayBuffer(4, 5, 6, 9, 12, 17, 18, 19, 22, 25, 27, 28, 30) starting at: 3 --- > catch (<none>) in ArrayBuffer(4, 5, 6, 9, 12, 17, 18, 19, 22, 25, 27, 28, 30, 32, 33) starting at: 3 -895c971 +905c981 < blocks: [1,2,3,6,7,8,11,14,16,17,19] --- > blocks: [1,2,3,6,7,8,11,14,16,17,19,20] -919c995,1002 +929c1005,1012 < 124 THROW(MyException) --- > ? STORE_LOCAL(value ex5) @@ -201,15 +201,15 @@ > 122 STORE_LOCAL(value x3) > 122 SCOPE_ENTER value x3 > 122 JUMP 7 -979c1062 +989c1072 < catch (IllegalArgumentException) in ArrayBuffer(6, 7, 8, 11, 14, 16, 17, 19) starting at: 3 --- > catch (IllegalArgumentException) in ArrayBuffer(6, 7, 8, 11, 14, 16, 17, 19, 20) starting at: 3 -1005c1088 +1015c1098 < blocks: [1,2,3,4,5,8,11,15,16,17,19] --- > blocks: [1,2,3,5,8,11,15,16,17,19,20] -1029c1112,1121 +1039c1122,1131 < 148 THROW(MyException) --- > ? STORE_LOCAL(value ex5) @@ -222,15 +222,15 @@ > 154 LOAD_LOCAL(value x3) > 154 IS_INSTANCE REF(class MyException) > 154 CZJUMP (BOOL)NE ? 5 : 11 -1050,1052d1141 +1060,1062d1151 < 145 JUMP 4 < < 4: -1285c1374 +1295c1384 < blocks: [1,2,3,4,5,7] --- > blocks: [1,2,3,4,5,7,8] -1309c1398,1405 +1319c1408,1415 < 38 THROW(IllegalArgumentException) --- > ? STORE_LOCAL(value e) @@ -241,16 +241,16 @@ > 42 CONSTANT("IllegalArgumentException") > 42 CALL_METHOD scala.Predef.println (dynamic) > 42 JUMP 2 -1358c1454 +1368c1464 < blocks: [1,2,3,4,5,8,11,13,14,16,17,19] --- > blocks: [1,2,3,5,8,11,13,14,16,17,19,20] -1382c1478,1479 +1392c1488,1489 < 203 THROW(MyException) --- > ? STORE_LOCAL(value ex5) > ? JUMP 20 -1402c1499,1508 +1412c1509,1518 < 209 THROW(MyException) --- > ? STORE_LOCAL(value ex5) @@ -263,15 +263,15 @@ > 212 LOAD_LOCAL(value x3) > 212 IS_INSTANCE REF(class MyException) > 212 CZJUMP (BOOL)NE ? 5 : 11 -1415,1417d1520 +1425,1427d1530 < 200 JUMP 4 < < 4: -1477c1580 +1487c1590 < blocks: [1,2,3,4,5,7] --- > blocks: [1,2,3,4,5,7,8] -1501c1604,1611 +1511c1614,1621 < 58 THROW(IllegalArgumentException) --- > ? STORE_LOCAL(value e) @@ -282,11 +282,11 @@ > 62 CONSTANT("RuntimeException") > 62 CALL_METHOD scala.Predef.println (dynamic) > 62 JUMP 2 -1550c1660 +1560c1670 < blocks: [1,2,3,4] --- > blocks: [1,2,3,4,5] -1570c1680,1685 +1580c1690,1695 < 229 THROW(MyException) --- > ? JUMP 5 @@ -295,19 +295,19 @@ > ? LOAD_LOCAL(variable monitor1) > 228 MONITOR_EXIT > 228 THROW(Throwable) -1576c1691 +1586c1701 < ? THROW(Throwable) --- > 228 THROW(Throwable) -1604c1719 +1614c1729 < locals: value args, variable result, variable monitor2, variable monitorResult1 --- > locals: value exception$1, value args, variable result, variable monitor2, variable monitorResult1 -1606c1721 +1616c1731 < blocks: [1,2,3,4] --- > blocks: [1,2,3,4,5] -1629c1744,1752 +1639c1754,1762 < 245 THROW(MyException) --- > ? STORE_LOCAL(value exception$1) @@ -319,7 +319,7 @@ > ? LOAD_LOCAL(variable monitor2) > 244 MONITOR_EXIT > 244 THROW(Throwable) -1635c1758 +1645c1768 < ? THROW(Throwable) --- > 244 THROW(Throwable) diff --git a/test/files/run/t2296c.check b/test/files/run/t2296c.check new file mode 100644 index 0000000000..076e9180a8 --- /dev/null +++ b/test/files/run/t2296c.check @@ -0,0 +1 @@ +RUNNING ACTION diff --git a/test/files/run/t2296c/Action.java b/test/files/run/t2296c/Action.java new file mode 100644 index 0000000000..50ba9a4de1 --- /dev/null +++ b/test/files/run/t2296c/Action.java @@ -0,0 +1,21 @@ +package bug.action; + +import bug.Global; + +public abstract class Action { + protected Global m_glob; + + public Action(Global glob0) { + m_glob = glob0; + } + + public Action() { + this(null); + } + + public abstract void run(int v); + + public void setGlobal(Global g) { + m_glob = g; + } +} diff --git a/test/files/run/t2296c/Display.java b/test/files/run/t2296c/Display.java new file mode 100644 index 0000000000..7f7e6a73d0 --- /dev/null +++ b/test/files/run/t2296c/Display.java @@ -0,0 +1,9 @@ +package bug; + +public class Display { + protected Global m_glob; + + public void start() { + m_glob.runActions(); + } +} diff --git a/test/files/run/t2296c/Global.java b/test/files/run/t2296c/Global.java new file mode 100644 index 0000000000..7e5a762de2 --- /dev/null +++ b/test/files/run/t2296c/Global.java @@ -0,0 +1,29 @@ +package bug; + +import bug.action.Action; +import java.util.List; +import java.util.LinkedList; + +public class Global { + public int items() { + return 0; + } + + public int items(int i) { + return i + ls.size(); + } + + private List<Action> ls = new LinkedList<Action>(); + + public void putAction(Action a) { + a.setGlobal(this); + ls.add(a); + } + + public void runActions() { + for (Action action: ls) { + System.out.println("RUNNING ACTION"); + action.run(0); + } + } +} diff --git a/test/files/run/t2296c/ScalaActivity.scala b/test/files/run/t2296c/ScalaActivity.scala new file mode 100644 index 0000000000..aa7648a944 --- /dev/null +++ b/test/files/run/t2296c/ScalaActivity.scala @@ -0,0 +1,18 @@ +package test + +import bug.Display +import bug.action.Action + +abstract class Outer extends Display { + + def init() { + m_glob.putAction(ScalaActivity) + } + + object ScalaActivity extends Action { + def run(v: Int) { + val testSet = List(1,2,3) + testSet.map(p => m_glob.items(p)) // crash with illegal access + } + } +} diff --git a/test/files/run/t2296c/Test.scala b/test/files/run/t2296c/Test.scala new file mode 100644 index 0000000000..1132bebebb --- /dev/null +++ b/test/files/run/t2296c/Test.scala @@ -0,0 +1,15 @@ +package test + +import bug.Global + +object Test { + def main(args: Array[String]) { + val m = new Main() + m.init() + m.start() + } +} + +class Main extends Outer { + m_glob = new Global() +} diff --git a/test/files/run/t2296c/a.scala b/test/files/run/t2296c/a.scala new file mode 100644 index 0000000000..fae32f4ec4 --- /dev/null +++ b/test/files/run/t2296c/a.scala @@ -0,0 +1,5 @@ +object Test { + def main(args: Array[String]): Unit = { + test.Test main args + } +} diff --git a/test/files/run/t5201.check b/test/files/run/t5201.check new file mode 100644 index 0000000000..27ba77ddaf --- /dev/null +++ b/test/files/run/t5201.check @@ -0,0 +1 @@ +true diff --git a/test/files/run/t5201.scala b/test/files/run/t5201.scala new file mode 100644 index 0000000000..48aa7ba54c --- /dev/null +++ b/test/files/run/t5201.scala @@ -0,0 +1,8 @@ +object Test extends App { + // First make sure specific types are preserved + val tmp: Vector[Int] = Vector(Vector(1,2), Vector(3,4)).view.flatten.force + + // Now make sure we really get a view + val seq = Seq(Seq(1, 2), Seq(3, 4)).view.flatten + Console.println(seq.isInstanceOf[collection.SeqView[_,_]]) +} diff --git a/test/files/run/t5328.check b/test/files/run/t5328.check new file mode 100644 index 0000000000..77a43968c5 --- /dev/null +++ b/test/files/run/t5328.check @@ -0,0 +1,3 @@ +2 +1,2,8 +1,8,3 diff --git a/test/files/run/t5328.scala b/test/files/run/t5328.scala new file mode 100644 index 0000000000..12adf45b84 --- /dev/null +++ b/test/files/run/t5328.scala @@ -0,0 +1,5 @@ +object Test extends App { + println(Vector(1).view.updated(0,2).toList mkString ",") + println(Seq(1,2,3).view.updated(2,8).toList mkString ",") + println(List(1,2,3).view.updated(1,8).toList mkString ",") +} diff --git a/test/pending/pos/z1720.scala b/test/pending/pos/z1720.scala new file mode 100644 index 0000000000..6050f3ff88 --- /dev/null +++ b/test/pending/pos/z1720.scala @@ -0,0 +1,16 @@ +package test + +class Thing { + def info: Info[this.type] = InfoRepository.getInfo(this) + def info2: Info[this.type] = { + def self: this.type = this + InfoRepository.getInfo(self) + } +} + +trait Info[T] +case class InfoImpl[T](thing: T) extends Info[T] + +object InfoRepository { + def getInfo(t: Thing): Info[t.type] = InfoImpl(t) +}
\ No newline at end of file |