scala/scala — pull request #3639 by retronym (2014-03-18 15:19:48+00:00)
Title: SI-8341 Refine handoff of undet. params from implicit search

In SI-7944 / 251c2b93, we discovered that typechecking of an implicit
candidate could leave orphaned undetermined type parameters in the
implicit search context. This resulted in naked type parameters
leaking into implicit expansions. The fix seemed easy: just copy
any symbols from `implicitSearchContext.undetparams` to the enclosing
context (other than ones in `SearchResult#subst`).

However, the test case in this ticket reveals a subtle flaw in that
fix: `implicitSerachContext.undetparams` only contains the type params
from the most recently typechecked candidate!

Why? Implicit search uses the same context to typecheck all plausibly
compatible candidates. The typechecking itself is driven by
`typedImplicit1`.

Side note, that explains the heisenbug behaviour noted in the ticket:
Not *all* plausibly implicit candidates are typechecked. If
the current 'best' eligible candidate is more specific than the next
candidate, we can skip that altogether.Implicit search actually
exploits this for performance by ordering the candidates according to
usage statistics. This reordering, means that commenting out lines
elsewhere in the file changed the behaviour!

This commit simply stores the undet. tparams in the `SearchResult`,
where it is safe from the vaguries of typechecking other candidates.

That makes `Test1` and `Test2` with in the enclosed test case fail
uniformly, both with each other, and with an explicit call to
the view.

This is ostensibly a regression from 2.10.3. To get there,
we need an implicit search that has to infer `Nothing` in a covariant
position. In 2.10.3, we would just let the `G` out into the wild,
which did the right thing for the wrong reasons.