Skip to content

Commit 0cffdf3

Browse files
author
Adriaan Moors
committed
SI-5189 1/2: inferConstrInst uses correct variance
fixed concurrent.impl.Promise by making FState invariant (it would be unsound to make it covariant)
1 parent b908232 commit 0cffdf3

File tree

4 files changed

+20
-3
lines changed

4 files changed

+20
-3
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1068,7 +1068,7 @@ trait Infer {
10681068
try {
10691069
// debuglog("TVARS "+ (tvars map (_.constr)))
10701070
// look at the argument types of the primary constructor corresponding to the pattern
1071-
val variances = undetparams map varianceInType(ctorTp)
1071+
val variances = undetparams map varianceInType(ctorTp.paramTypes.headOption getOrElse ctorTp)
10721072
val targs = solvedTypes(tvars, undetparams, variances, true, lubDepth(List(resTp, pt)))
10731073
// checkBounds(tree, NoPrefix, NoSymbol, undetparams, targs, "inferred ")
10741074
// no checkBounds here. If we enable it, test bug602 fails.

src/library/scala/concurrent/impl/Promise.scala

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,10 @@ object Promise {
8080
def EmptyPending[T](): FState[T] = emptyPendingValue.asInstanceOf[FState[T]]
8181

8282
/** Represents the internal state.
83+
*
84+
* [adriaan] it's unsound to make FState covariant (tryComplete won't type check)
8385
*/
84-
sealed trait FState[+T] { def value: Option[Try[T]] }
86+
sealed trait FState[T] { def value: Option[Try[T]] }
8587

8688
case class Pending[T](listeners: List[Try[T] => Any] = Nil) extends FState[T] {
8789
def value: Option[Try[T]] = None
@@ -155,7 +157,11 @@ object Promise {
155157
def tryComplete(v: Try[T]): List[Try[T] => Any] = {
156158
getState match {
157159
case cur @ Pending(listeners) =>
158-
if (updateState(cur, if (v.isFailure) Failure(Some(v.asInstanceOf[util.Failure[T]])) else Success(Some(v.asInstanceOf[util.Success[T]])))) listeners
160+
val newState =
161+
if (v.isFailure) Failure(Some(v.asInstanceOf[util.Failure[T]]))
162+
else Success(Some(v.asInstanceOf[util.Success[T]]))
163+
164+
if (updateState(cur, newState)) listeners
159165
else tryComplete(v)
160166
case _ => null
161167
}

test/files/neg/t5189.check

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
t5189.scala:3: error: type mismatch;
2+
found : Nothing => Any
3+
required: Any => Any
4+
def f(x: Any): Any => Any = x match { case Foo(bar) => bar }
5+
^
6+
one error found

test/files/neg/t5189.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
class TestNeg1 {
2+
case class Foo[T, U](f: T => U)
3+
def f(x: Any): Any => Any = x match { case Foo(bar) => bar }
4+
// uh-oh, Any => Any should be Nothing => Any.
5+
}

0 commit comments

Comments
 (0)