Skip to content

Commit f34ff5d

Browse files
committed
Drop retains annotations in inferred type trees
1 parent cc55381 commit f34ff5d

File tree

3 files changed

+28
-2
lines changed

3 files changed

+28
-2
lines changed

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,16 @@ extension (tp: AnnotatedType)
445445
case ann: CaptureAnnotation => ann.boxed
446446
case _ => false
447447

448+
class CleanupRetains(using Context) extends TypeMap:
449+
def apply(tp: Type): Type = cleanupRetains(tp, this)
450+
451+
/** Drop retains annotations in the type. */
452+
def cleanupRetains(tp: Type, theMap: CleanupRetains | Null = null)(using Context): Type =
453+
def mapOver = (if theMap != null then theMap else new CleanupRetains).mapOver(tp)
454+
tp match
455+
case RetainingType(tp, _) => tp
456+
case _ => mapOver
457+
448458
/** An extractor for `caps.reachCapability(ref)`, which is used to express a reach
449459
* capability as a tree in a @retains annotation.
450460
*/

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

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ import staging.StagingLevel
4848
import reporting.*
4949
import Nullables.*
5050
import NullOpsDecorator.*
51-
import cc.{CheckCaptures, isRetainsLike}
51+
import cc.{CheckCaptures, isRetainsLike, cleanupRetains}
5252
import config.Config
5353
import config.MigrationVersion
5454

@@ -2187,7 +2187,12 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
21872187
errorTree(tree, em"Something's wrong: missing original symbol for type tree")
21882188
}
21892189
case _ =>
2190-
completeTypeTree(InferredTypeTree(), pt, tree)
2190+
val pt1 = cleanupRetains(pt)
2191+
// Cleans up retains annotations in inferred type trees. This is needed because
2192+
// during the typer, it is infeasible to correctly infer the capture sets in most
2193+
// cases, resulting ill-formed capture sets that could crash the pickler later on.
2194+
// See #20035.
2195+
completeTypeTree(InferredTypeTree(), pt1, tree)
21912196

21922197
def typedInLambdaTypeTree(tree: untpd.InLambdaTypeTree, pt: Type)(using Context): Tree =
21932198
val tp =
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import language.experimental.captureChecking
2+
3+
trait Seq[+A]:
4+
def zipAll[A1 >: A, B](that: Seq[B]^, thisElem: A1, thatElem: B): Seq[(A1, B)]^{this, that}
5+
def map[B](f: A => B): Seq[B]^{this, f}
6+
7+
def zipAllOption[X](left: Seq[X], right: Seq[X]) =
8+
left.map(Option(_)).zipAll(right.map(Option(_)), None, None)
9+
10+
def fillRow[T](headRow: Seq[T], tailRow: Seq[T]) =
11+
val paddedZip = zipAllOption(headRow, tailRow)

0 commit comments

Comments
 (0)