Skip to content

Commit 184e0cc

Browse files
committed
Merge pull request scala#2242 from adriaanm/merge-2.10.x
Merge 2.10.x into master
2 parents ac51ccd + 5f32459 commit 184e0cc

File tree

20 files changed

+336
-12
lines changed

20 files changed

+336
-12
lines changed

src/compiler/scala/reflect/reify/Errors.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@ trait Errors {
2121
throw new ReificationException(defaultErrorPosition, msg)
2222
}
2323

24+
def CannotReifyCompoundTypeTreeWithNonEmptyBody(ctt: CompoundTypeTree) = {
25+
val msg = "implementation restriction: cannot reify refinement type trees with non-empty bodies"
26+
throw new ReificationException(ctt.pos, msg)
27+
}
28+
2429
def CannotReifyWeakType(details: Any) = {
2530
val msg = "cannot create a TypeTag" + details + ": use WeakTypeTag instead"
2631
throw new ReificationException(defaultErrorPosition, msg)

src/compiler/scala/reflect/reify/phases/Reshape.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ trait Reshape {
180180

181181
private def toPreTyperCompoundTypeTree(ctt: CompoundTypeTree): Tree = {
182182
val CompoundTypeTree(tmpl @ Template(parents, self, stats)) = ctt
183+
if (stats.nonEmpty) CannotReifyCompoundTypeTreeWithNonEmptyBody(ctt)
183184
assert(self eq emptyValDef, self)
184185
val att = tmpl.attachments.get[CompoundTypeTreeOriginalAttachment]
185186
val CompoundTypeTreeOriginalAttachment(parents1, stats1) = att.getOrElse(CompoundTypeTreeOriginalAttachment(parents, stats))

src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -270,22 +270,25 @@ trait NamesDefaults { self: Analyzer =>
270270
*/
271271
def argValDefs(args: List[Tree], paramTypes: List[Type], blockTyper: Typer): List[Option[ValDef]] = {
272272
val context = blockTyper.context
273-
val symPs = map2(args, paramTypes)((arg, tpe) => arg match {
273+
val symPs = map2(args, paramTypes)((arg, paramTpe) => arg match {
274274
case Ident(nme.SELECTOR_DUMMY) =>
275275
None // don't create a local ValDef if the argument is <unapply-selector>
276276
case _ =>
277-
val byName = isByNameParamType(tpe)
278-
val repeated = isScalaRepeatedParamType(tpe)
277+
val byName = isByNameParamType(paramTpe)
278+
val repeated = isScalaRepeatedParamType(paramTpe)
279279
val argTpe = (
280280
if (repeated) arg match {
281281
case Typed(expr, Ident(tpnme.WILDCARD_STAR)) => expr.tpe
282282
case _ => seqType(arg.tpe)
283283
}
284-
else arg.tpe
285-
).widen // have to widen or types inferred from literal defaults will be singletons
284+
else
285+
// Note stabilizing can lead to a non-conformant argument when existentials are involved, e.g. neg/t3507-old.scala, hence the filter.
286+
gen.stableTypeFor(arg).filter(_ <:< paramTpe).getOrElse(arg.tpe)
287+
// We have to deconst or types inferred from literal arguments will be Constant(_), e.g. pos/z1730.scala.
288+
).deconst
286289
val s = context.owner.newValue(unit.freshTermName("x$"), arg.pos, newFlags = ARTIFACT) setInfo (
287-
if (byName) functionType(Nil, argTpe) else argTpe
288-
)
290+
if (byName) functionType(Nil, argTpe) else argTpe
291+
)
289292
Some((context.scope.enter(s), byName, repeated))
290293
})
291294
map2(symPs, args) {
@@ -326,11 +329,10 @@ trait NamesDefaults { self: Analyzer =>
326329

327330
// type the application without names; put the arguments in definition-site order
328331
val typedApp = doTypedApply(tree, funOnly, reorderArgs(namelessArgs, argPos), mode, pt)
329-
if (typedApp.isErrorTyped) tree
330-
else typedApp match {
332+
typedApp match {
331333
// Extract the typed arguments, restore the call-site evaluation order (using
332334
// ValDef's in the block), change the arguments to these local values.
333-
case Apply(expr, typedArgs) =>
335+
case Apply(expr, typedArgs) if !(typedApp :: typedArgs).exists(_.isErrorTyped) => // bail out with erroneous args, see SI-7238
334336
// typedArgs: definition-site order
335337
val formals = formalTypes(expr.tpe.paramTypes, typedArgs.length, removeByName = false, removeRepeated = false)
336338
// valDefs: call-site order
@@ -358,6 +360,7 @@ trait NamesDefaults { self: Analyzer =>
358360
context.namedApplyBlockInfo =
359361
Some((block, NamedApplyInfo(qual, targs, vargss :+ refArgs, blockTyper)))
360362
block
363+
case _ => tree
361364
}
362365
}
363366

src/compiler/scala/tools/nsc/typechecker/Typers.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1535,7 +1535,7 @@ trait Typers extends Adaptations with Tags {
15351535
atPos(supertpt.pos.focus)(supercall)
15361536
} match {
15371537
case EmptyTree => MissingTypeArgumentsParentTpeError(supertpt)
1538-
case tpt => supertpt = TypeTree(tpt.tpe) setPos supertpt.pos.focus
1538+
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
15391539
}
15401540
}
15411541
// this is the place where we tell the typer what argss should be used for the super call

src/reflect/scala/reflect/internal/Types.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2958,6 +2958,12 @@ trait Types
29582958
origin: Type,
29592959
var constr: TypeConstraint
29602960
) extends Type {
2961+
2962+
// We don't want case class equality/hashing as TypeVar-s are mutable,
2963+
// and TypeRefs based on them get wrongly `uniqued` otherwise. See SI-7226.
2964+
override def hashCode(): Int = System.identityHashCode(this)
2965+
override def equals(other: Any): Boolean = this eq other.asInstanceOf[AnyRef]
2966+
29612967
def untouchable = false // by other typevars
29622968
override def params: List[Symbol] = Nil
29632969
override def typeArgs: List[Type] = Nil

test/files/neg/t7235.check

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
t7235.scala:9: error: implementation restriction: cannot reify refinement type trees with non-empty bodies
2+
val Block(List(ValDef(_, _, tpt: CompoundTypeTree, _)), _) = reify{ val x: C { def x: Int } = ??? }.tree
3+
^
4+
one error found

test/files/neg/t7235.scala

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import scala.reflect.runtime.universe._
2+
import scala.reflect.runtime.{universe => ru}
3+
import scala.reflect.runtime.{currentMirror => cm}
4+
import scala.tools.reflect.ToolBox
5+
6+
class C
7+
8+
object Test extends App {
9+
val Block(List(ValDef(_, _, tpt: CompoundTypeTree, _)), _) = reify{ val x: C { def x: Int } = ??? }.tree
10+
println(tpt)
11+
println(tpt.templ.parents)
12+
println(tpt.templ.self)
13+
println(tpt.templ.body)
14+
}

test/files/neg/t7238.check

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
t7238.scala:6: error: type mismatch;
2+
found : Seq[Any]
3+
required: Seq[String]
4+
c.c()(Seq[Any](): _*)
5+
^
6+
one error found

test/files/neg/t7238.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
trait Main {
2+
trait C {
3+
def c(x: Any = 0)(bs: String*)
4+
}
5+
def c: C
6+
c.c()(Seq[Any](): _*)
7+
}

test/files/pos/t7226.scala

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
trait HK {
2+
type Rep[X]
3+
4+
// okay
5+
def unzip2[A, B](ps: Rep[List[(A, B)]])
6+
unzip2(null.asInstanceOf[Rep[List[(Int, String)]]])
7+
8+
// okay
9+
def unzipHK[A, B, C[_]](ps: Rep[C[(A, B)]])
10+
unzipHK(null.asInstanceOf[Rep[List[(Int, String)]]])
11+
12+
def unzipHKRet0[A, C[_]](ps: C[A]): C[Int]
13+
def ls: List[String]
14+
unzipHKRet0(ls)
15+
16+
// fail
17+
def unzipHKRet[A, C[_]](ps: Rep[C[A]]): Rep[C[Int]]
18+
def rls: Rep[List[String]]
19+
unzipHKRet(rls)
20+
}
21+
22+
trait HK1 {
23+
type Rep[A]
24+
def unzip1[A, B, C[_]](ps: Rep[C[(A, B)]]): (Rep[C[A]], Rep[C[B]])
25+
def doUnzip1[A, B](ps: Rep[List[(A, B)]]) = unzip1(ps)
26+
}

0 commit comments

Comments
 (0)