Skip to content

Commit

Permalink
Don't leak sharpened bounds between implicit candidates
Browse files Browse the repository at this point in the history
The bounds propagation introduced in scala#6140 caused a
regression in scala/scala-java8-compat#97 because bounds sharpened while
ranking implicit candidates leaked from candidates tested earlier to
those tested later.

This commit fixes that by saving and restoring the infos of the symbols
of the undetermined type parameters around the call to type check the
implicit candidate which tests for it's applicability.

Initially it seemed like this ought to be a job for undoLog or
Context#savingUndeteriminedTypeParams, but neither of those do the right
thing here. UndoLog doesn't help because it affects the constraint on
the corresponding TypeVar rather than the info of the symbol; and
savingUndeterminedTypeParams doesn't help because the relevant call to
typedImplicit shares the enclosing ImplicitSearch#undetParams rather
than looking at the context.
  • Loading branch information
milessabin committed Feb 3, 2018
1 parent ec5e241 commit f21e037
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/compiler/scala/tools/nsc/typechecker/Implicits.scala
Original file line number Diff line number Diff line change
Expand Up @@ -963,7 +963,9 @@ trait Implicits {
}
)

val savedInfos = undetParams.map(_.info)
val typedFirstPending = typedImplicit(firstPending, ptChecked = true, isLocalToCallsite)
foreach2(undetParams, savedInfos){ (up, si) => up.setInfo(si) }

// Pass the errors to `DivergentImplicitRecovery` so that it can note
// the first `DivergentImplicitTypeError` that is being propagated
Expand Down
24 changes: 24 additions & 0 deletions test/files/pos/t10708.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
trait BaseStream[T, S <: BaseStream[T, S]]
trait Stream[T] extends BaseStream[T, Stream[T]]
trait IntStream extends BaseStream[Integer, IntStream]

sealed trait SS[T, S <: BaseStream[_, S]]
object SSImplicits extends Low {
implicit val IntValue: SS[Int, IntStream] = null
}
trait Low {
implicit def anyStreamShape[T]: SS[T, Stream[T]] = null
}

import SSImplicits.{IntValue, anyStreamShape}

class Test {
implicit def f[A, S <: BaseStream[_, S], CC](a: A)(implicit ss: SS[A, S]): S = ???

y
x

def x = f(0): IntStream
def y = f[String, Stream[String], Vector[String]]("")

}

0 comments on commit f21e037

Please sign in to comment.