Skip to content

Commit dbb9db5

Browse files
committed
Refactor type parameter widening
1 parent 825f0e9 commit dbb9db5

File tree

1 file changed

+12
-9
lines changed

1 file changed

+12
-9
lines changed

compiler/src/dotty/tools/dotc/cc/CheckCaptures.scala

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1310,12 +1310,14 @@ class CheckCaptures extends Recheck, SymTransformer:
13101310
testAdapted(actual, expected, tree, addenda)(err.typeMismatch)
13111311

13121312
@annotation.tailrec
1313-
private def widenNamed(tp: Type)(using Context): Type = tp match
1314-
case stp: SingletonType => widenNamed(stp.widen)
1315-
case ntp: NamedType => ntp.info match
1316-
case info: TypeBounds => widenNamed(info.hi)
1317-
case _ => tp
1318-
case _ => tp
1313+
private def findImpureUpperBound(tp: Type)(using Context): Type = tp match
1314+
case _: SingletonType => findImpureUpperBound(tp.widen)
1315+
case tp: TypeRef if tp.symbol.isAbstractOrParamType =>
1316+
tp.info match
1317+
case TypeBounds(_, hi) if hi.isBoxedCapturing => hi
1318+
case TypeBounds(_, hi) => findImpureUpperBound(hi)
1319+
case _ => NoType
1320+
case _ => NoType
13191321

13201322
inline def testAdapted(actual: Type, expected: Type, tree: Tree, addenda: Addenda)
13211323
(fail: (Tree, Type, Addenda) => Unit)(using Context): Type =
@@ -1332,7 +1334,8 @@ class CheckCaptures extends Recheck, SymTransformer:
13321334
//
13331335
// Therefore, when the expected type is a selection proto, we conservatively widen
13341336
// the actual type to strip type parameters.
1335-
widenNamed(actual)
1337+
val hi = findImpureUpperBound(actual)
1338+
if !hi.exists then actual else hi
13361339
else actual
13371340
val actualBoxed = adapt(actual1, expected1, tree)
13381341
//println(i"check conforms $actualBoxed <<< $expected1")
@@ -1357,8 +1360,8 @@ class CheckCaptures extends Recheck, SymTransformer:
13571360
* In those cases, we widen such types and try box adaptation another time.
13581361
*/
13591362
def tryWidenNamed: Boolean =
1360-
val actual1 = widenNamed(actual)
1361-
(actual1 ne actual) && {
1363+
val actual1 = findImpureUpperBound(actual)
1364+
actual1.exists && {
13621365
val actualBoxed1 = adapt(actual1, expected1, tree)
13631366
isCompatible(actualBoxed1, expected1)
13641367
}

0 commit comments

Comments
 (0)