@@ -49,25 +49,34 @@ object ProtoTypes {
49
49
/** Test compatibility after normalization.
50
50
* Do this in a fresh typerstate unless `keepConstraint` is true.
51
51
*/
52
- def normalizedCompatible (tp : Type , pt : Type , keepConstraint : Boolean )(using Context ): Boolean = {
53
- def testCompat (using Context ): Boolean = {
52
+ def normalizedCompatible (tp : Type , pt : Type , keepConstraint : Boolean )(using Context ): Boolean =
53
+
54
+ def testCompat (using Context ): Boolean =
54
55
val normTp = normalize(tp, pt)
55
56
isCompatible(normTp, pt) || pt.isRef(defn.UnitClass ) && normTp.isParameterless
56
- }
57
- if ( keepConstraint)
58
- tp.widenSingleton match {
57
+
58
+ if keepConstraint || ctx.mode.is( Mode . ConstrainResultDeep ) then
59
+ tp.widenSingleton match
59
60
case poly : PolyType =>
60
- // We can't keep the constraint in this case, since we have to add type parameters
61
- // to it, but there's no place to associate them with type variables.
62
- // So we'd get a "inconsistent: no typevars were added to committable constraint"
63
- // assertion failure in `constrained`. To do better, we'd have to change the
64
- // constraint handling architecture so that some type parameters are committable
65
- // and others are not. But that's a whole different ballgame.
66
- normalizedCompatible(tp, pt, keepConstraint = false )
61
+ val newctx = ctx.fresh.setNewTyperState()
62
+ val result = testCompat(using newctx)
63
+ typr.println(
64
+ i """ normalizedCompatible for $poly, $pt = $result
65
+ |constraint was: ${ctx.typerState.constraint}
66
+ |constraint now: ${newctx.typerState.constraint}""" )
67
+ val existingVars = ctx.typerState.uninstVars.toSet
68
+ if result
69
+ && (ctx.typerState.constraint ne newctx.typerState.constraint)
70
+ && newctx.typerState.uninstVars.forall(existingVars.contains)
71
+ then newctx.typerState.commit()
72
+ // If the new constrait contains fresh type variables we cannot keep it,
73
+ // since those type variables are not instantiated anywhere in the source.
74
+ // See pos/i6682a.scala for a test case. See pos/11243.scala and pos/i5773b.scala
75
+ // for tests where it matters that we keep the constraint otherwise.
76
+ result
67
77
case _ => testCompat
68
- }
69
78
else explore(testCompat)
70
- }
79
+ end normalizedCompatible
71
80
72
81
private def disregardProto (pt : Type )(using Context ): Boolean =
73
82
pt.dealias.isRef(defn.UnitClass )
@@ -80,7 +89,16 @@ object ProtoTypes {
80
89
val res = pt.widenExpr match {
81
90
case pt : FunProto =>
82
91
mt match {
83
- case mt : MethodType => constrainResult(resultTypeApprox(mt), pt.resultType)
92
+ case mt : MethodType =>
93
+ constrainResult(resultTypeApprox(mt), pt.resultType)
94
+ && {
95
+ if ctx.mode.is(Mode .ConstrainResultDeep ) then
96
+ if mt.isImplicitMethod == (pt.applyKind == ApplyKind .Using ) then
97
+ val tpargs = pt.args.lazyZip(mt.paramInfos).map(pt.typedArg)
98
+ tpargs.tpes.corresponds(mt.paramInfos)(_ <:< _)
99
+ else true
100
+ else true
101
+ }
84
102
case _ => true
85
103
}
86
104
case _ : ValueTypeOrProto if ! disregardProto(pt) =>
@@ -123,6 +141,7 @@ object ProtoTypes {
123
141
abstract case class IgnoredProto (ignored : Type ) extends CachedGroundType with MatchAlways :
124
142
override def revealIgnored = ignored
125
143
override def deepenProto (using Context ): Type = ignored
144
+ override def deepenProtoTrans (using Context ): Type = ignored.deepenProtoTrans
126
145
127
146
override def computeHash (bs : Hashable .Binders ): Int = doHash(bs, ignored)
128
147
@@ -202,7 +221,12 @@ object ProtoTypes {
202
221
def map (tm : TypeMap )(using Context ): SelectionProto = derivedSelectionProto(name, tm(memberProto), compat)
203
222
def fold [T ](x : T , ta : TypeAccumulator [T ])(using Context ): T = ta(x, memberProto)
204
223
205
- override def deepenProto (using Context ): SelectionProto = derivedSelectionProto(name, memberProto.deepenProto, compat)
224
+ override def deepenProto (using Context ): SelectionProto =
225
+ derivedSelectionProto(name, memberProto.deepenProto, compat)
226
+
227
+ override def deepenProtoTrans (using Context ): SelectionProto =
228
+ derivedSelectionProto(name, memberProto.deepenProtoTrans, compat)
229
+
206
230
override def computeHash (bs : Hashable .Binders ): Int = {
207
231
val delta = (if (compat eq NoViewsAllowed ) 1 else 0 ) | (if (privateOK) 2 else 0 )
208
232
addDelta(doHash(bs, name, memberProto), delta)
@@ -419,7 +443,11 @@ object ProtoTypes {
419
443
def fold [T ](x : T , ta : TypeAccumulator [T ])(using Context ): T =
420
444
ta(ta.foldOver(x, typedArgs().tpes), resultType)
421
445
422
- override def deepenProto (using Context ): FunProto = derivedFunProto(args, resultType.deepenProto, typer)
446
+ override def deepenProto (using Context ): FunProto =
447
+ derivedFunProto(args, resultType.deepenProto, typer)
448
+
449
+ override def deepenProtoTrans (using Context ): FunProto =
450
+ derivedFunProto(args, resultType.deepenProtoTrans, typer)
423
451
424
452
override def withContext (newCtx : Context ): ProtoType =
425
453
if newCtx `eq` protoCtx then this
@@ -472,7 +500,11 @@ object ProtoTypes {
472
500
def fold [T ](x : T , ta : TypeAccumulator [T ])(using Context ): T =
473
501
ta(ta(x, argType), resultType)
474
502
475
- override def deepenProto (using Context ): ViewProto = derivedViewProto(argType, resultType.deepenProto)
503
+ override def deepenProto (using Context ): ViewProto =
504
+ derivedViewProto(argType, resultType.deepenProto)
505
+
506
+ override def deepenProtoTrans (using Context ): ViewProto =
507
+ derivedViewProto(argType, resultType.deepenProtoTrans)
476
508
}
477
509
478
510
class CachedViewProto (argType : Type , resultType : Type ) extends ViewProto (argType, resultType) {
@@ -522,7 +554,11 @@ object ProtoTypes {
522
554
def fold [T ](x : T , ta : TypeAccumulator [T ])(using Context ): T =
523
555
ta(ta.foldOver(x, targs.tpes), resultType)
524
556
525
- override def deepenProto (using Context ): PolyProto = derivedPolyProto(targs, resultType.deepenProto)
557
+ override def deepenProto (using Context ): PolyProto =
558
+ derivedPolyProto(targs, resultType.deepenProto)
559
+
560
+ override def deepenProtoTrans (using Context ): PolyProto =
561
+ derivedPolyProto(targs, resultType.deepenProtoTrans)
526
562
}
527
563
528
564
/** A prototype for expressions [] that are known to be functions:
0 commit comments