Skip to content

Commit 2f13c2a

Browse files
committed
Fix #6238: Strip WildcardType when applying arguments
I'm not entirely sure why this fixes the issue but the previous behavior seems dubious to me: what's the meaning of applying a WildcardType argument to a type lambda ? By contrast, applying a TypeBounds has a well-defined behavior (`appliedTo` will call `TypeApplication#Reducer` to get rid of the type lambda).
1 parent ef5c96d commit 2f13c2a

File tree

2 files changed

+126
-1
lines changed

2 files changed

+126
-1
lines changed

compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -586,10 +586,14 @@ object ProtoTypes {
586586
else if (tp.symbol.isStatic || (tp.prefix `eq` NoPrefix)) tp
587587
else tp.derivedSelect(wildApprox(tp.prefix, theMap, seen))
588588
case tp @ AppliedType(tycon, args) =>
589+
def wildToBounds(tp: Type) = tp match {
590+
case WildcardType(tp: TypeBounds) => tp
591+
case tp => tp
592+
}
589593
wildApprox(tycon, theMap, seen) match {
590594
case _: WildcardType => WildcardType // this ensures we get a * type
591595
case tycon1 => tp.derivedAppliedType(tycon1,
592-
args.mapConserve(arg => wildApprox(arg, theMap, seen)))
596+
args.mapConserve(arg => wildToBounds(wildApprox(arg, theMap, seen))))
593597
}
594598
case tp: RefinedType => // default case, inlined for speed
595599
tp.derivedRefinedType(

tests/pos/i6238.scala

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
object K1 {
2+
class Foo[T]
3+
4+
class Bar[F[_]]
5+
object Bar {
6+
implicit def barF[F[_]](implicit fooF: Foo[Bar[F]]): Bar[F] = null
7+
}
8+
9+
class A[T]
10+
object A {
11+
implicit def fooA[F[_[_]]](implicit barB: F[B]): Foo[F[A]] = null
12+
}
13+
14+
class B[T]
15+
object B {
16+
implicit def fooB[F[_[_]]]: Foo[F[B]] = null
17+
}
18+
}
19+
20+
object K1U {
21+
class Foo[T]
22+
23+
class Bar[F[_ <: Int]]
24+
object Bar {
25+
implicit def barF[F[_ <: Int]](implicit fooF: Foo[Bar[F]]): Bar[F] = null
26+
}
27+
28+
class A[T <: Int]
29+
object A {
30+
implicit def fooA[F[_[_ <: Int]]](implicit barB: F[B]): Foo[F[A]] = null
31+
}
32+
33+
class B[T <: Int]
34+
object B {
35+
implicit def fooB[F[_[_ <: Int]]]: Foo[F[B]] = null
36+
}
37+
}
38+
39+
object K1L {
40+
class Foo[T]
41+
42+
class Bar[F[_ >: Int]]
43+
object Bar {
44+
implicit def barF[F[_ >: Int]](implicit fooF: Foo[Bar[F]]): Bar[F] = null
45+
}
46+
47+
class A[T >: Int]
48+
object A {
49+
implicit def fooA[F[_[_ >: Int]]](implicit barB: F[B]): Foo[F[A]] = null
50+
}
51+
52+
class B[T >: Int]
53+
object B {
54+
implicit def fooB[F[_[_ >: Int]]]: Foo[F[B]] = null
55+
}
56+
}
57+
58+
object K11 {
59+
class Foo[T]
60+
61+
class Bar[F[_[_]]]
62+
object Bar {
63+
implicit def barF[F[_[_]]](implicit fooF: Foo[Bar[F]]): Bar[F] = null
64+
}
65+
66+
class A[T[_]]
67+
object A {
68+
implicit def fooA[F[_[_[_]]]](implicit barB: F[B]): Foo[F[A]] = null
69+
}
70+
71+
class B[T[_]]
72+
object B {
73+
implicit def fooB[F[_[_[_]]]]: Foo[F[B]] = null
74+
}
75+
}
76+
77+
object K2 {
78+
class Foo[T]
79+
80+
class Bar[F[_, _]]
81+
object Bar {
82+
implicit def barF[F[_, _]](implicit fooF: Foo[Bar[F]]): Bar[F] = null
83+
}
84+
85+
class A[T, U]
86+
object A {
87+
implicit def fooA[F[_[_, _]]](implicit barB: F[B]): Foo[F[A]] = null
88+
}
89+
90+
class B[T, U]
91+
object B {
92+
implicit def fooB[F[_[_, _]]]: Foo[F[B]] = null
93+
}
94+
}
95+
96+
object Test {
97+
{
98+
import K1._
99+
implicitly[Bar[A]]
100+
}
101+
102+
{
103+
import K1U._
104+
implicitly[Bar[A]]
105+
}
106+
107+
{
108+
import K1L._
109+
implicitly[Bar[A]]
110+
}
111+
112+
{
113+
import K11._
114+
implicitly[Bar[A]]
115+
}
116+
117+
{
118+
import K2._
119+
implicitly[Bar[A]]
120+
}
121+
}

0 commit comments

Comments
 (0)