From d2b6a6186118309a9a2c1a2ad3336b5785828e07 Mon Sep 17 00:00:00 2001 From: Kacper Korban Date: Mon, 14 Oct 2024 10:33:52 +0200 Subject: [PATCH] Fix handling tracked param accessors --- .../src/dotty/tools/dotc/ast/Desugar.scala | 6 ++++-- .../src/dotty/tools/dotc/typer/Namer.scala | 8 +++---- .../src/dotty/tools/dotc/typer/Typer.scala | 4 ++-- tests/neg/abstract-tracked.check | 21 ++++++++++++++++--- tests/neg/abstract-tracked.scala | 13 ++++++++++-- tests/pos/abstract-tracked.scala | 15 +++++++++++++ 6 files changed, 54 insertions(+), 13 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/ast/Desugar.scala b/compiler/src/dotty/tools/dotc/ast/Desugar.scala index dac22068ff2e..43d21731887a 100644 --- a/compiler/src/dotty/tools/dotc/ast/Desugar.scala +++ b/compiler/src/dotty/tools/dotc/ast/Desugar.scala @@ -1481,8 +1481,10 @@ object desugar { rhsOK(rhs) } - val legalTracked: MemberDefTest = { - case ValDef(_, _, _) => true + val legalTracked: Context ?=> MemberDefTest = { + case valdef @ ValDef(_, _, _) => + val sym = valdef.symbol + ctx.owner.exists && (ctx.owner.isClass || ctx.owner.isConstructor) } def checkOpaqueAlias(tree: MemberDef)(using Context): MemberDef = diff --git a/compiler/src/dotty/tools/dotc/typer/Namer.scala b/compiler/src/dotty/tools/dotc/typer/Namer.scala index 6167db62fbe0..0849e57b8c7d 100644 --- a/compiler/src/dotty/tools/dotc/typer/Namer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Namer.scala @@ -877,16 +877,16 @@ class Namer { typer: Typer => protected def addAnnotations(sym: Symbol): Unit = original match { case original: untpd.MemberDef => lazy val annotCtx = annotContext(original, sym) - original.setMods: + original.setMods: original.mods.withAnnotations : - original.mods.annotations.mapConserve: annotTree => + original.mods.annotations.mapConserve: annotTree => val cls = typedAheadAnnotationClass(annotTree)(using annotCtx) if (cls eq sym) report.error(em"An annotation class cannot be annotated with iself", annotTree.srcPos) annotTree else - val ann = - if cls.is(JavaDefined) then Checking.checkNamedArgumentForJavaAnnotation(annotTree, cls.asClass) + val ann = + if cls.is(JavaDefined) then Checking.checkNamedArgumentForJavaAnnotation(annotTree, cls.asClass) else annotTree val ann1 = Annotation.deferred(cls)(typedAheadExpr(ann)(using annotCtx)) sym.addAnnotation(ann1) diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index 159c312d1225..74735a8b50c1 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -2835,14 +2835,14 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer excludeDeferredGiven(rhs, sym): typedExpr(_, tpt1.tpe.widenExpr) setAbstractTrackedInfo(sym, rhs1, tpt) - val tpt2 = if tpt.isEmpty then TypeTree(rhs1.tpe) else tpt1 + val tpt2 = if sym.flags.is(Tracked) && tpt.isEmpty && !sym.flags.is(ParamAccessor) 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 + if sym.allOverriddenSymbols.exists(_.flags.is(Tracked)) && !sym.flags.is(ParamAccessor) then sym.setFlag(Tracked) if tpt.isEmpty then sym.info = rhs.tpe diff --git a/tests/neg/abstract-tracked.check b/tests/neg/abstract-tracked.check index 5e0e641fff69..70a85e81df85 100644 --- a/tests/neg/abstract-tracked.check +++ b/tests/neg/abstract-tracked.check @@ -1,5 +1,20 @@ -- [E156] Syntax Error: tests/neg/abstract-tracked.scala:4:14 ---------------------------------------------------------- -4 |tracked trait F: // error - |^ +4 |tracked trait F // error + |^^^^^^^^^^^^^^^ |Modifier tracked is not allowed for this definition -5 | val x: Int +-- [E156] Syntax Error: tests/neg/abstract-tracked.scala:9:15 ---------------------------------------------------------- +9 |tracked object O // error + |^^^^^^^^^^^^^^^^ + |Modifier tracked is not allowed for this definition +-- [E156] Syntax Error: tests/neg/abstract-tracked.scala:11:14 --------------------------------------------------------- +11 |tracked class C // error + |^^^^^^^^^^^^^^^ + |Modifier tracked is not allowed for this definition +-- [E156] Syntax Error: tests/neg/abstract-tracked.scala:7:14 ---------------------------------------------------------- +7 | tracked def f: F // error + | ^^^^^^^^^^^^^^^^ + | Modifier tracked is not allowed for this definition +-- [E156] Syntax Error: tests/neg/abstract-tracked.scala:14:14 --------------------------------------------------------- +14 | tracked val x = 1 // error + | ^^^^^^^^^^^^^^^^^ + | Modifier tracked is not allowed for this definition diff --git a/tests/neg/abstract-tracked.scala b/tests/neg/abstract-tracked.scala index ad52243afd1a..ff4a7ea8174f 100644 --- a/tests/neg/abstract-tracked.scala +++ b/tests/neg/abstract-tracked.scala @@ -1,5 +1,14 @@ import scala.language.experimental.modularity import scala.language.future -tracked trait F: // error - val x: Int +tracked trait F // error + +trait G: + tracked def f: F // error + +tracked object O // error + +tracked class C // error + +def f = + tracked val x = 1 // error diff --git a/tests/pos/abstract-tracked.scala b/tests/pos/abstract-tracked.scala index cc6f824ed38f..fa6960894b75 100644 --- a/tests/pos/abstract-tracked.scala +++ b/tests/pos/abstract-tracked.scala @@ -10,6 +10,13 @@ trait G: trait H: tracked val z: Int = 3 +trait I extends F + +trait J extends F: + val x: Int = 1 + +class K(tracked val x: Int) + object Test: // val f : F(1) /*: F { val x: 1 }*/ = new F: // val x: 1 = 1 @@ -19,7 +26,15 @@ object Test: val y: 2 = 2 val h = new H: override val z = 4 + val i = new I: + val x = 5 + val j = new J: + override val x = 6 + val k = new K(7) summon[f.x.type <:< 1] summon[g.y.type <:< 2] summon[h.z.type <:< 4] + summon[i.x.type <:< 5] + summon[j.x.type <:< 6] + summon[k.x.type <:< 7]