Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions compiler/src/dotty/tools/dotc/Compiler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ class Compiler {
new ElimStaticThis, // Replace `this` references to static objects by global identifiers
new CountOuterAccesses) :: // Identify outer accessors that can be dropped
List(new DropOuterAccessors, // Drop unused outer accessors
new DropParentRefinements, // Drop parent refinements from a template
new CheckNoSuperThis, // Check that supercalls don't contain references to `this`
new Flatten, // Lift all inner classes to package scope
new TransformWildcards, // Replace wildcards with default values
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package dotty.tools.dotc.transform

import dotty.tools.dotc.transform.MegaPhase.MiniPhase
import dotty.tools.dotc.ast.tpd
import dotty.tools.dotc.core.Contexts.Context
import dotty.tools.dotc.core.DenotTransformers.IdentityDenotTransformer
import dotty.tools.dotc.typer.Typer

object DropParentRefinements:
val name: String = "dropParentRefinements"
val description: String = "drop parent refinements from a template"

/** Drop parent refinements from a template. because they are generated without
* an implementation. These refinements are unusally required for tracked
* members with more specific types.
*/
class DropParentRefinements extends MiniPhase with IdentityDenotTransformer:
thisPhase =>
import tpd.*

override def phaseName: String = DropParentRefinements.name

override def description: String = DropParentRefinements.description

override def runsAfterGroupsOf: Set[String] = Set(CountOuterAccesses.name)

override def changesMembers: Boolean = true // the phase drops parent refinements

override def transformTemplate(tree: tpd.Template)(using Context): tpd.Tree =
val newBody = tree.body.filter(!_.hasAttachment(Typer.RefinementFromParent))
tree.body.foreach { member =>
if member.hasAttachment(Typer.RefinementFromParent) then
member.symbol.dropAfter(thisPhase)
}
cpy.Template(tree)(body = newBody)
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/transform/Getters.scala
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ class Getters extends MiniPhase with SymTransformer { thisPhase =>
override def transformValDef(tree: ValDef)(using Context): Tree =
val sym = tree.symbol
if !sym.is(Method) then return tree
val getterDef = DefDef(sym.asTerm, tree.rhs).withSpan(tree.span)
val getterDef = DefDef(sym.asTerm, tree.rhs).withSpan(tree.span).withAttachmentsFrom(tree)
if !sym.is(Mutable) then return getterDef
ensureSetter(sym.asTerm)
if !newSetters.contains(sym.setter) then return getterDef
Expand Down
8 changes: 4 additions & 4 deletions compiler/src/dotty/tools/dotc/typer/Namer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
5 changes: 4 additions & 1 deletion compiler/src/dotty/tools/dotc/typer/Typer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ object Typer {
/** An attachment for GADT constraints that were inferred for a pattern. */
val InferredGadtConstraints = new Property.StickyKey[core.GadtConstraint]

/** Inducates that a definition was copied over from the parent refinements */
val RefinementFromParent = new Property.StickyKey[Unit]

/** An attachment on a Select node with an `apply` field indicating that the `apply`
* was inserted by the Typer.
*/
Expand Down Expand Up @@ -3081,7 +3084,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
( if sym.isType then TypeDef(sym.asType)
else if sym.is(Method) then DefDef(sym.asTerm)
else ValDef(sym.asTerm)
).withSpan(impl.span.startPos)
).withSpan(impl.span.startPos).withAttachment(RefinementFromParent, ())
body ++ refinements
case None =>
body
Expand Down
1 change: 1 addition & 0 deletions tests/run/i21213-min.check
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
bar
9 changes: 9 additions & 0 deletions tests/run/i21213-min.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import scala.language.experimental.modularity
import scala.language.future

sealed abstract class Foo(tracked val discriminator: String)
class Bar extends Foo("bar")

val bar: Foo = Bar()
object Test extends App:
println(bar.discriminator)
1 change: 1 addition & 0 deletions tests/run/i21213.check
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
bar
10 changes: 10 additions & 0 deletions tests/run/i21213.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import scala.language.experimental.modularity
import scala.language.future

enum Foo(tracked val discriminator: String):
case Bar() extends Foo("bar")
case Baz() extends Foo("baz")

val bar: Foo = Foo.Bar()
object Test extends App:
println(bar.discriminator)
Loading