scala/scala — pull request #2685 by retronym (2013-06-27 08:57:18+00:00)
Title: SI-7621 Fix SOE regression in lubs

The enclosed test case (whittled down lovingly from lift-mapper)
triggers the cycle in `elimSub`.

Regressed in a06d31f6a. The change was dicussed
.

This patch reverts to using `.underlying`.

Below, I've shown the different paths that are taken through
that method with before and after this patch. The key divergence
is when `.this.M.dealias` reveals a captured existential
type symbol. Because the enclosed test case has F-bounded generics,
when we later extrapolate that captured `_2` to its upper bound,
we create another call to lub with the same types.

A more detailed look at how that happens:

Review by @adriaanm.

Targetting 2.10.x on grounds of locality of the fix and regression from 2.10.0 -> 2.10.1.

Following .underlying (after)
=============================

ts0 = List(A, B)
underlyings = List(A, B)
dealiasWidens = List(A, B)

ts0 = List(Mapper[A], Mapper[B])
underlyings = List(Mapper[A], Mapper[B])
dealiasWidens = List(Mapper[A], Mapper[B])

ts0 = List(A, B)
underlyings = List(A, B)
dealiasWidens = List(A, B)

ts0 = List(Mapper[A], Mapper[B])
underlyings = List(Mapper[A], Mapper[B])
dealiasWidens = List(Mapper[A], Mapper[B])

ts0 = List(A, B)
underlyings = List(A, B)
dealiasWidens = List(A, B)

ts0 = List(Mapper[A], Mapper[B])
underlyings = List(Mapper[A], Mapper[B])
dealiasWidens = List(Mapper[A], Mapper[B])

ts0 = List(=> MappedField[A], => this.id.type)
underlyings = List(=> MappedField[A], => this.id.type)
dealiasWidens = List(=> MappedField[A], => this.id.type)

ts0 = List(MappedField[A], this.id.type)
underlyings = List(MappedField[A], IdPK.this.id.type)
dealiasWidens = List(MappedField[A], IdPK.this.id.type)

ts0 = List(MappedField[A], IdPK.this.id.type)
underlyings = List(MappedField[A], IdPK.this.id.type)
dealiasWidens = List(MappedField[A], IdPK.this.id.type)

ts0 = List(MappedField[A], MappedField[IdPK.this.M])
underlyings = List(MappedField[A], MappedField[IdPK.this.M])
dealiasWidens = List(MappedField[A], MappedField[IdPK.this.M])

ts0 = List(=> MappedField[A], => this.id.type)
underlyings = List(=> MappedField[A], => this.id.type)
dealiasWidens = List(=> MappedField[A], => this.id.type)

ts0 = List(MappedField[A], this.id.type)
underlyings = List(MappedField[A], IdPK.this.id.type)
dealiasWidens = List(MappedField[A], IdPK.this.id.type)

ts0 = List(MappedField[A], IdPK.this.id.type)
underlyings = List(MappedField[A], IdPK.this.id.type)
dealiasWidens = List(MappedField[A], IdPK.this.id.type)

ts0 = List(MappedField[A], MappedField[IdPK.this.M])
underlyings = List(MappedField[A], MappedField[IdPK.this.M])
dealiasWidens = List(MappedField[A], MappedField[IdPK.this.M])

ts0 = List(A, IdPK.this.M)
underlyings = List(A, IdPK.this.M)
dealiasWidens = List(A, IdPK.this.M)

ts0 = List(A with IdPK.this.M, this.M)
underlyings = List(A with IdPK.this.M, this.M)
dealiasWidens = List(A with IdPK.this.M, _2)

ts0 = List(A with IdPK.this.M, this.M)
underlyings = List(A with IdPK.this.M, this.M)
dealiasWidens = List(A with IdPK.this.M, B)

ts0 = List(A with IdPK.this.M, this.M)
underlyings = List(A with IdPK.this.M, this.M)
dealiasWidens = List(A with IdPK.this.M, B)

ts0 = List(A, B)
underlyings = List(A, B)
dealiasWidens = List(A, B)

ts0 = List(Mapper[A], Mapper[B])
underlyings = List(Mapper[A], Mapper[B])
dealiasWidens = List(Mapper[A], Mapper[B])

ts0 = List(A, B)
underlyings = List(A, B)
dealiasWidens = List(A, B)

ts0 = List(Mapper[A], Mapper[B])
underlyings = List(Mapper[A], Mapper[B])
dealiasWidens = List(Mapper[A], Mapper[B])

Following .dealiasWiden (before)
================================

ts0 = List(A, B)
underlyings = List(A, B)
dealiasWidens = List(A, B)

ts0 = List(Mapper[A], Mapper[B])
underlyings = List(Mapper[A], Mapper[B])
dealiasWidens = List(Mapper[A], Mapper[B])

ts0 = List(=> MappedField[A], => this.id.type)
underlyings = List(=> MappedField[A], => this.id.type)
dealiasWidens = List(=> MappedField[A], => this.id.type)

