Skip to content

Commit

Permalink
First draft of abstract tracked vals
Browse files Browse the repository at this point in the history
  • Loading branch information
KacperFKorban committed Oct 10, 2024
1 parent cd3bd1d commit 6465291
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 11 deletions.
5 changes: 3 additions & 2 deletions compiler/src/dotty/tools/dotc/ast/Desugar.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1007,12 +1007,13 @@ object desugar {
if mods.isAllOf(Given | Inline | Transparent) then
report.error("inline given instances cannot be trasparent", cdef)
var classMods = if mods.is(Given) then mods &~ (Inline | Transparent) | Synthetic else mods
if vparamAccessors.exists(_.mods.is(Tracked)) then
val newBody = tparamAccessors ::: vparamAccessors ::: normalizedBody ::: caseClassMeths
if newBody.collect { case d: ValOrDefDef => d }.exists(_.mods.is(Tracked)) then
classMods |= Dependent
cpy.TypeDef(cdef: TypeDef)(
name = className,
rhs = cpy.Template(impl)(constr, parents1, clsDerived, self1,
tparamAccessors ::: vparamAccessors ::: normalizedBody ::: caseClassMeths)
newBody)
).withMods(classMods)
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/parsing/Tokens.scala
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ object Tokens extends TokensCommon {

final val closingParens = BitSet(RPAREN, RBRACKET, RBRACE)

final val softModifierNames = Set(nme.inline, nme.into, nme.opaque, nme.open, nme.transparent, nme.infix)
final val softModifierNames = Set(nme.inline, nme.into, nme.opaque, nme.open, nme.transparent, nme.infix, nme.tracked)

def showTokenDetailed(token: Int): String = debugString(token)

Expand Down
28 changes: 20 additions & 8 deletions compiler/src/dotty/tools/dotc/typer/Typer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1426,7 +1426,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
index(stats)
typedStats(stats, ctx.owner)

def typedBlock(tree: untpd.Block, pt: Type)(using Context): Tree = {
def typedBlock(tree: untpd.Block, pt: Type)(using Context): Tree = trace.force(i"typing block $tree, pt = $pt") {
val (stats1, exprCtx) = withoutMode(Mode.Pattern) {
typedBlockStats(tree.stats)
}
Expand Down Expand Up @@ -2411,7 +2411,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
else if ctx.reporter.errorsReported then UnspecifiedErrorType
else errorType(em"cannot infer type; expected type $pt is not fully defined", tree.srcPos))

def typedTypeTree(tree: untpd.TypeTree, pt: Type)(using Context): Tree =
def typedTypeTree(tree: untpd.TypeTree, pt: Type)(using Context): Tree = trace.force(s"typedTypeTree $tree: $pt") {
tree match
case tree: untpd.DerivedTypeTree =>
tree.ensureCompletions
Expand All @@ -2427,6 +2427,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
}
case _ =>
completeTypeTree(InferredTypeTree(), pt, tree)
}

def typedInLambdaTypeTree(tree: untpd.InLambdaTypeTree, pt: Type)(using Context): Tree =
val tp =
Expand Down Expand Up @@ -2820,7 +2821,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
case _ =>
typed(rhs)

def typedValDef(vdef: untpd.ValDef, sym: Symbol)(using Context): Tree = {
def typedValDef(vdef: untpd.ValDef, sym: Symbol)(using Context): Tree = trace.force(i"typed val def $vdef, sym = $sym") {
val ValDef(name, tpt, _) = vdef
checkNonRootName(vdef.name, vdef.nameSpan)
completeAnnotations(vdef, sym)
Expand All @@ -2833,11 +2834,20 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
case rhs =>
excludeDeferredGiven(rhs, sym):
typedExpr(_, tpt1.tpe.widenExpr)
val vdef1 = assignType(cpy.ValDef(vdef)(name, tpt1, rhs1), sym)
postProcessInfo(vdef1, sym)
vdef1.setDefTree
setAbstractTrackedInfo(sym, rhs1, tpt)
val tpt2 = if tpt.isEmpty then TypeTree(rhs1.tpe) else tpt1
val vdef2 = assignType(cpy.ValDef(vdef)(name, tpt2, rhs1), sym)
postProcessInfo(vdef2, sym)
vdef2.setDefTree
}

private def setAbstractTrackedInfo(sym: Symbol, rhs: Tree, tpt: untpd.Tree)(using Context): Unit =
if sym.allOverriddenSymbols.exists(_.flags.is(Tracked)) then
sym.setFlag(Tracked)
if tpt.isEmpty then
sym.info = rhs.tpe


private def retractDefDef(sym: Symbol)(using Context): Tree =
// it's a discarded method (synthetic case class method or synthetic java record constructor or overridden member), drop it
val canBeInvalidated: Boolean =
Expand Down Expand Up @@ -3628,7 +3638,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
}

/** Typecheck and adapt tree, returning a typed tree. Parameters as for `typedUnadapted` */
def typed(tree: untpd.Tree, pt: Type, locked: TypeVars)(using Context): Tree =
def typed(tree: untpd.Tree, pt: Type, locked: TypeVars)(using Context): Tree = trace.force(i"typing $tree", typr) {
trace(i"typing $tree, pt = $pt", typr, show = true) {
record(s"typed $getClass")
record("typed total")
Expand All @@ -3640,6 +3650,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
tree.withType(WildcardType)
else adapt(typedUnadapted(tree, pt, locked), pt, locked)
}
}

def typed(tree: untpd.Tree, pt: Type = WildcardType)(using Context): Tree =
typed(tree, pt, ctx.typerState.ownedVars)
Expand Down Expand Up @@ -3755,7 +3766,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
def typedExpr(tree: untpd.Tree, pt: Type = WildcardType)(using Context): Tree =
withoutMode(Mode.PatternOrTypeBits)(typed(tree, pt))

def typedType(tree: untpd.Tree, pt: Type = WildcardType, mapPatternBounds: Boolean = false)(using Context): Tree =
def typedType(tree: untpd.Tree, pt: Type = WildcardType, mapPatternBounds: Boolean = false)(using Context): Tree = trace.force(i"typing type $tree, pt = $pt") {
val tree1 = withMode(Mode.Type) { typed(tree, pt) }
if mapPatternBounds && ctx.mode.is(Mode.Pattern) && !ctx.isAfterTyper then
tree1 match
Expand All @@ -3771,6 +3782,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
case tree1 =>
tree1
else tree1
}

def typedPattern(tree: untpd.Tree, selType: Type = WildcardType)(using Context): Tree =
withMode(Mode.Pattern)(typed(tree, selType))
Expand Down
19 changes: 19 additions & 0 deletions tests/pos/abstract-tracked.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import scala.language.experimental.modularity
import scala.language.future

trait F:
tracked val x: Int

trait G:
tracked val y: Int

object Test:
// val f : F(1) /*: F { val x: 1 }*/ = new F:
// val x: 1 = 1
val f = new F:
val x = 1
val g = new G:
val y: 2 = 2

summon[f.x.type <:< 1]
summon[g.y.type <:< 2]

0 comments on commit 6465291

Please sign in to comment.