Skip to content

Commit 6bd846a

Browse files
committed
Special case dropping EnumValue in Namer
We now drop EnumValue just when inferring types of enum cases. This can be done unconditionally since in any case every enum case extends Enum, which extends Product and Serializable. EnumValue is just an invisible implementation bundle. This means we disable for now the more general handling in widenInferred.
1 parent 9a887fe commit 6bd846a

File tree

4 files changed

+20
-4
lines changed

4 files changed

+20
-4
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,7 @@ object DesugarEnums {
306306
else {
307307
val (tag, scaffolding) = nextOrdinal(CaseKind.Simple)
308308
val creator = Apply(Ident(nme.DOLLAR_NEW), List(Literal(Constant(tag)), Literal(Constant(name.toString))))
309-
val vdef = ValDef(name, TypeTree(), creator).withMods(mods.withAddedFlags(EnumValue, span))
309+
val vdef = ValDef(name, enumClassRef, creator).withMods(mods.withAddedFlags(EnumValue, span))
310310
flatTree(scaffolding ::: vdef :: Nil).withSpan(span)
311311
}
312312
}

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,10 @@ trait ConstraintHandling[AbstractContext] {
341341

342342
val wideInst =
343343
if isSingleton(bound) then inst
344-
else widenProtected(widenOr(widenSingle(inst)))
344+
else /*widenProtected*/(widenOr(widenSingle(inst)))
345+
// widenProtected is currently not called since it's special cased in `dropEnumValue`
346+
// in `Namer`. It's left in here in case we want to generalize the scheme to other
347+
// "protected inheritance" classes.
345348
wideInst match
346349
case wideInst: TypeRef if wideInst.symbol.is(Module) =>
347350
TermRef(wideInst.prefix, wideInst.symbol.sourceModule)

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,7 @@ object Flags {
438438
* TODO: Should check that FromStartFlags do not change in completion
439439
*/
440440
val FromStartFlags: FlagSet = commonFlags(
441-
Module, Package, Deferred, Method, Case,
441+
Module, Package, Deferred, Method, Case, Enum,
442442
HigherKinded, Param, ParamAccessor,
443443
Scala2SpecialFlags, MutableOrOpen, Opaque, Touched, JavaStatic,
444444
OuterOrCovariant, LabelOrContravariant, CaseAccessor,

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

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1439,6 +1439,17 @@ class Namer { typer: Typer =>
14391439
// println(s"owner = ${sym.owner}, decls = ${sym.owner.info.decls.show}")
14401440
def isInlineVal = sym.isOneOf(FinalOrInline, butNot = Method | Mutable)
14411441

1442+
def isEnumValue(tp: Type) = tp.typeSymbol == defn.EnumValueClass
1443+
1444+
// Drop EnumValue parents from inferred types of enum constants
1445+
def dropEnumValue(tp: Type): Type = tp.dealias match
1446+
case tp @ AndType(tp1, tp2) =>
1447+
if isEnumValue(tp1) then tp2
1448+
else if isEnumValue(tp2) then tp1
1449+
else tp.derivedAndType(dropEnumValue(tp1), dropEnumValue(tp2))
1450+
case _ =>
1451+
tp
1452+
14421453
// Widen rhs type and eliminate `|' but keep ConstantTypes if
14431454
// definition is inline (i.e. final in Scala2) and keep module singleton types
14441455
// instead of widening to the underlying module class types.
@@ -1447,7 +1458,9 @@ class Namer { typer: Typer =>
14471458
def widenRhs(tp: Type): Type =
14481459
tp.widenTermRefExpr.simplified match
14491460
case ctp: ConstantType if isInlineVal => ctp
1450-
case tp => ctx.typeComparer.widenInferred(tp, rhsProto)
1461+
case tp =>
1462+
val tp1 = ctx.typeComparer.widenInferred(tp, rhsProto)
1463+
if sym.is(Enum) then dropEnumValue(tp1) else tp1
14511464

14521465
// Replace aliases to Unit by Unit itself. If we leave the alias in
14531466
// it would be erased to BoxedUnit.

0 commit comments

Comments
 (0)