Skip to content

Commit

Permalink
Drop retains annotations in inferred type trees
Browse files Browse the repository at this point in the history
  • Loading branch information
Linyxus committed Apr 1, 2024
1 parent cc55381 commit f34ff5d
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 2 deletions.
10 changes: 10 additions & 0 deletions compiler/src/dotty/tools/dotc/cc/CaptureOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,16 @@ extension (tp: AnnotatedType)
case ann: CaptureAnnotation => ann.boxed
case _ => false

class CleanupRetains(using Context) extends TypeMap:
def apply(tp: Type): Type = cleanupRetains(tp, this)

/** Drop retains annotations in the type. */
def cleanupRetains(tp: Type, theMap: CleanupRetains | Null = null)(using Context): Type =
def mapOver = (if theMap != null then theMap else new CleanupRetains).mapOver(tp)
tp match
case RetainingType(tp, _) => tp
case _ => mapOver

/** An extractor for `caps.reachCapability(ref)`, which is used to express a reach
* capability as a tree in a @retains annotation.
*/
Expand Down
9 changes: 7 additions & 2 deletions compiler/src/dotty/tools/dotc/typer/Typer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ import staging.StagingLevel
import reporting.*
import Nullables.*
import NullOpsDecorator.*
import cc.{CheckCaptures, isRetainsLike}
import cc.{CheckCaptures, isRetainsLike, cleanupRetains}
import config.Config
import config.MigrationVersion

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

def typedInLambdaTypeTree(tree: untpd.InLambdaTypeTree, pt: Type)(using Context): Tree =
val tp =
Expand Down
11 changes: 11 additions & 0 deletions tests/pos-custom-args/captures/tablediff.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import language.experimental.captureChecking

trait Seq[+A]:
def zipAll[A1 >: A, B](that: Seq[B]^, thisElem: A1, thatElem: B): Seq[(A1, B)]^{this, that}
def map[B](f: A => B): Seq[B]^{this, f}

def zipAllOption[X](left: Seq[X], right: Seq[X]) =
left.map(Option(_)).zipAll(right.map(Option(_)), None, None)

def fillRow[T](headRow: Seq[T], tailRow: Seq[T]) =
val paddedZip = zipAllOption(headRow, tailRow)

0 comments on commit f34ff5d

Please sign in to comment.