Skip to content

Commit 4f1431d

Browse files
committed
Fix match type instantiation when not approximating
When not approximating parameters, keep the constraint entries in a Range, so it can propagate through instantiateParams's ApproximatingTypeMap.
1 parent 5c2efc5 commit 4f1431d

File tree

19 files changed

+129
-54
lines changed

19 files changed

+129
-54
lines changed

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3095,17 +3095,18 @@ class TrackingTypeComparer(initctx: Context) extends TypeComparer(initctx) {
30953095
def paramInstances(canApprox: Boolean) = new TypeAccumulator[Array[Type]]:
30963096
def apply(insts: Array[Type], t: Type) = t match
30973097
case param @ TypeParamRef(b, n) if b eq caseLambda =>
3098+
def range1(tp: Type) = Range(tp, tp)
30983099
insts(n) =
30993100
if canApprox then
31003101
approximation(param, fromBelow = variance >= 0, Int.MaxValue).simplified
31013102
else constraint.entry(param) match
31023103
case entry: TypeBounds =>
31033104
val lo = fullLowerBound(param)
31043105
val hi = fullUpperBound(param)
3105-
if isSubType(hi, lo) then lo.simplified else Range(lo, hi)
3106+
if isSubType(hi, lo) then range1(lo.simplified) else Range(lo, hi)
31063107
case inst =>
31073108
assert(inst.exists, i"param = $param\nconstraint = $constraint")
3108-
inst.simplified
3109+
range1(inst.simplified)
31093110
insts
31103111
case _ =>
31113112
foldOver(insts, t)

compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1418,7 +1418,11 @@ class TreeUnpickler(reader: TastyReader,
14181418
val args = until(end)(readTpt())
14191419
val tree = untpd.AppliedTypeTree(tycon, args)
14201420
val ownType = ctx.typeAssigner.processAppliedType(tree, tycon.tpe.safeAppliedTo(args.tpes))
1421-
tree.withType(postProcessFunction(ownType))
1421+
tree.withType(postProcessFunction(ownType) match {
1422+
case tp @ MatchType.InDisguise(_) => tp
1423+
case tp: AndType => tp // pickleSkolem
1424+
case tp => tp.simplified // i17149
1425+
})
14221426
case ANNOTATEDtpt =>
14231427
Annotated(readTpt(), readTerm())
14241428
case LAMBDAtpt =>

compiler/src/dotty/tools/dotc/transform/TypeUtils.scala

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,11 @@ object TypeUtils {
7676
case AndType(tp1, tp2) =>
7777
// We assume that we have the following property:
7878
// (T1, T2, ..., Tn) & (U1, U2, ..., Un) = (T1 & U1, T2 & U2, ..., Tn & Un)
79-
tp1.tupleElementTypes.zip(tp2.tupleElementTypes).map { case (t1, t2) => t1.intersect(t2) }
79+
val types1 = tp1.tupleElementTypes
80+
val types2 = tp2.tupleElementTypes
81+
if !types1.isDefined then types2 // e.g. i15302b which has Int *: Int *: Tuple (not EmptyTuple)
82+
else if !types2.isDefined then types1
83+
else types1.zip(types2).map { case (t1, t2) => t1.intersect(t2) }
8084
case OrType(tp1, tp2) =>
8185
None // We can't combine the type of two tuples
8286
case _ =>

compiler/test/dotty/tools/dotc/interactive/CustomCompletionTests.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ class CustomCompletionTests extends DottyTest:
3636
initialCtx.fresh
3737
.addMode(Mode.ReadPositions | Mode.Interactive)
3838
// discard errors - comment out this line to print them in the console
39-
.setReporter(new StoreReporter(null))
39+
.setReporter(new StoreReporter(dotc.reporting.Reporter.NoReporter))
4040
.setSetting(initialCtx.settings.YstopAfter, List("typer"))
4141
)
4242
val file = SourceFile.virtual("<completions>", allCode, maybeIncomplete = true)

scaladoc-testcases/src/tests/typesSignatures.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ class Operators
5151
// type Binary2 = String op Int
5252

5353
import scala.compiletime.ops.boolean.*
54-
type Unary = ![true]
54+
type Unary = ![true] //expected: type Unary = false
5555
}
5656

5757
trait ThisTypeTest

tests/neg/11982.scala

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ type Head[X] = X match {
44
}
55

66
object Unpair {
7-
def unpair[X <: Tuple2[Any, Any]]: Head[X] = 1
8-
unpair[Tuple2["msg", 42]]: "msg" // error
7+
def unpair[X <: Tuple2[Any, Any]]: Head[X] = 1 // error
8+
unpair[Tuple2["msg", 42]]: "msg"
99
}
1010

1111

@@ -14,8 +14,8 @@ type Head2[X] = X match {
1414
}
1515

1616
object Unpair2 {
17-
def unpair[X <: Tuple2[Tuple2[Any, Any], Tuple2[Any, Any]]]: Head2[X] = 1
18-
unpair[Tuple2[Tuple2["msg", 42], Tuple2[41, 40]]]: "msg" // error
17+
def unpair[X <: Tuple2[Tuple2[Any, Any], Tuple2[Any, Any]]]: Head2[X] = 1 // error
18+
unpair[Tuple2[Tuple2["msg", 42], Tuple2[41, 40]]]: "msg"
1919
}
2020

2121

@@ -35,6 +35,6 @@ type Head4[X] = X match {
3535
}
3636

3737
object Unpair4 {
38-
def unpair[X <: Foo[Any, Any]]: Head4[Foo[X, X]] = 1
39-
unpair[Foo["msg", 42]]: "msg" // error
38+
def unpair[X <: Foo[Any, Any]]: Head4[Foo[X, X]] = 1 // error
39+
unpair[Foo["msg", 42]]: "msg"
4040
}

tests/neg/i11982.check

Lines changed: 0 additions & 4 deletions
This file was deleted.

tests/neg/i11982.scala

Lines changed: 0 additions & 27 deletions
This file was deleted.

tests/neg/i11982a.check

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,10 @@
77
|
88
| trying to reduce Tuple.Tail[X]
99
| failed since selector X
10-
| does not uniquely determine parameter xs in
10+
| does not uniquely determine parameters _, xs in
1111
| case _ *: xs => xs
12-
| The computed bounds for the parameter are:
12+
| The computed bounds for the parameters are:
13+
| _ >: Any
1314
| xs >: Any *: EmptyTuple.type <: Tuple
1415
|
1516
| longer explanation available when compiling with `-explain`
@@ -22,9 +23,10 @@
2223
|
2324
| trying to reduce Tuple.Tail[X]
2425
| failed since selector X
25-
| does not uniquely determine parameter xs in
26+
| does not uniquely determine parameters _, xs in
2627
| case _ *: xs => xs
27-
| The computed bounds for the parameter are:
28+
| The computed bounds for the parameters are:
29+
| _ >: Any
2830
| xs >: Any *: EmptyTuple.type <: Tuple
2931
|
3032
| longer explanation available when compiling with `-explain`
@@ -37,9 +39,10 @@
3739
|
3840
| trying to reduce Tuple.Tail[X]
3941
| failed since selector X
40-
| does not uniquely determine parameter xs in
42+
| does not uniquely determine parameters _, xs in
4143
| case _ *: xs => xs
42-
| The computed bounds for the parameter are:
44+
| The computed bounds for the parameters are:
45+
| _ >: Any
4346
| xs >: Any *: EmptyTuple.type <: Tuple
4447
|
4548
| longer explanation available when compiling with `-explain`

tests/neg/i13780.check

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,23 @@
1+
-- [E007] Type Mismatch Error: tests/neg/i13780.scala:12:32 ------------------------------------------------------------
2+
12 | def unpair[X <: Y]: Head[X] = "" // error
3+
| ^^
4+
| Found: ("" : String)
5+
| Required: Head[X]
6+
|
7+
| where: X is a type in method unpair with bounds <: A.this.Y
8+
|
9+
|
10+
| Note: a match type could not be fully reduced:
11+
|
12+
| trying to reduce Head[X]
13+
| failed since selector X
14+
| does not uniquely determine parameters a, b in
15+
| case (a, b) => a
16+
| The computed bounds for the parameters are:
17+
| a >: Any
18+
| b >: Any
19+
|
20+
| longer explanation available when compiling with `-explain`
121
-- [E007] Type Mismatch Error: tests/neg/i13780.scala:18:31 ------------------------------------------------------------
222
18 | def int[X <: Y]: Int = unpair[X] // error
323
| ^^^^^^^^^

0 commit comments

Comments
 (0)