diff options
-rw-r--r-- | src/compiler/scala/reflect/reify/Errors.scala | 5 | ||||
-rw-r--r-- | src/compiler/scala/reflect/reify/phases/Reshape.scala | 1 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala | 23 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 2 | ||||
-rw-r--r-- | src/reflect/scala/reflect/internal/Types.scala | 6 | ||||
-rw-r--r-- | test/files/neg/t7235.check | 4 | ||||
-rw-r--r-- | test/files/neg/t7235.scala | 14 | ||||
-rw-r--r-- | test/files/neg/t7238.check | 6 | ||||
-rw-r--r-- | test/files/neg/t7238.scala | 7 | ||||
-rw-r--r-- | test/files/pos/t7226.scala | 26 | ||||
-rw-r--r-- | test/files/pos/t7234.scala | 15 | ||||
-rw-r--r-- | test/files/pos/t7234b.scala | 20 | ||||
-rw-r--r-- | test/files/presentation/hyperlinks.check | 137 | ||||
-rw-r--r-- | test/files/presentation/hyperlinks/src/SuperTypes.scala | 32 | ||||
-rw-r--r-- | test/files/run/t5710-1.check | 1 | ||||
-rw-r--r-- | test/files/run/t5710-1.scala | 15 | ||||
-rw-r--r-- | test/files/run/t5710-2.check | 1 | ||||
-rw-r--r-- | test/files/run/t5710-2.scala | 15 | ||||
-rw-r--r-- | test/files/run/t7235.check | 4 | ||||
-rw-r--r-- | test/files/run/t7235.scala | 14 |
20 files changed, 336 insertions, 12 deletions
diff --git a/src/compiler/scala/reflect/reify/Errors.scala b/src/compiler/scala/reflect/reify/Errors.scala index 3a68794c97..860dfd72b2 100644 --- a/src/compiler/scala/reflect/reify/Errors.scala +++ b/src/compiler/scala/reflect/reify/Errors.scala @@ -21,6 +21,11 @@ trait Errors { throw new ReificationException(defaultErrorPosition, msg) } + def CannotReifyCompoundTypeTreeWithNonEmptyBody(ctt: CompoundTypeTree) = { + val msg = "implementation restriction: cannot reify refinement type trees with non-empty bodies" + throw new ReificationException(ctt.pos, msg) + } + def CannotReifyWeakType(details: Any) = { val msg = "cannot create a TypeTag" + details + ": use WeakTypeTag instead" throw new ReificationException(defaultErrorPosition, msg) diff --git a/src/compiler/scala/reflect/reify/phases/Reshape.scala b/src/compiler/scala/reflect/reify/phases/Reshape.scala index 50ee379c2e..bb5cb53d7d 100644 --- a/src/compiler/scala/reflect/reify/phases/Reshape.scala +++ b/src/compiler/scala/reflect/reify/phases/Reshape.scala @@ -180,6 +180,7 @@ trait Reshape { private def toPreTyperCompoundTypeTree(ctt: CompoundTypeTree): Tree = { val CompoundTypeTree(tmpl @ Template(parents, self, stats)) = ctt + if (stats.nonEmpty) CannotReifyCompoundTypeTreeWithNonEmptyBody(ctt) assert(self eq emptyValDef, self) val att = tmpl.attachments.get[CompoundTypeTreeOriginalAttachment] val CompoundTypeTreeOriginalAttachment(parents1, stats1) = att.getOrElse(CompoundTypeTreeOriginalAttachment(parents, stats)) diff --git a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala index fa141e95e1..ce8e0ed37b 100644 --- a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala +++ b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala @@ -270,22 +270,25 @@ trait NamesDefaults { self: Analyzer => */ def argValDefs(args: List[Tree], paramTypes: List[Type], blockTyper: Typer): List[Option[ValDef]] = { val context = blockTyper.context - val symPs = map2(args, paramTypes)((arg, tpe) => arg match { + val symPs = map2(args, paramTypes)((arg, paramTpe) => arg match { case Ident(nme.SELECTOR_DUMMY) => None // don't create a local ValDef if the argument is <unapply-selector> case _ => - val byName = isByNameParamType(tpe) - val repeated = isScalaRepeatedParamType(tpe) + val byName = isByNameParamType(paramTpe) + val repeated = isScalaRepeatedParamType(paramTpe) val argTpe = ( if (repeated) arg match { case Typed(expr, Ident(tpnme.WILDCARD_STAR)) => expr.tpe case _ => seqType(arg.tpe) } - else arg.tpe - ).widen // have to widen or types inferred from literal defaults will be singletons + else + // Note stabilizing can lead to a non-conformant argument when existentials are involved, e.g. neg/t3507-old.scala, hence the filter. + gen.stableTypeFor(arg).filter(_ <:< paramTpe).getOrElse(arg.tpe) + // We have to deconst or types inferred from literal arguments will be Constant(_), e.g. pos/z1730.scala. + ).deconst val s = context.owner.newValue(unit.freshTermName("x$"), arg.pos, newFlags = ARTIFACT) setInfo ( - if (byName) functionType(Nil, argTpe) else argTpe - ) + if (byName) functionType(Nil, argTpe) else argTpe + ) Some((context.scope.enter(s), byName, repeated)) }) map2(symPs, args) { @@ -326,11 +329,10 @@ trait NamesDefaults { self: Analyzer => // type the application without names; put the arguments in definition-site order val typedApp = doTypedApply(tree, funOnly, reorderArgs(namelessArgs, argPos), mode, pt) - if (typedApp.isErrorTyped) tree - else typedApp match { + typedApp match { // Extract the typed arguments, restore the call-site evaluation order (using // ValDef's in the block), change the arguments to these local values. - case Apply(expr, typedArgs) => + case Apply(expr, typedArgs) if !(typedApp :: typedArgs).exists(_.isErrorTyped) => // bail out with erroneous args, see SI-7238 // typedArgs: definition-site order val formals = formalTypes(expr.tpe.paramTypes, typedArgs.length, removeByName = false, removeRepeated = false) // valDefs: call-site order @@ -358,6 +360,7 @@ trait NamesDefaults { self: Analyzer => context.namedApplyBlockInfo = Some((block, NamedApplyInfo(qual, targs, vargss :+ refArgs, blockTyper))) block + case _ => tree } } diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index eaf57cd39c..92f53f4956 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -1535,7 +1535,7 @@ trait Typers extends Adaptations with Tags { atPos(supertpt.pos.focus)(supercall) } match { case EmptyTree => MissingTypeArgumentsParentTpeError(supertpt) - case tpt => supertpt = TypeTree(tpt.tpe) setPos supertpt.pos.focus + case tpt => supertpt = TypeTree(tpt.tpe) setPos supertpt.pos // SI-7224: don't .focus positions of the TypeTree of a parent that exists in source } } // this is the place where we tell the typer what argss should be used for the super call diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala index a6c5367425..e1433d1893 100644 --- a/src/reflect/scala/reflect/internal/Types.scala +++ b/src/reflect/scala/reflect/internal/Types.scala @@ -2958,6 +2958,12 @@ trait Types origin: Type, var constr: TypeConstraint ) extends Type { + + // We don't want case class equality/hashing as TypeVar-s are mutable, + // and TypeRefs based on them get wrongly `uniqued` otherwise. See SI-7226. + override def hashCode(): Int = System.identityHashCode(this) + override def equals(other: Any): Boolean = this eq other.asInstanceOf[AnyRef] + def untouchable = false // by other typevars override def params: List[Symbol] = Nil override def typeArgs: List[Type] = Nil diff --git a/test/files/neg/t7235.check b/test/files/neg/t7235.check new file mode 100644 index 0000000000..357a3dfd83 --- /dev/null +++ b/test/files/neg/t7235.check @@ -0,0 +1,4 @@ +t7235.scala:9: error: implementation restriction: cannot reify refinement type trees with non-empty bodies + val Block(List(ValDef(_, _, tpt: CompoundTypeTree, _)), _) = reify{ val x: C { def x: Int } = ??? }.tree + ^ +one error found diff --git a/test/files/neg/t7235.scala b/test/files/neg/t7235.scala new file mode 100644 index 0000000000..cfebad3fae --- /dev/null +++ b/test/files/neg/t7235.scala @@ -0,0 +1,14 @@ +import scala.reflect.runtime.universe._ +import scala.reflect.runtime.{universe => ru} +import scala.reflect.runtime.{currentMirror => cm} +import scala.tools.reflect.ToolBox + +class C + +object Test extends App { + val Block(List(ValDef(_, _, tpt: CompoundTypeTree, _)), _) = reify{ val x: C { def x: Int } = ??? }.tree + println(tpt) + println(tpt.templ.parents) + println(tpt.templ.self) + println(tpt.templ.body) +} diff --git a/test/files/neg/t7238.check b/test/files/neg/t7238.check new file mode 100644 index 0000000000..b87f83ff65 --- /dev/null +++ b/test/files/neg/t7238.check @@ -0,0 +1,6 @@ +t7238.scala:6: error: type mismatch; + found : Seq[Any] + required: Seq[String] + c.c()(Seq[Any](): _*) + ^ +one error found diff --git a/test/files/neg/t7238.scala b/test/files/neg/t7238.scala new file mode 100644 index 0000000000..d42dc8d385 --- /dev/null +++ b/test/files/neg/t7238.scala @@ -0,0 +1,7 @@ +trait Main { + trait C { + def c(x: Any = 0)(bs: String*) + } + def c: C + c.c()(Seq[Any](): _*) +} diff --git a/test/files/pos/t7226.scala b/test/files/pos/t7226.scala new file mode 100644 index 0000000000..06f0c95dc4 --- /dev/null +++ b/test/files/pos/t7226.scala @@ -0,0 +1,26 @@ +trait HK { + type Rep[X] + + // okay + def unzip2[A, B](ps: Rep[List[(A, B)]]) + unzip2(null.asInstanceOf[Rep[List[(Int, String)]]]) + + // okay + def unzipHK[A, B, C[_]](ps: Rep[C[(A, B)]]) + unzipHK(null.asInstanceOf[Rep[List[(Int, String)]]]) + + def unzipHKRet0[A, C[_]](ps: C[A]): C[Int] + def ls: List[String] + unzipHKRet0(ls) + + // fail + def unzipHKRet[A, C[_]](ps: Rep[C[A]]): Rep[C[Int]] + def rls: Rep[List[String]] + unzipHKRet(rls) +} + +trait HK1 { + type Rep[A] + def unzip1[A, B, C[_]](ps: Rep[C[(A, B)]]): (Rep[C[A]], Rep[C[B]]) + def doUnzip1[A, B](ps: Rep[List[(A, B)]]) = unzip1(ps) +} diff --git a/test/files/pos/t7234.scala b/test/files/pos/t7234.scala new file mode 100644 index 0000000000..59a233d835 --- /dev/null +++ b/test/files/pos/t7234.scala @@ -0,0 +1,15 @@ +trait Main { + trait A { + type B + } + trait C { + def c(a: A, x: Int = 0)(b: a.B) + } + def c: C + def d(a: A, x: Int = 0)(b: a.B) + + def ok1(a: A)(b: a.B) = c.c(a, 42)(b) + def ok2(a: A)(b: a.B) = d(a)(b) + + def fail(a: A)(b: a.B) = c.c(a)(b) +} diff --git a/test/files/pos/t7234b.scala b/test/files/pos/t7234b.scala new file mode 100644 index 0000000000..fee98e87a8 --- /dev/null +++ b/test/files/pos/t7234b.scala @@ -0,0 +1,20 @@ +trait Main { + trait A { + type B + def b: B + } + trait C { + def c(a: A, x: Int = 0)(b: => a.B, bs: a.B*) + def d(a: A = null, x: Int = 0)(b1: => a.B = a.b, b2: a.B = a.b) + } + def c: C + def ok(a: A)(b: a.B) = c.c(a, 42)(b) + def fail(a: A)(b: a.B) = c.c(a)(b) + def fail2(a: A)(b: a.B) = c.c(a)(b, b) + def fail3(a: A)(b: a.B) = c.c(a)(b, Seq[a.B](b): _*) + + def fail4(a: A)(b: a.B) = c.d(a)() + def fail5(a: A)(b: a.B) = c.d(a)(b1 = a.b) + def fail6(a: A)(b: a.B) = c.d(a)(b2 = a.b) + def fail7(a: A)(b: a.B) = c.d()() +} diff --git a/test/files/presentation/hyperlinks.check b/test/files/presentation/hyperlinks.check index 85d295dd7d..1051b67e85 100644 --- a/test/files/presentation/hyperlinks.check +++ b/test/files/presentation/hyperlinks.check @@ -1,4 +1,4 @@ -reload: NameDefaultTests.scala, PatMatTests.scala +reload: NameDefaultTests.scala, PatMatTests.scala, SuperTypes.scala askHyperlinkPos for `someOtherInt` at (14,24) NameDefaultTests.scala ================================================================================ @@ -44,3 +44,138 @@ askHyperlinkPos for `y` at (25,21) PatMatTests.scala ================================================================================ [response] found askHyperlinkPos for `y` at (23,13) PatMatTests.scala ================================================================================ + +askHyperlinkPos for `BadPos` at (10,26) SuperTypes.scala +================================================================================ +[response] found askHyperlinkPos for `BadPos` at (2,7) SuperTypes.scala +================================================================================ + +askHyperlinkPos for `BadPos` at (11,26) SuperTypes.scala +================================================================================ +[response] found askHyperlinkPos for `BadPos` at (2,7) SuperTypes.scala +================================================================================ + +askHyperlinkPos for `Trait` at (12,25) SuperTypes.scala +================================================================================ +[response] found askHyperlinkPos for `Trait` at (6,7) SuperTypes.scala +================================================================================ + +askHyperlinkPos for `SubTrait` at (13,28) SuperTypes.scala +================================================================================ +[response] found askHyperlinkPos for `SubTrait` at (7,7) SuperTypes.scala +================================================================================ + +askHyperlinkPos for `Trait` at (14,25) SuperTypes.scala +================================================================================ +[response] found askHyperlinkPos for `Trait` at (6,7) SuperTypes.scala +================================================================================ + +askHyperlinkPos for `LateralTrait` at (14,48) SuperTypes.scala +================================================================================ +[response] found askHyperlinkPos for `LateralTrait` at (8,7) SuperTypes.scala +================================================================================ + +askHyperlinkPos for `Base` at (15,24) SuperTypes.scala +================================================================================ +[response] found askHyperlinkPos for `Base` at (4,7) SuperTypes.scala +================================================================================ + +askHyperlinkPos for `Trait` at (15,40) SuperTypes.scala +================================================================================ +[response] found askHyperlinkPos for `Trait` at (6,7) SuperTypes.scala +================================================================================ + +askHyperlinkPos for `LateralTrait` at (15,63) SuperTypes.scala +================================================================================ +[response] found askHyperlinkPos for `LateralTrait` at (8,7) SuperTypes.scala +================================================================================ + +askHyperlinkPos for `PBase` at (19,29) SuperTypes.scala +================================================================================ +[response] found askHyperlinkPos for `PBase` at (17,7) SuperTypes.scala +================================================================================ + +askHyperlinkPos for `PTrait` at (20,33) SuperTypes.scala +================================================================================ +[response] found askHyperlinkPos for `PTrait` at (19,7) SuperTypes.scala +================================================================================ + +askHyperlinkPos for `PBase` at (21,36) SuperTypes.scala +================================================================================ +[response] found askHyperlinkPos for `PBase` at (17,7) SuperTypes.scala +================================================================================ + +askHyperlinkPos for `PTrait` at (23,27) SuperTypes.scala +================================================================================ +[response] found askHyperlinkPos for `PTrait` at (19,7) SuperTypes.scala +================================================================================ + +askHyperlinkPos for `PSubTrait` at (24,30) SuperTypes.scala +================================================================================ +[response] found askHyperlinkPos for `PSubTrait` at (20,7) SuperTypes.scala +================================================================================ + +askHyperlinkPos for `PTrait` at (25,27) SuperTypes.scala +================================================================================ +[response] found askHyperlinkPos for `PTrait` at (19,7) SuperTypes.scala +================================================================================ + +askHyperlinkPos for `PLateralTrait` at (25,56) SuperTypes.scala +================================================================================ +[response] found askHyperlinkPos for `PLateralTrait` at (21,7) SuperTypes.scala +================================================================================ + +askHyperlinkPos for `PBase` at (26,26) SuperTypes.scala +================================================================================ +[response] found askHyperlinkPos for `PBase` at (17,7) SuperTypes.scala +================================================================================ + +askHyperlinkPos for `PTrait` at (26,48) SuperTypes.scala +================================================================================ +[response] found askHyperlinkPos for `PTrait` at (19,7) SuperTypes.scala +================================================================================ + +askHyperlinkPos for `PLateralTrait` at (26,77) SuperTypes.scala +================================================================================ +[response] found askHyperlinkPos for `PLateralTrait` at (21,7) SuperTypes.scala +================================================================================ + +askHyperlinkPos for `BadPos` at (28,23) SuperTypes.scala +================================================================================ +[response] found askHyperlinkPos for `BadPos` at (2,7) SuperTypes.scala +================================================================================ + +askHyperlinkPos for `PTrait` at (29,23) SuperTypes.scala +================================================================================ +[response] found askHyperlinkPos for `PTrait` at (19,7) SuperTypes.scala +================================================================================ + +askHyperlinkPos for `PSubTrait` at (30,26) SuperTypes.scala +================================================================================ +[response] found askHyperlinkPos for `PSubTrait` at (20,7) SuperTypes.scala +================================================================================ + +askHyperlinkPos for `PTrait` at (31,23) SuperTypes.scala +================================================================================ +[response] found askHyperlinkPos for `PTrait` at (19,7) SuperTypes.scala +================================================================================ + +askHyperlinkPos for `PLateralTrait` at (31,52) SuperTypes.scala +================================================================================ +[response] found askHyperlinkPos for `PLateralTrait` at (21,7) SuperTypes.scala +================================================================================ + +askHyperlinkPos for `PBase` at (32,22) SuperTypes.scala +================================================================================ +[response] found askHyperlinkPos for `PBase` at (17,7) SuperTypes.scala +================================================================================ + +askHyperlinkPos for `PTrait` at (32,44) SuperTypes.scala +================================================================================ +[response] found askHyperlinkPos for `PTrait` at (19,7) SuperTypes.scala +================================================================================ + +askHyperlinkPos for `PLateralTrait` at (32,73) SuperTypes.scala +================================================================================ +[response] found askHyperlinkPos for `PLateralTrait` at (21,7) SuperTypes.scala +================================================================================ diff --git a/test/files/presentation/hyperlinks/src/SuperTypes.scala b/test/files/presentation/hyperlinks/src/SuperTypes.scala new file mode 100644 index 0000000000..15d16069fd --- /dev/null +++ b/test/files/presentation/hyperlinks/src/SuperTypes.scala @@ -0,0 +1,32 @@ +/** This tests that hyperlinking works for super types. See SI-7224 */ +class BadPos[A](a: A) + +class Base + +trait Trait extends Base +trait SubTrait extends Trait +trait LateralTrait extends Base + +object obj1 extends BadPos/*#*/(new Object) +object obj2 extends BadPos/*#*/[AnyRef](new Object) +object obj3 extends Trait/*#*/ +object obj4 extends SubTrait/*#*/ +object obj5 extends Trait/*#*/ with LateralTrait/*#*/ +object obj6 extends Base/*#*/ with Trait/*#*/ with LateralTrait/*#*/ + +class PBase[A] + +trait PTrait[A] extends PBase/*#*/[A] +trait PSubTrait[A] extends PTrait/*#*/[A] +trait PLateralTrait[A] extends PBase/*#*/[A] + +object pobj2 extends PTrait/*#*/[Int] +object pobj3 extends PSubTrait/*#*/[Int] +object pobj4 extends PTrait/*#*/[Int] with PLateralTrait/*#*/[Int] +object pobj5 extends PBase/*#*/[Int] with PTrait/*#*/[Int] with PLateralTrait/*#*/[Int] + +class c1 extends BadPos/*#*/(new Object) +class c2 extends PTrait/*#*/[Int] +class c3 extends PSubTrait/*#*/[Int] +class c4 extends PTrait/*#*/[Int] with PLateralTrait/*#*/[Int] +class c5 extends PBase/*#*/[Int] with PTrait/*#*/[Int] with PLateralTrait/*#*/[Int] diff --git a/test/files/run/t5710-1.check b/test/files/run/t5710-1.check new file mode 100644 index 0000000000..eac2025aeb --- /dev/null +++ b/test/files/run/t5710-1.check @@ -0,0 +1 @@ +evaluated = (abc,abc) diff --git a/test/files/run/t5710-1.scala b/test/files/run/t5710-1.scala new file mode 100644 index 0000000000..12bd858e06 --- /dev/null +++ b/test/files/run/t5710-1.scala @@ -0,0 +1,15 @@ +import scala.reflect.runtime.universe._ +import scala.reflect.runtime.{universe => ru} +import scala.reflect.runtime.{currentMirror => cm} +import scala.tools.reflect.ToolBox + +object Test extends App { + val code = reify { + val (x, y) = ("abc": Any) match { case x => (x, x) } + (x, y) + }; + + val toolbox = cm.mkToolBox() + val evaluated = toolbox.eval(code.tree) + println("evaluated = " + evaluated) +}
\ No newline at end of file diff --git a/test/files/run/t5710-2.check b/test/files/run/t5710-2.check new file mode 100644 index 0000000000..eac2025aeb --- /dev/null +++ b/test/files/run/t5710-2.check @@ -0,0 +1 @@ +evaluated = (abc,abc) diff --git a/test/files/run/t5710-2.scala b/test/files/run/t5710-2.scala new file mode 100644 index 0000000000..6d2129cca2 --- /dev/null +++ b/test/files/run/t5710-2.scala @@ -0,0 +1,15 @@ +import scala.reflect.runtime.universe._ +import scala.reflect.runtime.{universe => ru} +import scala.reflect.runtime.{currentMirror => cm} +import scala.tools.reflect.ToolBox + +object Test extends App { + val code = reify { + val (x, y) = "abc" match { case x => (x, x) } + (x, y) + }; + + val toolbox = cm.mkToolBox() + val evaluated = toolbox.eval(code.tree) + println("evaluated = " + evaluated) +}
\ No newline at end of file diff --git a/test/files/run/t7235.check b/test/files/run/t7235.check new file mode 100644 index 0000000000..9cb9c55a0c --- /dev/null +++ b/test/files/run/t7235.check @@ -0,0 +1,4 @@ +C +List(C) +private val _ = _ +List() diff --git a/test/files/run/t7235.scala b/test/files/run/t7235.scala new file mode 100644 index 0000000000..6039189716 --- /dev/null +++ b/test/files/run/t7235.scala @@ -0,0 +1,14 @@ +import scala.reflect.runtime.universe._ +import scala.reflect.runtime.{universe => ru} +import scala.reflect.runtime.{currentMirror => cm} +import scala.tools.reflect.ToolBox + +class C + +object Test extends App { + val Block(List(ValDef(_, _, tpt: CompoundTypeTree, _)), _) = reify{ val x: C{} = ??? }.tree + println(tpt) + println(tpt.templ.parents) + println(tpt.templ.self) + println(tpt.templ.body) +} |