Skip to content

Commit 5a62261

Browse files
committed
Allow erased on classes
1 parent 53793ae commit 5a62261

File tree

14 files changed

+107
-25
lines changed

14 files changed

+107
-25
lines changed

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -360,8 +360,8 @@ object Flags {
360360
/** An export forwarder */
361361
val (Exported @ _, _, _) = newFlags(41, "exported")
362362

363-
/** Labeled with `erased` modifier (erased value) */
364-
val (_, Erased @ _, _) = newFlags(42, "erased")
363+
/** Labeled with `erased` modifier (erased value or class) */
364+
val (Erased @ _, _, _) = newFlags(42, "erased")
365365

366366
/** An opaque type alias or a class containing one */
367367
val (Opaque @ _, _, _) = newFlags(43, "opaque")
@@ -439,13 +439,13 @@ object Flags {
439439

440440
/** Flags representing source modifiers */
441441
private val CommonSourceModifierFlags: FlagSet =
442-
commonFlags(Private, Protected, Final, Case, Implicit, Given, Override, JavaStatic, Transparent)
442+
commonFlags(Private, Protected, Final, Case, Implicit, Given, Override, JavaStatic, Transparent, Erased)
443443

444444
val TypeSourceModifierFlags: FlagSet =
445445
CommonSourceModifierFlags.toTypeFlags | Abstract | Sealed | Opaque | Open
446446

447447
val TermSourceModifierFlags: FlagSet =
448-
CommonSourceModifierFlags.toTermFlags | Inline | AbsOverride | Lazy | Erased
448+
CommonSourceModifierFlags.toTermFlags | Inline | AbsOverride | Lazy
449449

450450
/** Flags representing modifiers that can appear in trees */
451451
val ModifierFlags: FlagSet =
@@ -515,12 +515,12 @@ object Flags {
515515
val RetainedModuleValAndClassFlags: FlagSet =
516516
AccessFlags | Package | Case |
517517
Synthetic | JavaDefined | JavaStatic | Artifact |
518-
Lifted | MixedIn | Specialized | ConstructorProxy | Invisible
518+
Lifted | MixedIn | Specialized | ConstructorProxy | Invisible | Erased
519519

520520
/** Flags that can apply to a module val */
521521
val RetainedModuleValFlags: FlagSet = RetainedModuleValAndClassFlags |
522522
Override | Final | Method | Implicit | Given | Lazy |
523-
Accessor | AbsOverride | StableRealizable | Captured | Synchronized | Erased | Transparent
523+
Accessor | AbsOverride | StableRealizable | Captured | Synchronized | Transparent
524524

525525
/** Flags that can apply to a module class */
526526
val RetainedModuleClassFlags: FlagSet = RetainedModuleValAndClassFlags | Enum

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -729,10 +729,10 @@ class TreePickler(pickler: TastyPickler) {
729729
if flags.is(Transparent) then writeModTag(TRANSPARENT)
730730
if flags.is(Infix) then writeModTag(INFIX)
731731
if flags.is(Invisible) then writeModTag(INVISIBLE)
732+
if (flags.is(Erased)) writeModTag(ERASED)
732733
if (isTerm) {
733734
if (flags.is(Implicit)) writeModTag(IMPLICIT)
734735
if (flags.is(Given)) writeModTag(GIVEN)
735-
if (flags.is(Erased)) writeModTag(ERASED)
736736
if (flags.is(Lazy, butNot = Module)) writeModTag(LAZY)
737737
if (flags.is(AbsOverride)) { writeModTag(ABSTRACT); writeModTag(OVERRIDE) }
738738
if (flags.is(Mutable)) writeModTag(MUTABLE)

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -925,7 +925,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
925925
else PrintableFlags(isType)
926926
if (homogenizedView && mods.flags.isTypeFlags) flagMask &~= GivenOrImplicit // drop implicit/given from classes
927927
val rawFlags = if (sym.exists) sym.flags else mods.flags
928-
if (rawFlags.is(Param)) flagMask = flagMask &~ Given
928+
if (rawFlags.is(Param)) flagMask = flagMask &~ Given &~ Erased
929929
val flags = rawFlags & flagMask
930930
var flagsText = toTextFlags(sym, flags)
931931
val annotations =

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ class PruneErasedDefs extends MiniPhase with SymTransformer { thisTransform =>
3434
override def runsAfterGroupsOf: Set[String] = Set(RefChecks.name, ExplicitOuter.name)
3535

3636
override def transformSym(sym: SymDenotation)(using Context): SymDenotation =
37-
if (sym.isEffectivelyErased && !sym.is(Private) && sym.owner.isClass)
37+
if (sym.isEffectivelyErased && sym.isTerm && !sym.is(Private) && sym.owner.isClass)
3838
sym.copySymDenotation(initFlags = sym.flags | Private)
3939
else sym
4040

compiler/src/dotty/tools/dotc/typer/Checking.scala

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -501,7 +501,8 @@ object Checking {
501501
sym.setFlag(Private) // break the overriding relationship by making sym Private
502502
}
503503
if (sym.is(Erased))
504-
checkApplicable(Erased, !sym.isOneOf(MutableOrLazy, butNot = Given))
504+
checkApplicable(Erased,
505+
!sym.isOneOf(MutableOrLazy, butNot = Given) && !sym.isType || sym.isClass)
505506
}
506507

507508
/** Check the type signature of the symbol `M` defined by `tree` does not refer
@@ -997,11 +998,6 @@ trait Checking {
997998
errorTree(tpt, MissingTypeParameterFor(tpt.tpe))
998999
else tpt
9991000

1000-
/** Check that the signature of the class mamber does not return a repeated parameter type */
1001-
def checkSignatureRepeatedParam(sym: Symbol)(using Context): Unit =
1002-
if (!sym.isOneOf(Synthetic | InlineProxy | Param) && sym.info.finalResultType.isRepeatedParam)
1003-
report.error(em"Cannot return repeated parameter type ${sym.info.finalResultType}", sym.srcPos)
1004-
10051001
/** Verify classes extending AnyVal meet the requirements */
10061002
def checkDerivedValueClass(clazz: Symbol, stats: List[Tree])(using Context): Unit =
10071003
Checking.checkDerivedValueClass(clazz, stats)

compiler/src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1147,8 +1147,24 @@ class Typer extends Namer
11471147

11481148
assert(!funFlags.is(Erased) || !args.isEmpty, "An empty function cannot not be erased")
11491149

1150-
val funCls = defn.FunctionClass(args.length,
1151-
isContextual = funFlags.is(Given), isErased = funFlags.is(Erased))
1150+
val numArgs = args.length
1151+
val isContextual = funFlags.is(Given)
1152+
val isErased = funFlags.is(Erased)
1153+
val funCls = defn.FunctionClass(numArgs, isContextual, isErased)
1154+
1155+
/** If `app` is a function type with arguments that are all erased classes,
1156+
* turn it into an erased function type.
1157+
*/
1158+
def propagateErased(app: Tree): Tree = app match
1159+
case AppliedTypeTree(tycon: TypeTree, args)
1160+
if !isErased
1161+
&& numArgs > 0
1162+
&& args.indexWhere(arg => !isErasedClass(arg.tpe)) == numArgs =>
1163+
val tycon1 = TypeTree(defn.FunctionClass(numArgs, isContextual, isErased = true).typeRef)
1164+
.withSpan(tycon.span)
1165+
assignType(cpy.AppliedTypeTree(app)(tycon1, args), tycon1, args)
1166+
case _ =>
1167+
app
11521168

11531169
/** Typechecks dependent function type with given parameters `params` */
11541170
def typedDependent(params: List[untpd.ValDef])(using Context): Tree =
@@ -1172,7 +1188,7 @@ class Typer extends Namer
11721188
val resTpt = TypeTree(mt.nonDependentResultApprox).withSpan(body.span)
11731189
val typeArgs = appDef.termParamss.head.map(_.tpt) :+ resTpt
11741190
val tycon = TypeTree(funCls.typeRef)
1175-
val core = AppliedTypeTree(tycon, typeArgs)
1191+
val core = propagateErased(AppliedTypeTree(tycon, typeArgs))
11761192
RefinedTypeTree(core, List(appDef), ctx.owner.asClass)
11771193
end typedDependent
11781194

@@ -1181,7 +1197,8 @@ class Typer extends Namer
11811197
typedDependent(args.asInstanceOf[List[untpd.ValDef]])(
11821198
using ctx.fresh.setOwner(newRefinedClassSymbol(tree.span)).setNewScope)
11831199
case _ =>
1184-
typed(cpy.AppliedTypeTree(tree)(untpd.TypeTree(funCls.typeRef), args :+ body), pt)
1200+
propagateErased(
1201+
typed(cpy.AppliedTypeTree(tree)(untpd.TypeTree(funCls.typeRef), args :+ body), pt))
11851202
}
11861203
}
11871204

@@ -2065,7 +2082,7 @@ class Typer extends Namer
20652082
case rhs => typedExpr(rhs, tpt1.tpe.widenExpr)
20662083
}
20672084
val vdef1 = assignType(cpy.ValDef(vdef)(name, tpt1, rhs1), sym)
2068-
checkSignatureRepeatedParam(sym)
2085+
postProcessInfo(sym)
20692086
vdef1.setDefTree
20702087
}
20712088

@@ -2153,11 +2170,23 @@ class Typer extends Namer
21532170

21542171
val ddef2 = assignType(cpy.DefDef(ddef)(name, paramss1, tpt1, rhs1), sym)
21552172

2156-
checkSignatureRepeatedParam(sym)
2173+
postProcessInfo(sym)
21572174
ddef2.setDefTree
21582175
//todo: make sure dependent method types do not depend on implicits or by-name params
21592176
}
21602177

