Skip to content

Commit 6e8bea7

Browse files
committed
Refine constraining scheme for result types
- Take MatchTypes into account - Add test cases for tests that failed originally and would otherwise fail again after this PR. i19415.scala is fixed by the MatchType extension. i19749.scala was fixed by adding a `transparent`.
1 parent 07e9c40 commit 6e8bea7

File tree

3 files changed

+87
-2
lines changed

3 files changed

+87
-2
lines changed

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

+9-2
Original file line numberDiff line numberDiff line change
@@ -131,9 +131,16 @@ object ProtoTypes {
131131

132132
constFoldException(pt) || {
133133
if Inlines.isInlineable(meth) then
134-
// Stricter behaviour in 3.4+: do not apply `wildApprox` to non-transparent inlines
134+
// Stricter behavisour in 3.4+: do not apply `wildApprox` to non-transparent inlines
135+
// unless their return type is a MatchType. In this case there's no reason
136+
// not to constrain type variables in the expected type. For transparent inlines
137+
// we do not want to constrain type variables in the expected type since the
138+
// actual return type might be smaller after instantiation. For inlines returning
139+
// MatchTypes we do not want to constrain because the MatchType might be more
140+
// specific after instantiation. TODO: Should we also use Wildcards for non-inline
141+
// methods returning MatchTypes?
135142
if Feature.sourceVersion.isAtLeast(SourceVersion.`3.4`) then
136-
if meth.is(Transparent) then
143+
if meth.is(Transparent) || mt.resultType.isMatchAlias then
137144
constrainResult(mt, wildApprox(pt))
138145
// do not constrain the result type of transparent inline methods
139146
true

tests/pos/i19415.scala

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
def Test = {
2+
val left: Parser[String] = ???
3+
val right: Parser[Int] = ???
4+
val both = left && right
5+
6+
val works = both.map(Ior.Both.apply)
7+
val fails = (left && right).map(Ior.Both.apply)
8+
}
9+
10+
trait Parser[T]:
11+
final def &&[T2](other: Parser[T2])(implicit zip: Zip[T, T2]): Parser[zip.Out] = ???
12+
final def map[T2](f: T => T2): Parser[T2] = ???
13+
14+
infix trait Ior[+A, +B]
15+
object Ior:
16+
final case class Both[+A, +B](a: A, b: B) extends (A Ior B)
17+
18+
trait Zip[In1, In2]:
19+
type Out
20+
21+
object Zip {
22+
type Out[In1, In2, O] = Zip[In1, In2] { type Out = O }
23+
implicit def zip2[_1, _2]: Zip.Out[_1, _2, (_1, _2)] = ???
24+
}

tests/pos/i19479.scala

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
case class Person(id: Int)
2+
3+
class GeodeContinuousSourceSpec {
4+
summon[PdxEncoder[Person]]
5+
}
6+
7+
trait PdxEncoder[A] {
8+
def encode(a: A): Boolean
9+
}
10+
11+
object PdxEncoder extends ObjectEncoder {
12+
implicit def intEncoder: PdxEncoder[Int] = ???
13+
}
14+
15+
trait ObjectEncoder {
16+
given emptyTupleEncoder: PdxEncoder[EmptyTuple] = ???
17+
18+
given tupleEncoder[K <: String, H, T <: Tuple](using
19+
m: ValueOf[K],
20+
hEncoder: PdxEncoder[H],
21+
tEncoder: PdxEncoder[T]
22+
): PdxEncoder[FieldType[K, H] *: T] = ???
23+
24+
given objectEncoder[A, Repr <: Tuple](using
25+
gen: LabelledGeneric.Aux[A, Repr],
26+
tupleEncoder: PdxEncoder[Repr]
27+
): PdxEncoder[A] = ???
28+
}
29+
30+
import scala.deriving.Mirror
31+
32+
private type FieldType[K, +V] = V & KeyTag[K, V]
33+
private type KeyTag[K, +V]
34+
private type ZipWith[T1 <: Tuple, T2 <: Tuple, F[_, _]] <: Tuple = (T1, T2) match {
35+
case (h1 *: t1, h2 *: t2) => F[h1, h2] *: ZipWith[t1, t2, F]
36+
case (EmptyTuple, ?) => EmptyTuple
37+
case (?, EmptyTuple) => EmptyTuple
38+
case _ => Tuple
39+
}
40+
41+
private trait LabelledGeneric[A] {
42+
type Repr
43+
}
44+
45+
private object LabelledGeneric {
46+
type Aux[A, R] = LabelledGeneric[A] { type Repr = R }
47+
48+
transparent inline given productInst[A <: Product](using
49+
m: Mirror.ProductOf[A]
50+
): LabelledGeneric.Aux[A, ZipWith[m.MirroredElemLabels, m.MirroredElemTypes, FieldType]] =
51+
new LabelledGeneric[A] {
52+
type Repr = Tuple & ZipWith[m.MirroredElemLabels, m.MirroredElemTypes, FieldType]
53+
}
54+
}

0 commit comments

Comments
 (0)