diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2014-02-01 17:59:34 +0100 |
---|---|---|
committer | Adriaan Moors <adriaan.moors@typesafe.com> | 2014-02-18 21:02:50 -0800 |
commit | 917c49416133bd067c203f907e9fe9112a081ff4 (patch) | |
tree | eea69d042c59030ac663973b7013a12119763ae7 /test/files | |
parent | 3dbcb1b9d4daa5cba98747bbc66f898ba0f864fd (diff) | |
download | scala-917c49416133bd067c203f907e9fe9112a081ff4.tar.gz scala-917c49416133bd067c203f907e9fe9112a081ff4.tar.bz2 scala-917c49416133bd067c203f907e9fe9112a081ff4.zip |
SI-8224 Fix regression in f-bound aware LUBs
Disable the heuristic approach to recursive bounds unless
the compiler is running under `-Xstrict-inference`.
[the above was not authored by the original author]
In db46c71e88, steps were taken to avoid blowing up in the
pathological LUB calculation needed for:
def trav = List(List(), Stream())
This skipped a level in the base class sequence when f-bounds
were detected at the current level.
In that example, when `lublist` was about to:
mergePrefixAndArgs(
typeOf[LinearSeqOptimized[A, List[A]]],
typeOf[LinearSeqOptimized[A, Stream[A]]],
)
If it proceeded (as in 2.10.3), the LUB is invalid:
error: type arguments [B[_ >: D with C <: B[_ >: D with C <: A]],s.c.immutable.LinearSeq[B[_ >: D with C <: A]] with s.c.AbstractSeq[B[_ >: D with C <: A]] with s.c.LinearSeqOptimized[B[_ >: D with C <: A],s.c.immutable.LinearSeq[A] with s.c.AbstractSeq[A] with s.c.LinearSeqOptimized[A,Immutable with Equals with java.io.Serializable] with java.io.Serializable] with java.io.Serializable] do not conform to trait LinearSeqOptimized's type parameter bounds [+A,+Repr <: s.c.LinearSeqOptimized[A,Repr]]
To avoid this, the added code would skip to the first non-F-bounded
base type of the same arity of each element in the list. This would
get to:
LinearSeqLike[D, Stream[D]]
LinearSeqLike[C, List[C]]
which are lubbable without violating the type constraints.
I don't think this was the right remedy. For starters, as seen in
this bug report, SI-8224, if the list of types are identical we
have let a perfectly good lub slip through our fingers, and end up
calculating too general a type.
More generally, if the type arguments in f-bounded positions coincide,
we don't risk calculating a ill-bounded LUB.
Furthermore, the code was widening each of the types separately;
this isn't something we want to do within `if (isUniformFrontier)`.
AFAICT this was just wasteful and as all `ts0` start with the same
type symbol, so `typeConstructorList` should be uniform.
This commit restricts this base-class skipping to situations where
the argument inferred for an type argument that is used as an f-bound
is not:
a) an existential (as created by `mergePrefixAndArgs` in invariant
positions.), or
b) equivalent to one of the corresponding input type arguments
(this is the case that fixes the regression in pos/8224.scala)
Diffstat (limited to 'test/files')
-rw-r--r-- | test/files/pos/t8224.scala | 12 | ||||
-rw-r--r-- | test/files/run/t2251.flags | 1 | ||||
-rw-r--r-- | test/files/run/t2251b.flags | 1 |
3 files changed, 14 insertions, 0 deletions
diff --git a/test/files/pos/t8224.scala b/test/files/pos/t8224.scala new file mode 100644 index 0000000000..2fae925df3 --- /dev/null +++ b/test/files/pos/t8224.scala @@ -0,0 +1,12 @@ +import language.higherKinds + +trait P [N1, +E1[X <: N1]] +trait PIn[N2, +E2[X <: N2]] extends P[Int,Any] + +trait EI extends PIn[Int, Nothing] +trait NI extends PIn[Int, Nothing] + +object Test { + val lub = if (true) ??? : EI else ??? : NI + val pin: PIn[Int,Nothing] = lub +} diff --git a/test/files/run/t2251.flags b/test/files/run/t2251.flags new file mode 100644 index 0000000000..19243266d1 --- /dev/null +++ b/test/files/run/t2251.flags @@ -0,0 +1 @@ +-Xstrict-inference
\ No newline at end of file diff --git a/test/files/run/t2251b.flags b/test/files/run/t2251b.flags new file mode 100644 index 0000000000..19243266d1 --- /dev/null +++ b/test/files/run/t2251b.flags @@ -0,0 +1 @@ +-Xstrict-inference
\ No newline at end of file |