Skip to content

Commit 372ddf6

Browse files
committed
Fix #11078: avoid widening bounds in type avoidance
This avoids expanding F-Bounds as well.
1 parent 6d9e101 commit 372ddf6

File tree

3 files changed

+59
-1
lines changed

3 files changed

+59
-1
lines changed

compiler/src/dotty/tools/dotc/core/TypeOps.scala

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package dotc
33
package core
44

55
import Contexts._, Types._, Symbols._, Names._, Flags._
6-
import SymDenotations._
6+
import Denotations._, SymDenotations._
77
import util.Spans._
88
import util.Stats
99
import NameKinds.DepParamName
@@ -462,6 +462,24 @@ object TypeOps:
462462
else
463463
range(defn.NothingType, defn.AnyType)
464464
}
465+
466+
/** Deviation from standard tryWiden:
467+
* - Only widen type aliases
468+
*/
469+
override def tryWiden(tp: NamedType, pre: Type): Type = pre.member(tp.name) match {
470+
case d: SingleDenotation =>
471+
val tp1 = d.info.dealiasKeepAnnots
472+
tp1.stripAnnots match {
473+
case TypeAlias(alias) =>
474+
// if H#T = U, then for any x in L..H, x.T =:= U,
475+
// hence we can replace with U under all variances
476+
reapply(alias.rewrapAnnots(tp1))
477+
case _ =>
478+
NoType
479+
}
480+
case _ => NoType
481+
}
482+
465483
}
466484

467485
widenMap(tp)

tests/pos/i11078.scala

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
trait Foo[A <: Foo[A]]
2+
trait FooCreator[A <: Foo[A]] {
3+
def createFoo(): A
4+
}
5+
6+
trait FooWrapper {
7+
type A <: Foo[A]
8+
def foo: A
9+
}
10+
object FooWrapper {
11+
def apply[A0 <: Foo[A0]](toWrap: A0): FooWrapper { type A = A0 } = new FooWrapper {
12+
type A = A0
13+
def foo: A0 = toWrap
14+
}
15+
}
16+
17+
trait FooCreatorWrapper {
18+
type A <: Foo[A]
19+
def fooCreator: FooCreator[A]
20+
}
21+
22+
sealed trait Bar
23+
object Bar {
24+
case class Baz(wrapper: FooCreatorWrapper) extends Bar
25+
}
26+
27+
def process(bar: Bar): FooWrapper = bar match {
28+
case Bar.Baz(wrapper) => FooWrapper(wrapper.fooCreator.createFoo())
29+
}

tests/pos/i11078b.scala

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
class Test {
2+
trait Foo[A <: Foo[A]]
3+
4+
trait FooWrapper with self =>
5+
type A <: Foo[A]
6+
def doThing(foo: FooWrapper): FooWrapper { type A = self.A } = ???
7+
end FooWrapper
8+
9+
val foos: scala.Seq[FooWrapper] = ???
10+
val newFoo = foos.foldLeft(??? : FooWrapper)((topFoo, foo) => topFoo.doThing(foo))
11+
}

0 commit comments

Comments
 (0)