diff --git a/bench-micro/src/main/scala/dotty/tools/benchmarks/TypeOpsBenchmark.scala b/bench-micro/src/main/scala/dotty/tools/benchmarks/TypeOpsBenchmark.scala new file mode 100644 index 000000000000..2436fc10acfe --- /dev/null +++ b/bench-micro/src/main/scala/dotty/tools/benchmarks/TypeOpsBenchmark.scala @@ -0,0 +1,56 @@ +package dotty.tools.benchmarks + +import org.openjdk.jmh.annotations.* +import java.util.concurrent.TimeUnit.SECONDS +import dotty.tools.dotc.{Driver, Run, Compiler} +import dotty.tools.dotc.core.Mode +import dotty.tools.dotc.core.Types.{TermRef, Type} +import dotty.tools.dotc.core.Contexts.{ContextBase, Context, ctx, withMode} + +@Fork(value = 5) +@Warmup(iterations = 5, time = 1, timeUnit = SECONDS) +@Measurement(iterations = 5, time = 1, timeUnit = SECONDS) +@State(Scope.Thread) +class TypeOpsBenchmark: + var tp: Type = null + var context: Context = null + + @Param(Array("int", "singletonsSum", "intsSum", "deepSingletonsSum", "deepIntsSum", "singletonsIntersection", "singletonsUnion")) + var valName: String = "int" + + @Setup(Level.Iteration) + def setup(): Unit = + val driver = new Driver: + override def finish(compiler: Compiler, run: Run)(using Context): Unit = + withMode(Mode.Printing) { + val pkg = run.units(0).tpdTree.symbol + tp = pkg.requiredClass("Test").requiredValueRef(valName).underlying + context = ctx + } + super.finish(compiler, run) + driver.process(Array( + "-classpath", System.getProperty("BENCH_CLASS_PATH"), + "-Ystop-after:typer", + "tests/someTypes.scala" + )) + + @Benchmark + def isStable(): Unit = tp.isStable(using context) + + @Benchmark + def normalized(): Unit = tp.normalized(using context) + + @Benchmark + def simplified(): Unit = tp.simplified(using context) + + @Benchmark + def dealias(): Unit = tp.dealias(using context) + + @Benchmark + def widen(): Unit = tp.widen(using context) + + @Benchmark + def atoms(): Unit = tp.atoms(using context) + + @Benchmark + def isProvisional(): Unit = tp.isProvisional(using context) diff --git a/bench-micro/tests/someTypes.scala b/bench-micro/tests/someTypes.scala new file mode 100644 index 000000000000..4631c6ba0750 --- /dev/null +++ b/bench-micro/tests/someTypes.scala @@ -0,0 +1,22 @@ +import compiletime.ops.int.+ + +class Test: + val int: Int = 5 + + val int2: Int = 6 + + val singletonsSum: int.type + int2.type = ??? + + val intsSum: Int + Int = ??? + + val deepSingletonsSum: + ((int.type + int2.type) + (int.type + int2.type)) + ((int.type + int2.type) + (int.type + int2.type)) + + ((int.type + int2.type) + (int.type + int2.type)) + ((int.type + int2.type) + (int.type + int2.type)) = ??? + + val deepIntsSum: + ((Int + Int) + (Int + Int)) + ((Int + Int) + (Int + Int)) + + ((Int + Int) + (Int + Int)) + ((Int + Int) + (Int + Int)) = ??? + + val singletonsIntersection: int.type & int2.type = ??? + + val singletonsUnion: int.type | int2.type = ??? diff --git a/build.sbt b/build.sbt index bae6deafd8cc..80a36739d5e8 100644 --- a/build.sbt +++ b/build.sbt @@ -13,6 +13,7 @@ val `scala3-tasty-inspector` = Build.`scala3-tasty-inspector` val `scala3-language-server` = Build.`scala3-language-server` val `scala3-bench` = Build.`scala3-bench` val `scala3-bench-bootstrapped` = Build.`scala3-bench-bootstrapped` +val `scala3-bench-micro` = Build.`scala3-bench-micro` val `stdlib-bootstrapped` = Build.`stdlib-bootstrapped` val `stdlib-bootstrapped-tasty-tests` = Build.`stdlib-bootstrapped-tasty-tests` val `tasty-core` = Build.`tasty-core` diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index 8b9f8690604e..21e72c1d918f 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -175,6 +175,7 @@ object Types { // see: tests/explicit-nulls/pos/flow-stable.scala.disabled tp.tp1.isStable && (realizability(tp.tp2) eq Realizable) || tp.tp2.isStable && (realizability(tp.tp1) eq Realizable) + case tp: AppliedType => tp.cachedIsStable case _ => false } @@ -4161,10 +4162,32 @@ object Types { private var myStableHash: Byte = 0 private var myGround: Byte = 0 + private var myIsStablePeriod: Period = Nowhere + private var myIsStable: Boolean = false + def isGround(acc: TypeAccumulator[Boolean])(using Context): Boolean = if myGround == 0 then myGround = if acc.foldOver(true, this) then 1 else -1 myGround > 0 + private[Types] def cachedIsStable(using Context): Boolean = + // We need to invalidate the cache when the period changes because the + // case `TermRef` of `Type#isStable` reads denotations, which depend on + // the period. See docs/_docs/internals/periods.md for more information. + if myIsStablePeriod != ctx.period then + val res: Boolean = computeIsStable + // We don't cache if the type is provisional because `Type#isStable` + // calls `Type#stripTypeVar` which might return different results later. + if !isProvisional then + myIsStablePeriod = ctx.period + myIsStable = res + res + else + myIsStable + + private def computeIsStable(using Context): Boolean = tycon match + case tycon: TypeRef if defn.isCompiletimeAppliedType(tycon.symbol) && args.forall(_.isStable) => true + case _ => false + override def underlying(using Context): Type = tycon override def superType(using Context): Type = @@ -4242,7 +4265,7 @@ object Types { // final val one = 1 // type Two = one.type + one.type // ``` - case tp: TermRef => tp.underlying + case tp: TypeProxy if tp.underlying.isStable => tp.underlying.fixForEvaluation case tp => tp } diff --git a/compiler/src/dotty/tools/dotc/plugins/Plugins.scala b/compiler/src/dotty/tools/dotc/plugins/Plugins.scala index bcc0c221f78b..3093a1c0460f 100644 --- a/compiler/src/dotty/tools/dotc/plugins/Plugins.scala +++ b/compiler/src/dotty/tools/dotc/plugins/Plugins.scala @@ -51,7 +51,7 @@ trait Plugins { } else _roughPluginsList - /** Load all available plugins. Skips plugins that + /** Load all available plugins. Skips plugins that * either have the same name as another one, or which * define a phase name that another one does. */ diff --git a/library/src/scala/compiletime/ops/any.scala b/library/src/scala/compiletime/ops/any.scala index ba3b6809fb49..c6eb7c075b14 100644 --- a/library/src/scala/compiletime/ops/any.scala +++ b/library/src/scala/compiletime/ops/any.scala @@ -10,7 +10,7 @@ object any: * ``` * @syntax markdown */ - type ==[+X, +Y] <: Boolean + type ==[X, Y] <: Boolean /** Inequality comparison of two singleton types. * ```scala @@ -20,7 +20,7 @@ object any: * ``` * @syntax markdown */ - type !=[+X, +Y] <: Boolean + type !=[X, Y] <: Boolean /** Tests if a type is a constant. * ```scala @@ -48,4 +48,4 @@ object any: * ``` * @syntax markdown */ - type ToString[+X] <: String + type ToString[X] <: String diff --git a/library/src/scala/compiletime/ops/boolean.scala b/library/src/scala/compiletime/ops/boolean.scala index c67ca28e5d22..323fd7d6d7ed 100644 --- a/library/src/scala/compiletime/ops/boolean.scala +++ b/library/src/scala/compiletime/ops/boolean.scala @@ -10,7 +10,7 @@ object boolean: * ``` * @syntax markdown */ - type ![+X <: Boolean] <: Boolean + type ![X <: Boolean] <: Boolean /** Exclusive disjunction of two `Boolean` singleton types. * ```scala @@ -19,7 +19,7 @@ object boolean: * ``` * @syntax markdown */ - type ^[+X <: Boolean, +Y <: Boolean] <: Boolean + type ^[X <: Boolean, Y <: Boolean] <: Boolean /** Conjunction of two `Boolean` singleton types. * ```scala @@ -28,7 +28,7 @@ object boolean: * ``` * @syntax markdown */ - type &&[+X <: Boolean, +Y <: Boolean] <: Boolean + type &&[X <: Boolean, Y <: Boolean] <: Boolean /** Disjunction of two `Boolean` singleton types. * ```scala @@ -37,4 +37,4 @@ object boolean: * ``` * @syntax markdown */ - type ||[+X <: Boolean, +Y <: Boolean] <: Boolean + type ||[X <: Boolean, Y <: Boolean] <: Boolean diff --git a/library/src/scala/compiletime/ops/double.scala b/library/src/scala/compiletime/ops/double.scala index 91f65f644e4b..74882b867e00 100644 --- a/library/src/scala/compiletime/ops/double.scala +++ b/library/src/scala/compiletime/ops/double.scala @@ -8,7 +8,7 @@ object double: * ``` * @syntax markdown */ - type +[+X <: Double, +Y <: Double] <: Double + type +[X <: Double, Y <: Double] <: Double /** Subtraction of two `Double` singleton types. * ```scala @@ -16,7 +16,7 @@ object double: * ``` * @syntax markdown */ - type -[+X <: Double, +Y <: Double] <: Double + type -[X <: Double, Y <: Double] <: Double /** Multiplication of two `Double` singleton types. * ```scala @@ -24,7 +24,7 @@ object double: * ``` * @syntax markdown */ - type *[+X <: Double, +Y <: Double] <: Double + type *[X <: Double, Y <: Double] <: Double /** Integer division of two `Double` singleton types. * ```scala @@ -32,7 +32,7 @@ object double: * ``` * @syntax markdown */ - type /[+X <: Double, +Y <: Double] <: Double + type /[X <: Double, Y <: Double] <: Double /** Remainder of the division of `X` by `Y`. * ```scala @@ -40,7 +40,7 @@ object double: * ``` * @syntax markdown */ - type %[+X <: Double, +Y <: Double] <: Double + type %[X <: Double, Y <: Double] <: Double /** Less-than comparison of two `Double` singleton types. * ```scala @@ -49,7 +49,7 @@ object double: * ``` * @syntax markdown */ - type <[+X <: Double, +Y <: Double] <: Boolean + type <[X <: Double, Y <: Double] <: Boolean /** Greater-than comparison of two `Double` singleton types. * ```scala @@ -58,7 +58,7 @@ object double: * ``` * @syntax markdown */ - type >[+X <: Double, +Y <: Double] <: Boolean + type >[X <: Double, Y <: Double] <: Boolean /** Greater-or-equal comparison of two `Double` singleton types. * ```scala @@ -67,7 +67,7 @@ object double: * ``` * @syntax markdown */ - type >=[+X <: Double, +Y <: Double] <: Boolean + type >=[X <: Double, Y <: Double] <: Boolean /** Less-or-equal comparison of two `Double` singleton types. * ```scala @@ -76,7 +76,7 @@ object double: * ``` * @syntax markdown */ - type <=[+X <: Double, +Y <: Double] <: Boolean + type <=[X <: Double, Y <: Double] <: Boolean /** Absolute value of an `Double` singleton type. * ```scala @@ -84,7 +84,7 @@ object double: * ``` * @syntax markdown */ - type Abs[+X <: Double] <: Double + type Abs[X <: Double] <: Double /** Negation of an `Double` singleton type. * ```scala @@ -93,7 +93,7 @@ object double: * ``` * @syntax markdown */ - type Negate[+X <: Double] <: Double + type Negate[X <: Double] <: Double /** Minimum of two `Double` singleton types. * ```scala @@ -101,7 +101,7 @@ object double: * ``` * @syntax markdown */ - type Min[+X <: Double, +Y <: Double] <: Double + type Min[X <: Double, Y <: Double] <: Double /** Maximum of two `Double` singleton types. * ```scala @@ -109,7 +109,7 @@ object double: * ``` * @syntax markdown */ - type Max[+X <: Double, +Y <: Double] <: Double + type Max[X <: Double, Y <: Double] <: Double /** Int conversion of a `Double` singleton type. * ```scala @@ -117,7 +117,7 @@ object double: * ``` * @syntax markdown */ - type ToInt[+X <: Double] <: Int + type ToInt[X <: Double] <: Int /** Long conversion of a `Double` singleton type. * ```scala @@ -125,7 +125,7 @@ object double: * ``` * @syntax markdown */ - type ToLong[+X <: Double] <: Long + type ToLong[X <: Double] <: Long /** Float conversion of a `Double` singleton type. * ```scala @@ -133,4 +133,4 @@ object double: * ``` * @syntax markdown */ - type ToFloat[+X <: Double] <: Float + type ToFloat[X <: Double] <: Float \ No newline at end of file diff --git a/library/src/scala/compiletime/ops/float.scala b/library/src/scala/compiletime/ops/float.scala index c42aa4aec70f..29e02992a8df 100644 --- a/library/src/scala/compiletime/ops/float.scala +++ b/library/src/scala/compiletime/ops/float.scala @@ -8,7 +8,7 @@ object float: * ``` * @syntax markdown */ - type +[+X <: Float, +Y <: Float] <: Float + type +[X <: Float, Y <: Float] <: Float /** Subtraction of two `Float` singleton types. * ```scala @@ -16,7 +16,7 @@ object float: * ``` * @syntax markdown */ - type -[+X <: Float, +Y <: Float] <: Float + type -[X <: Float, Y <: Float] <: Float /** Multiplication of two `Float` singleton types. * ```scala @@ -24,7 +24,7 @@ object float: * ``` * @syntax markdown */ - type *[+X <: Float, +Y <: Float] <: Float + type *[X <: Float, Y <: Float] <: Float /** Integer division of two `Float` singleton types. * ```scala @@ -32,7 +32,7 @@ object float: * ``` * @syntax markdown */ - type /[+X <: Float, +Y <: Float] <: Float + type /[X <: Float, Y <: Float] <: Float /** Remainder of the division of `X` by `Y`. * ```scala @@ -40,7 +40,7 @@ object float: * ``` * @syntax markdown */ - type %[+X <: Float, +Y <: Float] <: Float + type %[X <: Float, Y <: Float] <: Float /** Less-than comparison of two `Float` singleton types. * ```scala @@ -49,7 +49,7 @@ object float: * ``` * @syntax markdown */ - type <[+X <: Float, +Y <: Float] <: Boolean + type <[X <: Float, Y <: Float] <: Boolean /** Greater-than comparison of two `Float` singleton types. * ```scala @@ -58,7 +58,7 @@ object float: * ``` * @syntax markdown */ - type >[+X <: Float, +Y <: Float] <: Boolean + type >[X <: Float, Y <: Float] <: Boolean /** Greater-or-equal comparison of two `Float` singleton types. * ```scala @@ -67,7 +67,7 @@ object float: * ``` * @syntax markdown */ - type >=[+X <: Float, +Y <: Float] <: Boolean + type >=[X <: Float, Y <: Float] <: Boolean /** Less-or-equal comparison of two `Float` singleton types. * ```scala @@ -76,7 +76,7 @@ object float: * ``` * @syntax markdown */ - type <=[+X <: Float, +Y <: Float] <: Boolean + type <=[X <: Float, Y <: Float] <: Boolean /** Absolute value of an `Float` singleton type. * ```scala @@ -84,7 +84,7 @@ object float: * ``` * @syntax markdown */ - type Abs[+X <: Float] <: Float + type Abs[X <: Float] <: Float /** Negation of an `Float` singleton type. * ```scala @@ -93,7 +93,7 @@ object float: * ``` * @syntax markdown */ - type Negate[+X <: Float] <: Float + type Negate[X <: Float] <: Float /** Minimum of two `Float` singleton types. * ```scala @@ -101,7 +101,7 @@ object float: * ``` * @syntax markdown */ - type Min[+X <: Float, +Y <: Float] <: Float + type Min[X <: Float, Y <: Float] <: Float /** Maximum of two `Float` singleton types. * ```scala @@ -109,7 +109,7 @@ object float: * ``` * @syntax markdown */ - type Max[+X <: Float, +Y <: Float] <: Float + type Max[X <: Float, Y <: Float] <: Float /** Int conversion of a `Float` singleton type. * ```scala @@ -117,7 +117,7 @@ object float: * ``` * @syntax markdown */ - type ToInt[+X <: Float] <: Int + type ToInt[X <: Float] <: Int /** Long conversion of a `Float` singleton type. * ```scala @@ -125,7 +125,7 @@ object float: * ``` * @syntax markdown */ - type ToLong[+X <: Float] <: Long + type ToLong[X <: Float] <: Long /** Double conversion of a `Float` singleton type. * ```scala @@ -133,4 +133,4 @@ object float: * ``` * @syntax markdown */ - type ToDouble[+X <: Float] <: Double + type ToDouble[X <: Float] <: Double diff --git a/library/src/scala/compiletime/ops/int.scala b/library/src/scala/compiletime/ops/int.scala index ef7707173a00..f041576faa86 100644 --- a/library/src/scala/compiletime/ops/int.scala +++ b/library/src/scala/compiletime/ops/int.scala @@ -15,7 +15,7 @@ object int: * ``` * @syntax markdown */ - type S[+N <: Int] <: Int + type S[N <: Int] <: Int /** Addition of two `Int` singleton types. * ```scala @@ -23,7 +23,7 @@ object int: * ``` * @syntax markdown */ - type +[+X <: Int, +Y <: Int] <: Int + type +[X <: Int, Y <: Int] <: Int /** Subtraction of two `Int` singleton types. * ```scala @@ -31,7 +31,7 @@ object int: * ``` * @syntax markdown */ - type -[+X <: Int, +Y <: Int] <: Int + type -[X <: Int, Y <: Int] <: Int /** Multiplication of two `Int` singleton types. * ```scala @@ -39,7 +39,7 @@ object int: * ``` * @syntax markdown */ - type *[+X <: Int, +Y <: Int] <: Int + type *[X <: Int, Y <: Int] <: Int /** Integer division of two `Int` singleton types. * ```scala @@ -47,7 +47,7 @@ object int: * ``` * @syntax markdown */ - type /[+X <: Int, +Y <: Int] <: Int + type /[X <: Int, Y <: Int] <: Int /** Remainder of the division of `X` by `Y`. * ```scala @@ -55,7 +55,7 @@ object int: * ``` * @syntax markdown */ - type %[+X <: Int, +Y <: Int] <: Int + type %[X <: Int, Y <: Int] <: Int /** Binary left shift of `X` by `Y`. * ```scala @@ -63,7 +63,7 @@ object int: * ``` * @syntax markdown */ - type <<[+X <: Int, +Y <: Int] <: Int + type <<[X <: Int, Y <: Int] <: Int /** Binary right shift of `X` by `Y`. * ```scala @@ -71,7 +71,7 @@ object int: * ``` * @syntax markdown */ - type >>[+X <: Int, +Y <: Int] <: Int + type >>[X <: Int, Y <: Int] <: Int /** Binary right shift of `X` by `Y`, filling the left with zeros. * ```scala @@ -79,7 +79,7 @@ object int: * ``` * @syntax markdown */ - type >>>[+X <: Int, +Y <: Int] <: Int + type >>>[X <: Int, Y <: Int] <: Int /** Bitwise xor of `X` and `Y`. * ```scala @@ -87,7 +87,7 @@ object int: * ``` * @syntax markdown */ - type ^[+X <: Int, +Y <: Int] <: Int + type ^[X <: Int, Y <: Int] <: Int /** Less-than comparison of two `Int` singleton types. * ```scala @@ -96,7 +96,7 @@ object int: * ``` * @syntax markdown */ - type <[+X <: Int, +Y <: Int] <: Boolean + type <[X <: Int, Y <: Int] <: Boolean /** Greater-than comparison of two `Int` singleton types. * ```scala @@ -105,7 +105,7 @@ object int: * ``` * @syntax markdown */ - type >[+X <: Int, +Y <: Int] <: Boolean + type >[X <: Int, Y <: Int] <: Boolean /** Greater-or-equal comparison of two `Int` singleton types. * ```scala @@ -114,7 +114,7 @@ object int: * ``` * @syntax markdown */ - type >=[+X <: Int, +Y <: Int] <: Boolean + type >=[X <: Int, Y <: Int] <: Boolean /** Less-or-equal comparison of two `Int` singleton types. * ```scala @@ -123,7 +123,7 @@ object int: * ``` * @syntax markdown */ - type <=[+X <: Int, +Y <: Int] <: Boolean + type <=[X <: Int, Y <: Int] <: Boolean /** Bitwise and of `X` and `Y`. * ```scala @@ -132,7 +132,7 @@ object int: * ``` * @syntax markdown */ - type BitwiseAnd[+X <: Int, +Y <: Int] <: Int + type BitwiseAnd[X <: Int, Y <: Int] <: Int /** Bitwise or of `X` and `Y`. * ```scala @@ -140,7 +140,7 @@ object int: * ``` * @syntax markdown */ - type BitwiseOr[+X <: Int, +Y <: Int] <: Int + type BitwiseOr[X <: Int, Y <: Int] <: Int /** Absolute value of an `Int` singleton type. * ```scala @@ -148,7 +148,7 @@ object int: * ``` * @syntax markdown */ - type Abs[+X <: Int] <: Int + type Abs[X <: Int] <: Int /** Negation of an `Int` singleton type. * ```scala @@ -157,7 +157,7 @@ object int: * ``` * @syntax markdown */ - type Negate[+X <: Int] <: Int + type Negate[X <: Int] <: Int /** Minimum of two `Int` singleton types. * ```scala @@ -165,7 +165,7 @@ object int: * ``` * @syntax markdown */ - type Min[+X <: Int, +Y <: Int] <: Int + type Min[X <: Int, Y <: Int] <: Int /** Maximum of two `Int` singleton types. * ```scala @@ -173,7 +173,7 @@ object int: * ``` * @syntax markdown */ - type Max[+X <: Int, +Y <: Int] <: Int + type Max[X <: Int, Y <: Int] <: Int /** String conversion of an `Int` singleton type. * ```scala @@ -182,7 +182,7 @@ object int: * @syntax markdown */ //@deprecated("Use compiletime.ops.any.ToString instead.","3.2.0") // uncomment when reaching 3.2.0 - type ToString[+X <: Int] <: String + type ToString[X <: Int] <: String /** Long conversion of an `Int` singleton type. * ```scala @@ -190,7 +190,7 @@ object int: * ``` * @syntax markdown */ - type ToLong[+X <: Int] <: Long + type ToLong[X <: Int] <: Long /** Float conversion of an `Int` singleton type. * ```scala @@ -198,7 +198,7 @@ object int: * ``` * @syntax markdown */ - type ToFloat[+X <: Int] <: Float + type ToFloat[X <: Int] <: Float /** Double conversion of an `Int` singleton type. * ```scala @@ -206,7 +206,7 @@ object int: * ``` * @syntax markdown */ - type ToDouble[+X <: Int] <: Double + type ToDouble[X <: Int] <: Double /** Number of zero bits preceding the highest-order ("leftmost") * one-bit in the two's complement binary representation of the specified `Int` singleton type. @@ -220,4 +220,4 @@ object int: * ``` * @syntax markdown */ - type NumberOfLeadingZeros[+X <: Int] <: Int + type NumberOfLeadingZeros[X <: Int] <: Int diff --git a/library/src/scala/compiletime/ops/long.scala b/library/src/scala/compiletime/ops/long.scala index 1d10e3bf3213..3ab7841faedd 100644 --- a/library/src/scala/compiletime/ops/long.scala +++ b/library/src/scala/compiletime/ops/long.scala @@ -15,7 +15,7 @@ object long: * ``` * @syntax markdown */ - type S[+N <: Long] <: Long + type S[N <: Long] <: Long /** Addition of two `Long` singleton types. * ```scala @@ -23,7 +23,7 @@ object long: * ``` * @syntax markdown */ - type +[+X <: Long, +Y <: Long] <: Long + type +[X <: Long, Y <: Long] <: Long /** Subtraction of two `Long` singleton types. * ```scala @@ -31,7 +31,7 @@ object long: * ``` * @syntax markdown */ - type -[+X <: Long, +Y <: Long] <: Long + type -[X <: Long, Y <: Long] <: Long /** Multiplication of two `Long` singleton types. * ```scala @@ -39,7 +39,7 @@ object long: * ``` * @syntax markdown */ - type *[+X <: Long, +Y <: Long] <: Long + type *[X <: Long, Y <: Long] <: Long /** Integer division of two `Long` singleton types. * ```scala @@ -47,7 +47,7 @@ object long: * ``` * @syntax markdown */ - type /[+X <: Long, +Y <: Long] <: Long + type /[X <: Long, Y <: Long] <: Long /** Remainder of the division of `X` by `Y`. * ```scala @@ -55,7 +55,7 @@ object long: * ``` * @syntax markdown */ - type %[+X <: Long, +Y <: Long] <: Long + type %[X <: Long, Y <: Long] <: Long /** Binary left shift of `X` by `Y`. * ```scala @@ -63,7 +63,7 @@ object long: * ``` * @syntax markdown */ - type <<[+X <: Long, +Y <: Long] <: Long + type <<[X <: Long, Y <: Long] <: Long /** Binary right shift of `X` by `Y`. * ```scala @@ -71,7 +71,7 @@ object long: * ``` * @syntax markdown */ - type >>[+X <: Long, +Y <: Long] <: Long + type >>[X <: Long, Y <: Long] <: Long /** Binary right shift of `X` by `Y`, filling the left with zeros. * ```scala @@ -79,7 +79,7 @@ object long: * ``` * @syntax markdown */ - type >>>[+X <: Long, +Y <: Long] <: Long + type >>>[X <: Long, Y <: Long] <: Long /** Bitwise xor of `X` and `Y`. * ```scala @@ -87,7 +87,7 @@ object long: * ``` * @syntax markdown */ - type ^[+X <: Long, +Y <: Long] <: Long + type ^[X <: Long, Y <: Long] <: Long /** Less-than comparison of two `Long` singleton types. * ```scala @@ -96,7 +96,7 @@ object long: * ``` * @syntax markdown */ - type <[+X <: Long, +Y <: Long] <: Boolean + type <[X <: Long, Y <: Long] <: Boolean /** Greater-than comparison of two `Long` singleton types. * ```scala @@ -105,7 +105,7 @@ object long: * ``` * @syntax markdown */ - type >[+X <: Long, +Y <: Long] <: Boolean + type >[X <: Long, Y <: Long] <: Boolean /** Greater-or-equal comparison of two `Long` singleton types. * ```scala @@ -114,7 +114,7 @@ object long: * ``` * @syntax markdown */ - type >=[+X <: Long, +Y <: Long] <: Boolean + type >=[X <: Long, Y <: Long] <: Boolean /** Less-or-equal comparison of two `Long` singleton types. * ```scala @@ -123,7 +123,7 @@ object long: * ``` * @syntax markdown */ - type <=[+X <: Long, +Y <: Long] <: Boolean + type <=[X <: Long, Y <: Long] <: Boolean /** Bitwise and of `X` and `Y`. * ```scala @@ -132,7 +132,7 @@ object long: * ``` * @syntax markdown */ - type BitwiseAnd[+X <: Long, +Y <: Long] <: Long + type BitwiseAnd[X <: Long, Y <: Long] <: Long /** Bitwise or of `X` and `Y`. * ```scala @@ -140,7 +140,7 @@ object long: * ``` * @syntax markdown */ - type BitwiseOr[+X <: Long, +Y <: Long] <: Long + type BitwiseOr[X <: Long, Y <: Long] <: Long /** Absolute value of an `Long` singleton type. * ```scala @@ -148,7 +148,7 @@ object long: * ``` * @syntax markdown */ - type Abs[+X <: Long] <: Long + type Abs[X <: Long] <: Long /** Negation of an `Long` singleton type. * ```scala @@ -157,7 +157,7 @@ object long: * ``` * @syntax markdown */ - type Negate[+X <: Long] <: Long + type Negate[X <: Long] <: Long /** Minimum of two `Long` singleton types. * ```scala @@ -165,7 +165,7 @@ object long: * ``` * @syntax markdown */ - type Min[+X <: Long, +Y <: Long] <: Long + type Min[X <: Long, Y <: Long] <: Long /** Maximum of two `Long` singleton types. * ```scala @@ -173,7 +173,7 @@ object long: * ``` * @syntax markdown */ - type Max[+X <: Long, +Y <: Long] <: Long + type Max[X <: Long, Y <: Long] <: Long /** Number of zero bits preceding the highest-order ("leftmost") * one-bit in the two's complement binary representation of the specified `Long` singleton type. @@ -187,7 +187,7 @@ object long: * ``` * @syntax markdown */ - type NumberOfLeadingZeros[+X <: Long] <: Int + type NumberOfLeadingZeros[X <: Long] <: Int /** Int conversion of a `Long` singleton type. * ```scala @@ -195,7 +195,7 @@ object long: * ``` * @syntax markdown */ - type ToInt[+X <: Long] <: Int + type ToInt[X <: Long] <: Int /** Float conversion of a `Long` singleton type. * ```scala @@ -203,7 +203,7 @@ object long: * ``` * @syntax markdown */ - type ToFloat[+X <: Long] <: Float + type ToFloat[X <: Long] <: Float /** Double conversion of a `Long` singleton type. * ```scala @@ -211,4 +211,4 @@ object long: * ``` * @syntax markdown */ - type ToDouble[+X <: Long] <: Double + type ToDouble[X <: Long] <: Double diff --git a/library/src/scala/compiletime/ops/string.scala b/library/src/scala/compiletime/ops/string.scala index 18c5b13871b1..35562cfd6261 100644 --- a/library/src/scala/compiletime/ops/string.scala +++ b/library/src/scala/compiletime/ops/string.scala @@ -8,7 +8,7 @@ object string: * ``` * @syntax markdown */ - type +[+X <: String, +Y <: String] <: String + type +[X <: String, Y <: String] <: String /** Length of a `String` singleton type. * ```scala @@ -16,7 +16,7 @@ object string: * ``` * @syntax markdown */ - type Length[+X <: String] <: Int + type Length[X <: String] <: Int /** Substring of a `String` singleton type, with a singleton type * begin inclusive index `IBeg`, and a singleton type exclusive end index `IEnd`. @@ -28,7 +28,7 @@ object string: * ``` * @syntax markdown */ - type Substring[+S <: String, +IBeg <: Int, +IEnd <: Int] <: String + type Substring[S <: String, IBeg <: Int, IEnd <: Int] <: String /** Tests if this `String` singleton type matches the given * regular expression `String` singleton type. @@ -37,7 +37,7 @@ object string: * ``` * @syntax markdown */ - type Matches[+S <: String, +Regex <: String] <: Boolean + type Matches[S <: String, Regex <: String] <: Boolean /** Returns the Char type at the specified index. * An index ranges from 0 to Length[S] - 1. The first Char of @@ -47,4 +47,4 @@ object string: * ``` * @syntax markdown */ - type CharAt[+S <: String, +Idx <: Int] <: Char + type CharAt[S <: String, Idx <: Int] <: Char diff --git a/project/Build.scala b/project/Build.scala index 5d02e9870253..9ae3c477ffd5 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -1247,6 +1247,10 @@ object Build { lazy val `scala3-bench-bootstrapped` = project.in(file("bench")).asDottyBench(Bootstrapped) lazy val `scala3-bench-run` = project.in(file("bench-run")).asDottyBench(Bootstrapped) + lazy val `scala3-bench-micro` = project.in(file("bench-micro")) + .asDottyBench(Bootstrapped) + .settings(Jmh / run / mainClass := Some("org.openjdk.jmh.Main")) + val testcasesOutputDir = taskKey[Seq[String]]("Root directory where tests classses are generated") val testcasesSourceRoot = taskKey[String]("Root directory where tests sources are generated") val testDocumentationRoot = taskKey[String]("Root directory where tests documentation are stored") diff --git a/project/plugins.sbt b/project/plugins.sbt index f0b13c6cb7c4..bb43d75d44da 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -10,7 +10,7 @@ addSbtPlugin("com.jsuereth" % "sbt-pgp" % "2.0.0") addSbtPlugin("org.xerial.sbt" % "sbt-pack" % "0.13") -addSbtPlugin("pl.project13.scala" % "sbt-jmh" % "0.3.2") +addSbtPlugin("pl.project13.scala" % "sbt-jmh" % "0.4.3") addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.9.0") diff --git a/tests/neg/singleton-ops-int.scala b/tests/neg/singleton-ops-int.scala index f7081342a4ee..bdceb5bad5e3 100644 --- a/tests/neg/singleton-ops-int.scala +++ b/tests/neg/singleton-ops-int.scala @@ -117,11 +117,23 @@ object Test { val t83: ToDouble[1] = 1.0 val t84: ToDouble[2] = 2 // error - // Singleton operations are covariant. - type Plus2[X <: Int] = X + 2 - val x: Int = 5 - val xPlus2: Plus2[x.type] = (x + 2).asInstanceOf - summon[xPlus2.type + 1 <:< Plus2[x.type] + 1] + // Singletons are dereferenced + val t85: Int = 5 + val t86: t85.type = t85 + summon[t85.type + t85.type =:= t86.type + t86.type] + + // Singletons are dereferenced recursively + val t87: t86.type = t87 + summon[t85.type + t85.type =:= t87.type + t87.type] + + // Skolems of compile-time types are dereferenced: + // (?1 : (Test.x : Int) * (Test.x : Int)) --> (Test.x : Int) * (Test.x : Int) def mult(x: Int, y: Int): x.type * y.type = (x * y).asInstanceOf - val y: x.type * x.type * x.type = mult(mult(x, x), x) + val t88: t85.type * t85.type * t85.type = mult(mult(t85, t85), t85) + + // Compile-time operations with singleton arguments are singletons + summon[t85.type + t86.type <:< Singleton] + + // Compile-time operations with non-singleton arguments are not singletons + summon[t85.type + Int <:< Singleton] // error }