ts0 = List(MappedField[A], this.id.type)
underlyings = List(MappedField[A], IdPK.this.id.type)
dealiasWidens = List(MappedField[A], IdPK.this.id.type)

ts0 = List(MappedField[A], IdPK.this.id.type)
underlyings = List(MappedField[A], IdPK.this.id.type)
dealiasWidens = List(MappedField[A], IdPK.this.id.type)

ts0 = List(MappedField[A], MappedField[IdPK.this.M])
underlyings = List(MappedField[A], MappedField[IdPK.this.M])
dealiasWidens = List(MappedField[A], MappedField[IdPK.this.M])

ts0 = List(=> MappedField[A], => this.id.type)
underlyings = List(=> MappedField[A], => this.id.type)
dealiasWidens = List(=> MappedField[A], => this.id.type)

ts0 = List(MappedField[A], this.id.type)
underlyings = List(MappedField[A], IdPK.this.id.type)
dealiasWidens = List(MappedField[A], IdPK.this.id.type)

ts0 = List(MappedField[A], IdPK.this.id.type)
underlyings = List(MappedField[A], IdPK.this.id.type)
dealiasWidens = List(MappedField[A], IdPK.this.id.type)

ts0 = List(MappedField[A], MappedField[IdPK.this.M])
underlyings = List(MappedField[A], MappedField[IdPK.this.M])
dealiasWidens = List(MappedField[A], MappedField[IdPK.this.M])

ts0 = List(A, IdPK.this.M)
underlyings = List(A, IdPK.this.M)
dealiasWidens = List(A, IdPK.this.M)

ts0 = List(A with IdPK.this.M, this.M)
underlyings = List(A with IdPK.this.M, this.M)
dealiasWidens = List(A with IdPK.this.M, _2)

ts0 = List(A with IdPK.this.M, _2)
underlyings = List(A with IdPK.this.M, _2)
dealiasWidens = List(A with IdPK.this.M, _2)

ts0 = List(A with IdPK.this.M, this.M)
underlyings = List(A with IdPK.this.M, this.M)
dealiasWidens = List(A with IdPK.this.M, B)

ts0 = List(A with IdPK.this.M, B)
underlyings = List(A with IdPK.this.M, B)
dealiasWidens = List(A with IdPK.this.M, B)

ts0 = List(Mapper[A], Mapper[B])
underlyings = List(Mapper[A], Mapper[B])
dealiasWidens = List(Mapper[A], Mapper[B])

ts0 = List(A, B)
underlyings = List(A, B)
dealiasWidens = List(A, B)

ts0 = List(Mapper[A], Mapper[B])
underlyings = List(Mapper[A], Mapper[B])
dealiasWidens = List(Mapper[A], Mapper[B])

ts0 = List(A, B)
underlyings = List(A, B)
dealiasWidens = List(A, B)

ts0 = List(Mapper[A], Mapper[B])
underlyings = List(Mapper[A], Mapper[B])
dealiasWidens = List(Mapper[A], Mapper[B])

ts0 = List(=> MappedField[A], => this.id.type)
underlyings = List(=> MappedField[A], => this.id.type)
dealiasWidens = List(=> MappedField[A], => this.id.type)

ts0 = List(MappedField[A], this.id.type)
underlyings = List(MappedField[A], IdPK.this.id.type)
dealiasWidens = List(MappedField[A], IdPK.this.id.type)

ts0 = List(MappedField[A], IdPK.this.id.type)
underlyings = List(MappedField[A], IdPK.this.id.type)
dealiasWidens = List(MappedField[A], IdPK.this.id.type)

ts0 = List(MappedField[A], MappedField[IdPK.this.M])
underlyings = List(MappedField[A], MappedField[IdPK.this.M])
dealiasWidens = List(MappedField[A], MappedField[IdPK.this.M])

ts0 = List(=> MappedField[A], => this.id.type)
underlyings = List(=> MappedField[A], => this.id.type)
dealiasWidens = List(=> MappedField[A], => this.id.type)

ts0 = List(MappedField[A], this.id.type)
underlyings = List(MappedField[A], IdPK.this.id.type)
dealiasWidens = List(MappedField[A], IdPK.this.id.type)

ts0 = List(MappedField[A], IdPK.this.id.type)
underlyings = List(MappedField[A], IdPK.this.id.type)
dealiasWidens = List(MappedField[A], IdPK.this.id.type)

ts0 = List(MappedField[A], MappedField[IdPK.this.M])
underlyings = List(MappedField[A], MappedField[IdPK.this.M])
dealiasWidens = List(MappedField[A], MappedField[IdPK.this.M])

ts0 = List(A, IdPK.this.M)
underlyings = List(A, IdPK.this.M)
dealiasWidens = List(A, IdPK.this.M)

ts0 = List(A with IdPK.this.M, this.M)
underlyings = List(A with IdPK.this.M, this.M)
dealiasWidens = List(A with IdPK.this.M, _5)

ts0 = List(A with IdPK.this.M, _5)
underlyings = List(A with IdPK.this.M, _5)
dealiasWidens = List(A with IdPK.this.M, _5)