2178+
private def isErasedClass(tpe: Type)(using Context): Boolean =
2179+
tpe.underlyingClassRef(refinementOK = true).typeSymbol.is(Erased)
2180+
2181+
/** (1) Check that the signature of the class mamber does not return a repeated parameter type
2182+
* (2) If info is an erased class, set erased flag of member
2183+
*/
2184+
private def postProcessInfo(sym: Symbol)(using Context): Unit =
2185+
if (!sym.isOneOf(Synthetic | InlineProxy | Param) && sym.info.finalResultType.isRepeatedParam)
2186+
report.error(em"Cannot return repeated parameter type ${sym.info.finalResultType}", sym.srcPos)
2187+
if !sym.is(Module) && isErasedClass(sym.info) then
2188+
sym.setFlag(Erased)
2189+
21612190
def typedTypeDef(tdef: untpd.TypeDef, sym: Symbol)(using Context): Tree = {
21622191
val TypeDef(name, rhs) = tdef
21632192
completeAnnotations(tdef, sym)

tests/neg-custom-args/erased/erased-class.scala

Lines changed: 0 additions & 1 deletion
This file was deleted.

tests/neg-custom-args/erased/erased-trait.scala

Lines changed: 0 additions & 1 deletion
This file was deleted.

tests/neg-custom-args/erased/i4058.scala

Lines changed: 0 additions & 1 deletion
This file was deleted.

tests/neg-custom-args/erased/i6795.scala

Lines changed: 0 additions & 1 deletion
This file was deleted.

0 commit comments

Comments
 (0)