Skip to content

Commit c3469da

Browse files
authored
Merge pull request #4622 from dotty-staging/add-transparent-2
Add transparent methods
2 parents 0f43132 + b359c7d commit c3469da

22 files changed

+192
-105
lines changed

compiler/src/dotty/tools/dotc/ast/TreeInfo.scala

+1
Original file line numberDiff line numberDiff line change
@@ -551,6 +551,7 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] =>
551551
/** An extractor for def of a closure contained the block of the closure. */
552552
object closureDef {
553553
def unapply(tree: Tree): Option[DefDef] = tree match {
554+
case Block(Nil, expr) => unapply(expr)
554555
case Block((meth @ DefDef(nme.ANON_FUN, _, _, _, _)) :: Nil, closure: Closure) =>
555556
Some(meth)
556557
case _ => None

compiler/src/dotty/tools/dotc/ast/untpd.scala

+2
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,8 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
132132

133133
case class Inline() extends Mod(Flags.Inline)
134134

135+
case class Transparent() extends Mod(Flags.Transparent)
136+
135137
case class Enum() extends Mod(Flags.Enum)
136138
}
137139

compiler/src/dotty/tools/dotc/core/Flags.scala

+17-8
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,10 @@ object Flags {
363363
/** Symbol is a Java default method */
364364
final val DefaultMethod = termFlag(38, "<defaultmethod>")
365365

366-
/** Symbol is a Java enum */
366+
/** Labelled with `transparent` modifier */
367+
final val Transparent = termFlag(39, "transparent")
368+
369+
/** Symbol is an enum class or enum case (if used with case) */
367370
final val Enum = commonFlag(40, "<enum>")
368371

369372
/** Labeled with `erased` modifier (erased value) */
@@ -436,7 +439,7 @@ object Flags {
436439

437440
/** Flags representing source modifiers */
438441
final val SourceModifierFlags =
439-
commonFlags(Private, Protected, Abstract, Final, Inline,
442+
commonFlags(Private, Protected, Abstract, Final, Inline, Transparent,
440443
Sealed, Case, Implicit, Override, AbsOverride, Lazy, JavaStatic, Erased)
441444

442445
/** Flags representing modifiers that can appear in trees */
@@ -457,7 +460,7 @@ object Flags {
457460
Scala2ExistentialCommon | Mutable.toCommonFlags | Touched | JavaStatic |
458461
CovariantOrOuter | ContravariantOrLabel | CaseAccessor.toCommonFlags |
459462
NonMember | ImplicitCommon | Permanent | Synthetic |
460-
SuperAccessorOrScala2x | Inline
463+
SuperAccessorOrScala2x | Inline | Transparent.toCommonFlags
461464

462465
/** Flags that are not (re)set when completing the denotation, or, if symbol is
463466
* a top-level class or object, when completing the denotation once the class
@@ -513,7 +516,7 @@ object Flags {
513516
/** Flags that can apply to a module val */
514517
final val RetainedModuleValFlags: FlagSet = RetainedModuleValAndClassFlags |
515518
Override | Final | Method | Implicit | Lazy |
516-
Accessor | AbsOverride | Stable | Captured | Synchronized | Inline | Erased
519+
Accessor | AbsOverride | Stable | Captured | Synchronized | Erased
517520

518521
/** Flags that can apply to a module class */
519522
final val RetainedModuleClassFlags: FlagSet = RetainedModuleValAndClassFlags | ImplClass | Enum
@@ -548,8 +551,8 @@ object Flags {
548551
/** Either method or lazy or deferred */
549552
final val MethodOrLazyOrDeferred = Method | Lazy | Deferred
550553

551-
/** Labeled `private`, `final`, or `inline` */
552-
final val PrivateOrFinalOrInline = Private | Final | Inline
554+
/** Labeled `private`, `final`, `inline`, or `transparent` */
555+
final val EffectivelyFinal = Private | Final | Inline | Transparent.toCommonFlags
553556

554557
/** A private method */
555558
final val PrivateMethod = allOf(Private, Method)
@@ -560,6 +563,9 @@ object Flags {
560563
/** An inline method */
561564
final val InlineMethod = allOf(Inline, Method)
562565

566+
/** An transparent method */
567+
final val TransparentMethod = allOf(Transparent, Method)
568+
563569
/** An inline parameter */
564570
final val InlineParam = allOf(Inline, Param)
565571

@@ -575,6 +581,9 @@ object Flags {
575581
/** An accessor or label */
576582
final val AccessorOrLabel = Accessor | Label
577583

584+
/** An accessor or a synthetic symbol */
585+
final val AccessorOrSynthetic = Accessor | Synthetic
586+
578587
/** A synthetic or private definition */
579588
final val SyntheticOrPrivate = Synthetic | Private
580589

@@ -584,8 +593,8 @@ object Flags {
584593
/** A deferred type member or parameter (these don't have right hand sides) */
585594
final val DeferredOrTypeParam = Deferred | TypeParam
586595

587-
/** value that's final or inline */
588-
final val FinalOrInline = Final | Inline
596+
/** value that's final, inline, or transparent */
597+
final val FinalOrInlineOrTransparent = Final | Inline | Transparent.toCommonFlags
589598

590599
/** A covariant type parameter instance */
591600
final val LocalCovariant = allOf(Local, Covariant)

compiler/src/dotty/tools/dotc/core/Mode.scala

-1
Original file line numberDiff line numberDiff line change
@@ -93,5 +93,4 @@ object Mode {
9393

9494
/** We are in the IDE */
9595
val Interactive = newMode(20, "Interactive")
96-
9796
}

compiler/src/dotty/tools/dotc/core/SymDenotations.scala

+8-2
Original file line numberDiff line numberDiff line change
@@ -779,7 +779,13 @@ object SymDenotations {
779779

780780
def isSkolem: Boolean = name == nme.SKOLEM
781781

782-
def isInlineMethod(implicit ctx: Context): Boolean = is(InlineMethod, butNot = Accessor)
782+
def isInlinedMethod(implicit ctx: Context): Boolean =
783+
is(InlineMethod, butNot = Accessor)
784+
785+
def isTransparentMethod(implicit ctx: Context): Boolean =
786+
is(TransparentMethod, butNot = Accessor)
787+
788+
def isInlineableMethod(implicit ctx: Context) = isInlinedMethod || isTransparentMethod
783789

784790
/** ()T and => T types should be treated as equivalent for this symbol.
785791
* Note: For the moment, we treat Scala-2 compiled symbols as loose matching,
@@ -905,7 +911,7 @@ object SymDenotations {
905911

906912
/** A symbol is effectively final if it cannot be overridden in a subclass */
907913
final def isEffectivelyFinal(implicit ctx: Context): Boolean =
908-
is(PrivateOrFinalOrInline) || !owner.isClass || owner.is(ModuleOrFinal) || owner.isAnonymousClass
914+
is(EffectivelyFinal) || !owner.isClass || owner.is(ModuleOrFinal) || owner.isAnonymousClass
909915

910916
/** The class containing this denotation which has the given effective name. */
911917
final def enclosingClassNamed(name: Name)(implicit ctx: Context): Symbol = {

compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala

+24-20
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,8 @@ Standard-Section: "ASTs" TopLevelStat*
179179
ERASED
180180
LAZY
181181
OVERRIDE
182-
INLINE // inline method
182+
INLINE
183+
TRANSPARENT
183184
MACRO // inline method containing toplevel splices
184185
STATIC // mapped to static Java member
185186
OBJECT // an object or its class
@@ -280,25 +281,26 @@ object TastyFormat {
280281
final val LAZY = 14
281282
final val OVERRIDE = 15
282283
final val INLINE = 16
283-
final val STATIC = 17
284-
final val OBJECT = 18
285-
final val TRAIT = 19
286-
final val ENUM = 20
287-
final val LOCAL = 21
288-
final val SYNTHETIC = 22
289-
final val ARTIFACT = 23
290-
final val MUTABLE = 24
291-
final val LABEL = 25
292-
final val FIELDaccessor = 26
293-
final val CASEaccessor = 27
294-
final val COVARIANT = 28
295-
final val CONTRAVARIANT = 29
296-
final val SCALA2X = 30
297-
final val DEFAULTparameterized = 31
298-
final val STABLE = 32
299-
final val MACRO = 33
300-
final val ERASED = 34
301-
final val PARAMsetter = 35
284+
final val TRANSPARENT = 17
285+
final val STATIC = 18
286+
final val OBJECT = 19
287+
final val TRAIT = 20
288+
final val ENUM = 21
289+
final val LOCAL = 22
290+
final val SYNTHETIC = 23
291+
final val ARTIFACT = 24
292+
final val MUTABLE = 25
293+
final val LABEL = 26
294+
final val FIELDaccessor = 27
295+
final val CASEaccessor = 28
296+
final val COVARIANT = 29
297+
final val CONTRAVARIANT = 30
298+
final val SCALA2X = 31
299+
final val DEFAULTparameterized = 32
300+
final val STABLE = 33
301+
final val MACRO = 34
302+
final val ERASED = 35
303+
final val PARAMsetter = 36
302304

303305
// Cat. 2: tag Nat
304306

@@ -446,6 +448,7 @@ object TastyFormat {
446448
| LAZY
447449
| OVERRIDE
448450
| INLINE
451+
| TRANSPARENT
449452
| MACRO
450453
| STATIC
451454
| OBJECT
@@ -502,6 +505,7 @@ object TastyFormat {
502505
case LAZY => "LAZY"
503506
case OVERRIDE => "OVERRIDE"
504507
case INLINE => "INLINE"
508+
case TRANSPARENT => "TRANSPARENT"
505509
case MACRO => "MACRO"
506510
case STATIC => "STATIC"
507511
case OBJECT => "OBJECT"

compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala

+1
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,7 @@ class TreePickler(pickler: TastyPickler) {
589589
if (flags is Case) writeByte(CASE)
590590
if (flags is Override) writeByte(OVERRIDE)
591591
if (flags is Inline) writeByte(INLINE)
592+
if (flags is Transparent) writeByte(TRANSPARENT)
592593
if (flags is Macro) writeByte(MACRO)
593594
if (flags is JavaStatic) writeByte(STATIC)
594595
if (flags is Module) writeByte(OBJECT)

compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala

+20-15
Original file line numberDiff line numberDiff line change
@@ -513,7 +513,7 @@ class TreeUnpickler(reader: TastyReader,
513513
val rhsStart = currentAddr
514514
val rhsIsEmpty = nothingButMods(end)
515515
if (!rhsIsEmpty) skipTree()
516-
val (givenFlags, annots, privateWithin) = readModifiers(end)
516+
val (givenFlags, annotFns, privateWithin) = readModifiers(end)
517517
pickling.println(i"creating symbol $name at $start with flags $givenFlags")
518518
val flags = normalizeFlags(tag, givenFlags, name, isAbsType, rhsIsEmpty)
519519
def adjustIfModule(completer: LazyType) =
@@ -532,13 +532,12 @@ class TreeUnpickler(reader: TastyReader,
532532
rootd.symbol
533533
case _ =>
534534
val completer = adjustIfModule(new Completer(ctx.owner, subReader(start, end)))
535-
536535
if (isClass)
537536
ctx.newClassSymbol(ctx.owner, name.asTypeName, flags, completer, privateWithin, coord)
538537
else
539538
ctx.newSymbol(ctx.owner, name, flags, completer, privateWithin, coord)
540539
}
541-
sym.annotations = annots
540+
sym.annotations = annotFns.map(_(sym))
542541
ctx.owner match {
543542
case cls: ClassSymbol => cls.enter(sym)
544543
case _ =>
@@ -548,7 +547,7 @@ class TreeUnpickler(reader: TastyReader,
548547
sym.completer.withDecls(newScope)
549548
forkAt(templateStart).indexTemplateParams()(localContext(sym))
550549
}
551-
else if (sym.isInlineMethod)
550+
else if (sym.isInlineableMethod)
552551
sym.addAnnotation(LazyBodyAnnotation { ctx0 =>
553552
implicit val ctx: Context = localContext(sym)(ctx0).addMode(Mode.ReadPositions)
554553
// avoids space leaks by not capturing the current context
@@ -561,9 +560,9 @@ class TreeUnpickler(reader: TastyReader,
561560
/** Read modifier list into triplet of flags, annotations and a privateWithin
562561
* boundary symbol.
563562
*/
564-
def readModifiers(end: Addr)(implicit ctx: Context): (FlagSet, List[Annotation], Symbol) = {
563+
def readModifiers(end: Addr)(implicit ctx: Context): (FlagSet, List[Symbol => Annotation], Symbol) = {
565564
var flags: FlagSet = EmptyFlags
566-
var annots: List[Annotation] = Nil
565+
var annotFns: List[Symbol => Annotation] = Nil
567566
var privateWithin: Symbol = NoSymbol
568567
while (currentAddr.index != end.index) {
569568
def addFlag(flag: FlagSet) = {
@@ -588,6 +587,7 @@ class TreeUnpickler(reader: TastyReader,
588587
case LAZY => addFlag(Lazy)
589588
case OVERRIDE => addFlag(Override)
590589
case INLINE => addFlag(Inline)
590+
case TRANSPARENT => addFlag(Transparent)
591591
case MACRO => addFlag(Macro)
592592
case STATIC => addFlag(JavaStatic)
593593
case OBJECT => addFlag(Module)
@@ -614,23 +614,25 @@ class TreeUnpickler(reader: TastyReader,
614614
addFlag(Protected)
615615
privateWithin = readType().typeSymbol
616616
case ANNOTATION =>
617-
annots = readAnnot(ctx) :: annots
617+
annotFns = readAnnot(ctx) :: annotFns
618618
case tag =>
619619
assert(false, s"illegal modifier tag $tag at $currentAddr, end = $end")
620620
}
621621
}
622-
(flags, annots.reverse, privateWithin)
622+
(flags, annotFns.reverse, privateWithin)
623623
}
624624

625-
private val readAnnot: Context => Annotation = {
625+
private val readAnnot: Context => Symbol => Annotation = {
626626
implicit ctx =>
627627
readByte()
628628
val end = readEnd()
629629
val tp = readType()
630-
val lazyAnnotTree = readLater(end, rdr => ctx => rdr.readTerm()(ctx))
631-
Annotation.deferredSymAndTree(
632-
implicit ctx => tp.typeSymbol,
633-
implicit ctx => lazyAnnotTree.complete)
630+
val lazyAnnotTree = readLaterWithOwner(end, rdr => ctx => rdr.readTerm()(ctx))
631+
632+
owner =>
633+
Annotation.deferredSymAndTree(
634+
implicit ctx => tp.typeSymbol,
635+
implicit ctx => lazyAnnotTree(owner).complete)
634636
}
635637

636638
/** Create symbols for the definitions in the statement sequence between
@@ -1153,10 +1155,13 @@ class TreeUnpickler(reader: TastyReader,
11531155
setPos(start, CaseDef(pat, guard, rhs))
11541156
}
11551157

1156-
def readLater[T <: AnyRef](end: Addr, op: TreeReader => Context => T)(implicit ctx: Context): Trees.Lazy[T] = {
1158+
def readLater[T <: AnyRef](end: Addr, op: TreeReader => Context => T)(implicit ctx: Context): Trees.Lazy[T] =
1159+
readLaterWithOwner(end, op)(ctx)(ctx.owner)
1160+
1161+
def readLaterWithOwner[T <: AnyRef](end: Addr, op: TreeReader => Context => T)(implicit ctx: Context): Symbol => Trees.Lazy[T] = {
11571162
val localReader = fork
11581163
goto(end)
1159-
new LazyReader(localReader, ctx.owner, ctx.mode, op)
1164+
owner => new LazyReader(localReader, owner, ctx.mode, op)
11601165
}
11611166

11621167
def readHole(end: Addr, isType: Boolean)(implicit ctx: Context): Tree = {

compiler/src/dotty/tools/dotc/parsing/Parsers.scala

+11-10
Original file line numberDiff line numberDiff line change
@@ -1675,16 +1675,17 @@ object Parsers {
16751675
/* -------- MODIFIERS and ANNOTATIONS ------------------------------------------- */
16761676

16771677
private def modOfToken(tok: Int): Mod = tok match {
1678-
case ABSTRACT => Mod.Abstract()
1679-
case FINAL => Mod.Final()
1680-
case IMPLICIT => Mod.Implicit()
1681-
case ERASED => Mod.Erased()
1682-
case INLINE => Mod.Inline()
1683-
case LAZY => Mod.Lazy()
1684-
case OVERRIDE => Mod.Override()
1685-
case PRIVATE => Mod.Private()
1686-
case PROTECTED => Mod.Protected()
1687-
case SEALED => Mod.Sealed()
1678+
case ABSTRACT => Mod.Abstract()
1679+
case FINAL => Mod.Final()
1680+
case IMPLICIT => Mod.Implicit()
1681+
case ERASED => Mod.Erased()
1682+
case INLINE => Mod.Inline()
1683+
case TRANSPARENT => Mod.Transparent()
1684+
case LAZY => Mod.Lazy()
1685+
case OVERRIDE => Mod.Override()
1686+
case PRIVATE => Mod.Private()
1687+
case PROTECTED => Mod.Protected()
1688+
case SEALED => Mod.Sealed()
16881689
}
16891690

16901691
/** Drop `private' modifier when followed by a qualifier.

compiler/src/dotty/tools/dotc/parsing/Tokens.scala

+4-3
Original file line numberDiff line numberDiff line change
@@ -176,8 +176,9 @@ object Tokens extends TokensCommon {
176176
final val THEN = 60; enter(THEN, "then")
177177
final val FORSOME = 61; enter(FORSOME, "forSome") // TODO: deprecate
178178
final val INLINE = 62; enter(INLINE, "inline")
179-
final val ENUM = 63; enter(ENUM, "enum")
180-
final val ERASED = 64; enter(ERASED, "erased")
179+
final val TRANSPARENT = 63; enter(TRANSPARENT, "transparent")
180+
final val ENUM = 64; enter(ENUM, "enum")
181+
final val ERASED = 65; enter(ERASED, "erased")
181182

182183
/** special symbols */
183184
final val NEWLINE = 78; enter(NEWLINE, "end of statement", "new line")
@@ -226,7 +227,7 @@ object Tokens extends TokensCommon {
226227
final val defIntroTokens = templateIntroTokens | dclIntroTokens
227228

228229
final val localModifierTokens = BitSet(
229-
ABSTRACT, FINAL, SEALED, IMPLICIT, INLINE, LAZY, ERASED)
230+
ABSTRACT, FINAL, SEALED, IMPLICIT, INLINE, TRANSPARENT, LAZY, ERASED)
230231

231232
final val accessModifierTokens = BitSet(
232233
PRIVATE, PROTECTED)

compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -612,7 +612,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
612612
}
613613

614614
private def toTextOwner(tree: Tree[_]) =
615-
"[owner = " ~ tree.symbol.owner.show ~ "]" provided ctx.settings.YprintDebugOwners.value
615+
"[owner = " ~ tree.symbol.maybeOwner.show ~ "]" provided ctx.settings.YprintDebugOwners.value
616616

617617
protected def dclTextOr[T >: Untyped](tree: Tree[T])(treeText: => Text) =
618618
toTextOwner(tree) ~ {

compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -1575,7 +1575,7 @@ object messages {
15751575
private val varNote =
15761576
if (sym.is(Mutable)) "Note that variables need to be initialized to be defined."
15771577
else ""
1578-
val msg = hl"""only classes can have declared but undefined members"""
1578+
val msg = hl"""declaration of $sym not allowed here: only classes can have declared but undefined members"""
15791579
val kind = "Syntax"
15801580
val explanation = s"$varNote"
15811581
}

compiler/src/dotty/tools/dotc/transform/PostTyper.scala

+1-5
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase
165165

166166
def markAsMacro(c: Context): Unit =
167167
if (c.owner eq c.outer.owner) markAsMacro(c.outer)
168-
else if (c.owner.isInlineMethod) c.owner.setFlag(Macro)
168+
else if (c.owner.isInlineableMethod) c.owner.setFlag(Macro)
169169
else if (!c.outer.owner.is(Package)) markAsMacro(c.outer)
170170

171171
if (sym.isSplice || sym.isQuote) {
@@ -192,10 +192,6 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase
192192
}
193193
else
194194
transformSelect(tree, Nil)
195-
case tree: Super =>
196-
if (ctx.owner.enclosingMethod.isInlineMethod)
197-
ctx.error(SuperCallsNotAllowedInline(ctx.owner), tree.pos)
198-
super.transform(tree)
199195
case tree: Apply =>
200196
methPart(tree) match {
201197
case Select(nu: New, nme.CONSTRUCTOR) if isCheckable(nu) =>

0 commit comments

Comments
 (0)