diff --git a/compiler/src/dotty/tools/dotc/ast/DesugarEnums.scala b/compiler/src/dotty/tools/dotc/ast/DesugarEnums.scala index 50e32c20e5e9..b130e7cb9aea 100644 --- a/compiler/src/dotty/tools/dotc/ast/DesugarEnums.scala +++ b/compiler/src/dotty/tools/dotc/ast/DesugarEnums.scala @@ -124,7 +124,7 @@ object DesugarEnums { /** A creation method for a value of enum type `E`, which is defined as follows: * - * private def $new(_$ordinal: Int, $name: String) = new E { + * private def $new(_$ordinal: Int, $name: String) = new E with scala.runtime.EnumValue { * def $ordinal = $tag * override def toString = $name * $values.register(this) @@ -135,7 +135,7 @@ object DesugarEnums { val toStringDef = toStringMeth(Ident(nme.nameDollar)) val creator = New(Template( constr = emptyConstructor, - parents = enumClassRef :: Nil, + parents = enumClassRef :: scalaRuntimeDot(tpnme.EnumValue) :: Nil, derived = Nil, self = EmptyValDef, body = List(ordinalDef, toStringDef) ++ registerCall @@ -286,7 +286,9 @@ object DesugarEnums { val (tag, scaffolding) = nextOrdinal(CaseKind.Object) val ordinalDef = ordinalMethLit(tag) val toStringDef = toStringMethLit(name.toString) - val impl1 = cpy.Template(impl)(body = List(ordinalDef, toStringDef) ++ registerCall) + val impl1 = cpy.Template(impl)( + parents = impl.parents :+ scalaRuntimeDot(tpnme.EnumValue), + body = List(ordinalDef, toStringDef) ++ registerCall) .withAttachment(ExtendsSingletonMirror, ()) val vdef = ValDef(name, TypeTree(), New(impl1)).withMods(mods.withAddedFlags(EnumValue, span)) flatTree(scaffolding ::: vdef :: Nil).withSpan(span) diff --git a/compiler/src/dotty/tools/dotc/ast/untpd.scala b/compiler/src/dotty/tools/dotc/ast/untpd.scala index 3b4a52f176c7..cbbe96075ac0 100644 --- a/compiler/src/dotty/tools/dotc/ast/untpd.scala +++ b/compiler/src/dotty/tools/dotc/ast/untpd.scala @@ -450,6 +450,7 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo { def rootDot(name: Name)(implicit src: SourceFile): Select = Select(Ident(nme.ROOTPKG), name) def scalaDot(name: Name)(implicit src: SourceFile): Select = Select(rootDot(nme.scala), name) def scalaAnnotationDot(name: Name)(using SourceFile): Select = Select(scalaDot(nme.annotation), name) + def scalaRuntimeDot(name: Name)(using SourceFile): Select = Select(scalaDot(nme.runtime), name) def scalaUnit(implicit src: SourceFile): Select = scalaDot(tpnme.Unit) def scalaAny(implicit src: SourceFile): Select = scalaDot(tpnme.Any) def javaDotLangDot(name: Name)(implicit src: SourceFile): Select = Select(Select(Ident(nme.java), nme.lang), name) diff --git a/compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala b/compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala index 1c575b1c5f68..0d6bcadaf331 100644 --- a/compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala +++ b/compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala @@ -300,6 +300,8 @@ trait ConstraintHandling[AbstractContext] { * (i.e. `inst.widenSingletons <:< bound` succeeds with satisfiable constraint) * 2. If `inst` is a union type, approximate the union type from above by an intersection * of all common base types, provided the result is a subtype of `bound`. + * 3. (currently not enabled, see #9028) If `inst` is an intersection with some restricted base types, drop + * the restricted base types from the intersection, provided the result is a subtype of `bound`. * * Don't do these widenings if `bound` is a subtype of `scala.Singleton`. * Also, if the result of these widenings is a TypeRef to a module class, @@ -309,26 +311,48 @@ trait ConstraintHandling[AbstractContext] { * At this point we also drop the @Repeated annotation to avoid inferring type arguments with it, * as those could leak the annotation to users (see run/inferred-repeated-result). */ - def widenInferred(inst: Type, bound: Type)(implicit actx: AbstractContext): Type = { - def widenOr(tp: Type) = { + def widenInferred(inst: Type, bound: Type)(implicit actx: AbstractContext): Type = + + def isRestricted(tp: Type) = tp.typeSymbol == defn.EnumValueClass // for now, to be generalized later + + def dropRestricted(tp: Type): Type = tp.dealias match + case tpd @ AndType(tp1, tp2) => + if isRestricted(tp1) then tp2 + else if isRestricted(tp2) then tp1 + else + val tpw = tpd.derivedAndType(dropRestricted(tp1), dropRestricted(tp2)) + if tpw ne tpd then tpw else tp + case _ => + tp + + def widenRestricted(tp: Type) = + val tpw = dropRestricted(tp) + if (tpw ne tp) && (tpw <:< bound) then tpw else tp + + def widenOr(tp: Type) = val tpw = tp.widenUnion if (tpw ne tp) && (tpw <:< bound) then tpw else tp - } - def widenSingle(tp: Type) = { + + def widenSingle(tp: Type) = val tpw = tp.widenSingletons if (tpw ne tp) && (tpw <:< bound) then tpw else tp - } + def isSingleton(tp: Type): Boolean = tp match case WildcardType(optBounds) => optBounds.exists && isSingleton(optBounds.bounds.hi) case _ => isSubTypeWhenFrozen(tp, defn.SingletonType) + val wideInst = - if isSingleton(bound) then inst else widenOr(widenSingle(inst)) + if isSingleton(bound) then inst + else /*widenRestricted*/(widenOr(widenSingle(inst))) + // widenRestricted is currently not called since it's special cased in `dropEnumValue` + // in `Namer`. It's left in here in case we want to generalize the scheme to other + // "protected inheritance" classes. wideInst match case wideInst: TypeRef if wideInst.symbol.is(Module) => TermRef(wideInst.prefix, wideInst.symbol.sourceModule) case _ => wideInst.dropRepeatedAnnot - } + end widenInferred /** The instance type of `param` in the current constraint (which contains `param`). * If `fromBelow` is true, the instance type is the lub of the parameter's diff --git a/compiler/src/dotty/tools/dotc/core/Definitions.scala b/compiler/src/dotty/tools/dotc/core/Definitions.scala index 379b18b77a02..ee06ad3579a5 100644 --- a/compiler/src/dotty/tools/dotc/core/Definitions.scala +++ b/compiler/src/dotty/tools/dotc/core/Definitions.scala @@ -639,6 +639,7 @@ class Definitions { @tu lazy val EnumClass: ClassSymbol = ctx.requiredClass("scala.Enum") @tu lazy val Enum_ordinal: Symbol = EnumClass.requiredMethod(nme.ordinal) + @tu lazy val EnumValueClass: ClassSymbol = ctx.requiredClass("scala.runtime.EnumValue") @tu lazy val EnumValuesClass: ClassSymbol = ctx.requiredClass("scala.runtime.EnumValues") @tu lazy val ProductClass: ClassSymbol = ctx.requiredClass("scala.Product") @tu lazy val Product_canEqual : Symbol = ProductClass.requiredMethod(nme.canEqual_) diff --git a/compiler/src/dotty/tools/dotc/core/Flags.scala b/compiler/src/dotty/tools/dotc/core/Flags.scala index 3ffafc0e48fb..0b2aa4133983 100644 --- a/compiler/src/dotty/tools/dotc/core/Flags.scala +++ b/compiler/src/dotty/tools/dotc/core/Flags.scala @@ -438,7 +438,7 @@ object Flags { * TODO: Should check that FromStartFlags do not change in completion */ val FromStartFlags: FlagSet = commonFlags( - Module, Package, Deferred, Method, Case, + Module, Package, Deferred, Method, Case, Enum, HigherKinded, Param, ParamAccessor, Scala2SpecialFlags, MutableOrOpen, Opaque, Touched, JavaStatic, OuterOrCovariant, LabelOrContravariant, CaseAccessor, diff --git a/compiler/src/dotty/tools/dotc/core/StdNames.scala b/compiler/src/dotty/tools/dotc/core/StdNames.scala index 45e23e9d4512..ec1887c8eff3 100644 --- a/compiler/src/dotty/tools/dotc/core/StdNames.scala +++ b/compiler/src/dotty/tools/dotc/core/StdNames.scala @@ -357,7 +357,7 @@ object StdNames { val CAP: N = "CAP" val Constant: N = "Constant" val ConstantType: N = "ConstantType" - val doubleHash: N = "doubleHash" + val EnumValue: N = "EnumValue" val ExistentialTypeTree: N = "ExistentialTypeTree" val Flag : N = "Flag" val floatHash: N = "floatHash" @@ -365,7 +365,6 @@ object StdNames { val Import: N = "Import" val Literal: N = "Literal" val LiteralAnnotArg: N = "LiteralAnnotArg" - val longHash: N = "longHash" val MatchCase: N = "MatchCase" val MirroredElemTypes: N = "MirroredElemTypes" val MirroredElemLabels: N = "MirroredElemLabels" @@ -443,6 +442,7 @@ object StdNames { val delayedInitArg: N = "delayedInit$body" val derived: N = "derived" val derives: N = "derives" + val doubleHash: N = "doubleHash" val drop: N = "drop" val dynamics: N = "dynamics" val elem: N = "elem" @@ -505,6 +505,7 @@ object StdNames { val language: N = "language" val length: N = "length" val lengthCompare: N = "lengthCompare" + val longHash: N = "longHash" val macroThis : N = "_this" val macroContext : N = "c" val main: N = "main" diff --git a/compiler/src/dotty/tools/dotc/typer/Namer.scala b/compiler/src/dotty/tools/dotc/typer/Namer.scala index 329135a02b32..b11fef3ee26d 100644 --- a/compiler/src/dotty/tools/dotc/typer/Namer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Namer.scala @@ -1439,6 +1439,19 @@ class Namer { typer: Typer => // println(s"owner = ${sym.owner}, decls = ${sym.owner.info.decls.show}") def isInlineVal = sym.isOneOf(FinalOrInline, butNot = Method | Mutable) + def isEnumValue(tp: Type) = tp.typeSymbol == defn.EnumValueClass + + // Drop EnumValue parents from inferred types of enum constants + def dropEnumValue(tp: Type): Type = tp.dealias match + case tpd @ AndType(tp1, tp2) => + if isEnumValue(tp1) then tp2 + else if isEnumValue(tp2) then tp1 + else + val tpw = tpd.derivedAndType(dropEnumValue(tp1), dropEnumValue(tp2)) + if tpw ne tpd then tpw else tp + case _ => + tp + // Widen rhs type and eliminate `|' but keep ConstantTypes if // definition is inline (i.e. final in Scala2) and keep module singleton types // instead of widening to the underlying module class types. @@ -1447,7 +1460,9 @@ class Namer { typer: Typer => def widenRhs(tp: Type): Type = tp.widenTermRefExpr.simplified match case ctp: ConstantType if isInlineVal => ctp - case tp => ctx.typeComparer.widenInferred(tp, rhsProto) + case tp => + val tp1 = ctx.typeComparer.widenInferred(tp, rhsProto) + if sym.is(Enum) then dropEnumValue(tp1) else tp1 // Replace aliases to Unit by Unit itself. If we leave the alias in // it would be erased to BoxedUnit. diff --git a/docs/docs/reference/enums/desugarEnums.md b/docs/docs/reference/enums/desugarEnums.md index 7ab1460c44ef..3070602c6c11 100644 --- a/docs/docs/reference/enums/desugarEnums.md +++ b/docs/docs/reference/enums/desugarEnums.md @@ -126,7 +126,9 @@ map into `case class`es or `val`s. where `n` is the ordinal number of the case in the companion object, starting from 0. The statement `$values.register(this)` registers the value as one of the `values` of the enumeration (see below). `$values` is a - compiler-defined private value in the companion object. + compiler-defined private value in the companion object. The anonymous class also + implements the abstract `Product` methods that it inherits from `Enum`. + It is an error if a value case refers to a type parameter of the enclosing `enum` in a type argument of ``. @@ -178,6 +180,7 @@ Companion objects of enumerations that contain at least one simple case define i } ``` +The anonymous class also implements the abstract `Product` methods that it inherits from `Enum`. The `$ordinal` method above is used to generate the `ordinal` method if the enum does not extend a `java.lang.Enum` (as Scala enums do not extend `java.lang.Enum`s unless explicitly specified). In case it does, there is no need to generate `ordinal` as `java.lang.Enum` defines it. ### Scopes for Enum Cases diff --git a/docs/docs/reference/enums/enums.md b/docs/docs/reference/enums/enums.md index c56f733ab5b9..90e52bdb2414 100644 --- a/docs/docs/reference/enums/enums.md +++ b/docs/docs/reference/enums/enums.md @@ -95,7 +95,7 @@ If you want to use the Scala-defined enums as Java enums, you can do so by exten enum Color extends java.lang.Enum[Color] { case Red, Green, Blue } ``` -The type parameter comes from the Java enum [definition](https://docs.oracle.com/javase/8/docs/api/index.html?java/lang/Enum.html) and should be the same as the type of the enum. +The type parameter comes from the Java enum [definition](https://docs.oracle.com/javase/8/docs/api/index.html?java/lang/Enum.html) and should be the same as the type of the enum. There is no need to provide constructor arguments (as defined in the Java API docs) to `java.lang.Enum` when extending it – the compiler will generate them automatically. After defining `Color` like that, you can use it like you would a Java enum: @@ -116,7 +116,7 @@ This trait defines a single public method, `ordinal`: package scala /** A base trait of all enum classes */ -trait Enum { +trait Enum extends Product with Serializable { /** A number uniquely identifying a case of an enum */ def ordinal: Int diff --git a/library/src-bootstrapped/scala/Enum.scala b/library/src-bootstrapped/scala/Enum.scala new file mode 100644 index 000000000000..d1e72cb06ff1 --- /dev/null +++ b/library/src-bootstrapped/scala/Enum.scala @@ -0,0 +1,9 @@ +package scala + +/** A base trait of all enum classes */ +trait Enum extends Product, Serializable: + + /** A number uniquely identifying a case of an enum */ + def ordinal: Int + protected def $ordinal: Int + diff --git a/library/src/scala/Enum.scala b/library/src-non-bootstrapped/Enum.scala similarity index 91% rename from library/src/scala/Enum.scala rename to library/src-non-bootstrapped/Enum.scala index 69f1daa27ab8..4f8fe897d41c 100644 --- a/library/src/scala/Enum.scala +++ b/library/src-non-bootstrapped/Enum.scala @@ -1,9 +1,8 @@ package scala /** A base trait of all enum classes */ -trait Enum { +trait Enum: /** A number uniquely identifying a case of an enum */ def ordinal: Int protected def $ordinal: Int -} diff --git a/library/src/scala/runtime/EnumValue.scala b/library/src/scala/runtime/EnumValue.scala new file mode 100644 index 000000000000..f07b756190e8 --- /dev/null +++ b/library/src/scala/runtime/EnumValue.scala @@ -0,0 +1,10 @@ +package scala.runtime + +trait EnumValue extends Product, Serializable: + override def canEqual(that: Any) = this eq that.asInstanceOf[AnyRef] + override def productArity: Int = 0 + override def productPrefix: String = toString + override def productElement(n: Int): Any = + throw IndexOutOfBoundsException(n.toString) + override def productElementName(n: Int): String = + throw IndexOutOfBoundsException(n.toString) diff --git a/tests/fuzzy/b82054893e0db44e31ae82d696c19c1fbc7be55c.scala b/tests/fuzzy/b82054893e0db44e31ae82d696c19c1fbc7be55c.scala index 1e57d871d58e..9247be34b235 100644 --- a/tests/fuzzy/b82054893e0db44e31ae82d696c19c1fbc7be55c.scala +++ b/tests/fuzzy/b82054893e0db44e31ae82d696c19c1fbc7be55c.scala @@ -1,4 +1,4 @@ -object main { +object _main { def i0 = { class i1 { private[i0] var i2: _ > 0 private def i3: List[Int] diff --git a/tests/neg/enumvalues.scala b/tests/neg/enumvalues.scala new file mode 100644 index 000000000000..f9d847f5fb63 --- /dev/null +++ b/tests/neg/enumvalues.scala @@ -0,0 +1,15 @@ +enum Color: + case Red, Green, Blue + +enum Option[+T]: + case None extends Option[Nothing] + +import scala.runtime.EnumValue + +@main def Test(c: Boolean) = + // Verify that enum constants don't leak the scala.runtime.EnumValue trait + val x: EnumValue = if c then Color.Red else Color.Blue // error // error + val y: EnumValue = Color.Green // error + val z: EnumValue = Option.None // error + + diff --git a/tests/pos/enum-List-control.scala b/tests/pos/enum-List-control.scala index 931406214122..2a957a2c4ab2 100644 --- a/tests/pos/enum-List-control.scala +++ b/tests/pos/enum-List-control.scala @@ -2,11 +2,16 @@ abstract sealed class List[T] extends Enum object List { final class Cons[T](x: T, xs: List[T]) extends List[T] { def $ordinal = 0 + def canEqual(that: Any): Boolean = that.isInstanceOf[Cons[_]] + def productArity: Int = 2 + def productElement(n: Int): Any = n match + case 0 => x + case 1 => xs } object Cons { def apply[T](x: T, xs: List[T]): List[T] = new Cons(x, xs) } - final class Nil[T]() extends List[T] { + final class Nil[T]() extends List[T], runtime.EnumValue { def $ordinal = 1 } object Nil { diff --git a/tests/pos/localmodules.scala b/tests/pos/localmodules.scala index 3e1600842c20..f681d34f3123 100644 --- a/tests/pos/localmodules.scala +++ b/tests/pos/localmodules.scala @@ -1,6 +1,6 @@ package test; -object main { +object _main { class a { diff --git a/tests/pos/t0002.scala b/tests/pos/t0002.scala index 4c58ed3f4f6d..b6caffb784d4 100644 --- a/tests/pos/t0002.scala +++ b/tests/pos/t0002.scala @@ -1,4 +1,4 @@ -object main { +object _main { def main(args: Array[String]) = { val b = true; while (b == true) { } diff --git a/tests/pos/t789.scala b/tests/pos/t789.scala index c453e229ac7e..f086f65633ca 100644 --- a/tests/pos/t789.scala +++ b/tests/pos/t789.scala @@ -1,4 +1,4 @@ -object main { // don't do this at home +object _main { // don't do this at home trait Impl diff --git a/tests/pos/typealiases.scala b/tests/pos/typealiases.scala index 93d1dce4dc31..c5bde6e2dbdd 100644 --- a/tests/pos/typealiases.scala +++ b/tests/pos/typealiases.scala @@ -11,7 +11,7 @@ trait Test[T] { def check2[S](xs: Array[S], c: Check[S]) = c(xs) } -object main extends Test[Int] { +object _main extends Test[Int] { val pair1 = (1,1) implicit def topair(x: Int): Tuple2[Int, Int] = (x,x) diff --git a/tests/run/i9011.scala b/tests/run/i9011.scala new file mode 100644 index 000000000000..e5b488cb1b5d --- /dev/null +++ b/tests/run/i9011.scala @@ -0,0 +1,57 @@ +enum Opt[+T] derives Eq: + case Sm(t: T) + case Nn + +import scala.deriving._ +import scala.compiletime.{erasedValue, summonInline} + +trait Eq[T] { + def eqv(x: T, y: T): Boolean +} + +object Eq { + given Eq[Int] { + def eqv(x: Int, y: Int) = x == y + } + + inline def summonAll[T <: Tuple]: List[Eq[_]] = inline erasedValue[T] match { + case _: Unit => Nil + case _: (t *: ts) => summonInline[Eq[t]] :: summonAll[ts] + } + + def check(elem: Eq[_])(x: Any, y: Any): Boolean = + elem.asInstanceOf[Eq[Any]].eqv(x, y) + + def iterator[T](p: T) = p.asInstanceOf[Product].productIterator + + def eqSum[T](s: Mirror.SumOf[T], elems: List[Eq[_]]): Eq[T] = + new Eq[T] { + def eqv(x: T, y: T): Boolean = { + val ordx = s.ordinal(x) + (s.ordinal(y) == ordx) && check(elems(ordx))(x, y) + } + } + + def eqProduct[T](p: Mirror.ProductOf[T], elems: List[Eq[_]]): Eq[T] = + new Eq[T] { + def eqv(x: T, y: T): Boolean = + iterator(x).zip(iterator(y)).zip(elems.iterator).forall { + case ((x, y), elem) => check(elem)(x, y) + } + } + + inline given derived[T](using m: Mirror.Of[T]) as Eq[T] = { + val elemInstances = summonAll[m.MirroredElemTypes] + inline m match { + case s: Mirror.SumOf[T] => eqSum(s, elemInstances) + case p: Mirror.ProductOf[T] => eqProduct(p, elemInstances) + } + } +} + +object Test extends App { + import Opt._ + val eqoi = summon[Eq[Opt[Int]]] + assert(eqoi.eqv(Sm(23), Sm(23))) + assert(eqoi.eqv(Nn, Nn)) +} \ No newline at end of file diff --git a/tests/semanticdb/expect/Enums.expect.scala b/tests/semanticdb/expect/Enums.expect.scala index 34a4a406425d..3baff23aa49c 100644 --- a/tests/semanticdb/expect/Enums.expect.scala +++ b/tests/semanticdb/expect/Enums.expect.scala @@ -29,19 +29,19 @@ object Enums/*<-_empty_::Enums.*/: case Sunday/*<-_empty_::Enums.WeekDays.Sunday.*/ enum Coin/*<-_empty_::Enums.Coin#*/(value/*<-_empty_::Enums.Coin#value.*/: Int/*->scala::Int#*/): - case Penny/*<-_empty_::Enums.Coin.Penny.*/ extends Coin/*->_empty_::Enums.Coin#*/(1) - case Nickel/*<-_empty_::Enums.Coin.Nickel.*/ extends Coin/*->_empty_::Enums.Coin#*/(5) - case Dime/*<-_empty_::Enums.Coin.Dime.*/ extends Coin/*->_empty_::Enums.Coin#*/(10) - case Quarter/*<-_empty_::Enums.Coin.Quarter.*/ extends Coin/*->_empty_::Enums.Coin#*/(25) - case Dollar/*<-_empty_::Enums.Coin.Dollar.*/ extends Coin/*->_empty_::Enums.Coin#*/(100) + case Penny/*<-_empty_::Enums.Coin.Penny.*/ extends Coin/*->_empty_::Enums.Coin#*/(1)/*->scala::runtime::EnumValue#*/ + case Nickel/*<-_empty_::Enums.Coin.Nickel.*/ extends Coin/*->_empty_::Enums.Coin#*/(5)/*->scala::runtime::EnumValue#*/ + case Dime/*<-_empty_::Enums.Coin.Dime.*/ extends Coin/*->_empty_::Enums.Coin#*/(10)/*->scala::runtime::EnumValue#*/ + case Quarter/*<-_empty_::Enums.Coin.Quarter.*/ extends Coin/*->_empty_::Enums.Coin#*/(25)/*->scala::runtime::EnumValue#*/ + case Dollar/*<-_empty_::Enums.Coin.Dollar.*/ extends Coin/*->_empty_::Enums.Coin#*/(100)/*->scala::runtime::EnumValue#*/ enum Maybe/*<-_empty_::Enums.Maybe#*/[+A/*<-_empty_::Enums.Maybe#[A]*/]: case Just/*<-_empty_::Enums.Maybe.Just#*/(value/*<-_empty_::Enums.Maybe.Just#value.*/: A/*->_empty_::Enums.Maybe.Just#[A]*/) - case None/*<-_empty_::Enums.Maybe.None.*/ + case None/*<-_empty_::Enums.Maybe.None.*//*->scala::runtime::EnumValue#*/ enum Tag/*<-_empty_::Enums.Tag#*/[A/*<-_empty_::Enums.Tag#[A]*/]: - case IntTag/*<-_empty_::Enums.Tag.IntTag.*/ extends Tag/*->_empty_::Enums.Tag#*/[Int/*->scala::Int#*/] - case BooleanTag/*<-_empty_::Enums.Tag.BooleanTag.*/ extends Tag/*->_empty_::Enums.Tag#*/[Boolean/*->scala::Boolean#*/] + case IntTag/*<-_empty_::Enums.Tag.IntTag.*/ extends Tag/*->_empty_::Enums.Tag#*/[Int/*->scala::Int#*/]/*->scala::runtime::EnumValue#*/ + case BooleanTag/*<-_empty_::Enums.Tag.BooleanTag.*/ extends Tag/*->_empty_::Enums.Tag#*/[Boolean/*->scala::Boolean#*/]/*->scala::runtime::EnumValue#*/ enum <:_empty_::Enums.`<:<`.Refl#[C]*/ <:_empty_::Enums.`<:<`#*/ C/*->_empty_::Enums.`<:<`.Refl#[C]*/) @@ -59,11 +59,11 @@ object Enums/*<-_empty_::Enums.*/: def surfaceGravity/*<-_empty_::Enums.Planet#surfaceGravity().*/ = G/*->_empty_::Enums.Planet#G.*/ */*->scala::Double#`*`(+6).*/ mass/*->_empty_::Enums.Planet#mass.*/ //*->scala::Double#`::`(+6).*/ (radius/*->_empty_::Enums.Planet#radius.*/ */*->scala::Double#`*`(+6).*/ radius/*->_empty_::Enums.Planet#radius.*/) def surfaceWeight/*<-_empty_::Enums.Planet#surfaceWeight().*/(otherMass/*<-_empty_::Enums.Planet#surfaceWeight().(otherMass)*/: Double/*->scala::Double#*/) = otherMass/*->_empty_::Enums.Planet#surfaceWeight().(otherMass)*/ */*->scala::Double#`*`(+6).*/ surfaceGravity/*->_empty_::Enums.Planet#surfaceGravity().*/ - case Mercury/*<-_empty_::Enums.Planet.Mercury.*/ extends Planet/*->_empty_::Enums.Planet#*/(3.303e+23, 2.4397e6) - case Venus/*<-_empty_::Enums.Planet.Venus.*/ extends Planet/*->_empty_::Enums.Planet#*/(4.869e+24, 6.0518e6) - case Earth/*<-_empty_::Enums.Planet.Earth.*/ extends Planet/*->_empty_::Enums.Planet#*/(5.976e+24, 6.37814e6) - case Mars/*<-_empty_::Enums.Planet.Mars.*/ extends Planet/*->_empty_::Enums.Planet#*/(6.421e+23, 3.3972e6) - case Jupiter/*<-_empty_::Enums.Planet.Jupiter.*/ extends Planet/*->_empty_::Enums.Planet#*/(1.9e+27, 7.1492e7) - case Saturn/*<-_empty_::Enums.Planet.Saturn.*/ extends Planet/*->_empty_::Enums.Planet#*/(5.688e+26, 6.0268e7) - case Uranus/*<-_empty_::Enums.Planet.Uranus.*/ extends Planet/*->_empty_::Enums.Planet#*/(8.686e+25, 2.5559e7) - case Neptune/*<-_empty_::Enums.Planet.Neptune.*/ extends Planet/*->_empty_::Enums.Planet#*/(1.024e+26, 2.4746e7) + case Mercury/*<-_empty_::Enums.Planet.Mercury.*/ extends Planet/*->_empty_::Enums.Planet#*/(3.303e+23, 2.4397e6)/*->scala::runtime::EnumValue#*/ + case Venus/*<-_empty_::Enums.Planet.Venus.*/ extends Planet/*->_empty_::Enums.Planet#*/(4.869e+24, 6.0518e6)/*->scala::runtime::EnumValue#*/ + case Earth/*<-_empty_::Enums.Planet.Earth.*/ extends Planet/*->_empty_::Enums.Planet#*/(5.976e+24, 6.37814e6)/*->scala::runtime::EnumValue#*/ + case Mars/*<-_empty_::Enums.Planet.Mars.*/ extends Planet/*->_empty_::Enums.Planet#*/(6.421e+23, 3.3972e6)/*->scala::runtime::EnumValue#*/ + case Jupiter/*<-_empty_::Enums.Planet.Jupiter.*/ extends Planet/*->_empty_::Enums.Planet#*/(1.9e+27, 7.1492e7)/*->scala::runtime::EnumValue#*/ + case Saturn/*<-_empty_::Enums.Planet.Saturn.*/ extends Planet/*->_empty_::Enums.Planet#*/(5.688e+26, 6.0268e7)/*->scala::runtime::EnumValue#*/ + case Uranus/*<-_empty_::Enums.Planet.Uranus.*/ extends Planet/*->_empty_::Enums.Planet#*/(8.686e+25, 2.5559e7)/*->scala::runtime::EnumValue#*/ + case Neptune/*<-_empty_::Enums.Planet.Neptune.*/ extends Planet/*->_empty_::Enums.Planet#*/(1.024e+26, 2.4746e7)/*->scala::runtime::EnumValue#*/ diff --git a/tests/semanticdb/metac.expect b/tests/semanticdb/metac.expect index 09ac1176b4af..6bf2e8fe4e3f 100644 --- a/tests/semanticdb/metac.expect +++ b/tests/semanticdb/metac.expect @@ -636,7 +636,7 @@ Uri => Enums.scala Text => empty Language => Scala Symbols => 157 entries -Occurrences => 187 entries +Occurrences => 203 entries Symbols: _empty_/Enums. => final object Enums @@ -855,18 +855,23 @@ Occurrences: [31:9..31:14): Penny <- _empty_/Enums.Coin.Penny. [31:26..31:30): Coin -> _empty_/Enums.Coin# [31:30..31:30): -> _empty_/Enums.Coin#``(). +[31:33..31:33): -> scala/runtime/EnumValue# [32:9..32:15): Nickel <- _empty_/Enums.Coin.Nickel. [32:26..32:30): Coin -> _empty_/Enums.Coin# [32:30..32:30): -> _empty_/Enums.Coin#``(). +[32:33..32:33): -> scala/runtime/EnumValue# [33:9..33:13): Dime <- _empty_/Enums.Coin.Dime. [33:26..33:30): Coin -> _empty_/Enums.Coin# [33:30..33:30): -> _empty_/Enums.Coin#``(). +[33:34..33:34): -> scala/runtime/EnumValue# [34:9..34:16): Quarter <- _empty_/Enums.Coin.Quarter. [34:26..34:30): Coin -> _empty_/Enums.Coin# [34:30..34:30): -> _empty_/Enums.Coin#``(). +[34:34..34:34): -> scala/runtime/EnumValue# [35:9..35:15): Dollar <- _empty_/Enums.Coin.Dollar. [35:26..35:30): Coin -> _empty_/Enums.Coin# [35:30..35:30): -> _empty_/Enums.Coin#``(). +[35:35..35:35): -> scala/runtime/EnumValue# [37:7..37:12): Maybe <- _empty_/Enums.Maybe# [37:12..37:16): <- _empty_/Enums.Maybe#``(). [37:14..37:15): A <- _empty_/Enums.Maybe#[A] @@ -876,6 +881,7 @@ Occurrences: [38:21..38:22): A -> _empty_/Enums.Maybe.Just#[A] [39:4..39:4): -> _empty_/Enums.Maybe#``(). [39:9..39:13): None <- _empty_/Enums.Maybe.None. +[39:13..39:13): -> scala/runtime/EnumValue# [41:7..41:10): Tag <- _empty_/Enums.Tag# [41:10..41:13): <- _empty_/Enums.Tag#``(). [41:11..41:12): A <- _empty_/Enums.Tag#[A] @@ -883,10 +889,12 @@ Occurrences: [42:24..42:27): Tag -> _empty_/Enums.Tag# [42:28..42:31): Int -> scala/Int# [42:32..42:32): -> _empty_/Enums.Tag#``(). +[42:32..42:32): -> scala/runtime/EnumValue# [43:9..43:19): BooleanTag <- _empty_/Enums.Tag.BooleanTag. [43:28..43:31): Tag -> _empty_/Enums.Tag# [43:32..43:39): Boolean -> scala/Boolean# [43:40..43:40): -> _empty_/Enums.Tag#``(). +[43:40..43:40): -> scala/runtime/EnumValue# [45:7..45:10): <:< <- _empty_/Enums.`<:<`# [45:10..45:17): <- _empty_/Enums.`<:<`#``(). [45:12..45:13): A <- _empty_/Enums.`<:<`#[A] @@ -964,27 +972,35 @@ Occurrences: [61:9..61:16): Mercury <- _empty_/Enums.Planet.Mercury. [61:25..61:31): Planet -> _empty_/Enums.Planet# [61:31..61:31): -> _empty_/Enums.Planet#``(). +[61:52..61:52): -> scala/runtime/EnumValue# [62:9..62:14): Venus <- _empty_/Enums.Planet.Venus. [62:25..62:31): Planet -> _empty_/Enums.Planet# [62:31..62:31): -> _empty_/Enums.Planet#``(). +[62:52..62:52): -> scala/runtime/EnumValue# [63:9..63:14): Earth <- _empty_/Enums.Planet.Earth. [63:25..63:31): Planet -> _empty_/Enums.Planet# [63:31..63:31): -> _empty_/Enums.Planet#``(). +[63:53..63:53): -> scala/runtime/EnumValue# [64:9..64:13): Mars <- _empty_/Enums.Planet.Mars. [64:25..64:31): Planet -> _empty_/Enums.Planet# [64:31..64:31): -> _empty_/Enums.Planet#``(). +[64:52..64:52): -> scala/runtime/EnumValue# [65:9..65:16): Jupiter <- _empty_/Enums.Planet.Jupiter. [65:25..65:31): Planet -> _empty_/Enums.Planet# [65:31..65:31): -> _empty_/Enums.Planet#``(). +[65:52..65:52): -> scala/runtime/EnumValue# [66:9..66:15): Saturn <- _empty_/Enums.Planet.Saturn. [66:25..66:31): Planet -> _empty_/Enums.Planet# [66:31..66:31): -> _empty_/Enums.Planet#``(). +[66:52..66:52): -> scala/runtime/EnumValue# [67:9..67:15): Uranus <- _empty_/Enums.Planet.Uranus. [67:25..67:31): Planet -> _empty_/Enums.Planet# [67:31..67:31): -> _empty_/Enums.Planet#``(). +[67:52..67:52): -> scala/runtime/EnumValue# [68:9..68:16): Neptune <- _empty_/Enums.Planet.Neptune. [68:25..68:31): Planet -> _empty_/Enums.Planet# [68:31..68:31): -> _empty_/Enums.Planet#``(). +[68:52..68:52): -> scala/runtime/EnumValue# expect/EtaExpansion.scala -------------------------