scala/scala — pull request #3486 by retronym (2014-02-07 14:35:17+00:00)
Title: SI-7553 Propagate type of unstable args through dependent methods

After a soundness fix in SI-3873, instantiation of dependent
method type results behaved differently for if the argument
from which we were propagating information had a stable type
or not. This is particular to substutition into singleton types
over the parameter in question.

If the argument was stable, it was substituted into singleton
types, such as the one below in the prefix in `a.type#B`
(which is the longhand version of `a.B`)

scala> class A { type B >: Null <: AnyRef }
defined class A

scala> object AA extends A { type B = String }
defined object AA

scala> def foo(a: A): a.B = null
foo: (a: A)a.B

scala> foo(AA)
res0: AA.B = null

But what if it isn't stable?

scala> foo({def a = AA; a: A { type B <: String}})
res3: a.B = null

This commit changes that to:

scala> foo({def a = AA; a: A { type B <: String}})
res1: a.type with A{type B <: String}#B = null

That oddly printed type is missing parens: it should be:

(a.type with A{type B <: String})#B

It is is a protection from refinement that combines:
a) the singleton type on the parameter
b) the type of the argument

Review by @adriaanm