Skip to content

Commit

Permalink
Merge pull request #15268 from dotty-staging/mb/revert-compiletime-op…
Browse files Browse the repository at this point in the history
…s-covariance

Revert #14452 and make compile-time operations on stable arguments stable
  • Loading branch information
mbovel authored Jun 15, 2022
2 parents 741587d + 9205cc6 commit 80a1e95
Show file tree
Hide file tree
Showing 15 changed files with 220 additions and 102 deletions.
Original file line number Diff line number Diff line change
@@ -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)
22 changes: 22 additions & 0 deletions bench-micro/tests/someTypes.scala
Original file line number Diff line number Diff line change
@@ -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 = ???
1 change: 1 addition & 0 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -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`
Expand Down
25 changes: 24 additions & 1 deletion compiler/src/dotty/tools/dotc/core/Types.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand Down Expand Up @@ -4162,10 +4163,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 =
Expand Down Expand Up @@ -4243,7 +4266,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
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/plugins/Plugins.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand Down
6 changes: 3 additions & 3 deletions library/src/scala/compiletime/ops/any.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ object any:
* ```
* @syntax markdown
*/
type ==[+X, +Y] <: Boolean
type ==[X, Y] <: Boolean

/** Inequality comparison of two singleton types.
* ```scala
Expand All @@ -26,7 +26,7 @@ object any:
* ```
* @syntax markdown
*/
type !=[+X, +Y] <: Boolean
type !=[X, Y] <: Boolean

/** Tests if a type is a constant.
* ```scala
Expand Down Expand Up @@ -63,4 +63,4 @@ object any:
* ```
* @syntax markdown
*/
type ToString[+X] <: String
type ToString[X] <: String
8 changes: 4 additions & 4 deletions library/src/scala/compiletime/ops/boolean.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ object boolean:
* ```
* @syntax markdown
*/
type ![+X <: Boolean] <: Boolean
type ![X <: Boolean] <: Boolean

/** Exclusive disjunction of two `Boolean` singleton types.
* ```scala
Expand All @@ -25,7 +25,7 @@ object boolean:
* ```
* @syntax markdown
*/
type ^[+X <: Boolean, +Y <: Boolean] <: Boolean
type ^[X <: Boolean, Y <: Boolean] <: Boolean

/** Conjunction of two `Boolean` singleton types.
* ```scala
Expand All @@ -37,7 +37,7 @@ object boolean:
* ```
* @syntax markdown
*/
type &&[+X <: Boolean, +Y <: Boolean] <: Boolean
type &&[X <: Boolean, Y <: Boolean] <: Boolean

/** Disjunction of two `Boolean` singleton types.
* ```scala
Expand All @@ -49,4 +49,4 @@ object boolean:
* ```
* @syntax markdown
*/
type ||[+X <: Boolean, +Y <: Boolean] <: Boolean
type ||[X <: Boolean, Y <: Boolean] <: Boolean
32 changes: 16 additions & 16 deletions library/src/scala/compiletime/ops/double.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ object double:
* ```
* @syntax markdown
*/
type +[+X <: Double, +Y <: Double] <: Double
type +[X <: Double, Y <: Double] <: Double

/** Subtraction of two `Double` singleton types.
* ```scala
Expand All @@ -22,7 +22,7 @@ object double:
* ```
* @syntax markdown
*/
type -[+X <: Double, +Y <: Double] <: Double
type -[X <: Double, Y <: Double] <: Double

/** Multiplication of two `Double` singleton types.
* ```scala
Expand All @@ -33,7 +33,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
Expand All @@ -44,7 +44,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
Expand All @@ -55,7 +55,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
Expand All @@ -67,7 +67,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
Expand All @@ -79,7 +79,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
Expand All @@ -91,7 +91,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
Expand All @@ -103,7 +103,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
Expand All @@ -114,7 +114,7 @@ object double:
* ```
* @syntax markdown
*/
type Abs[+X <: Double] <: Double
type Abs[X <: Double] <: Double

/** Negation of an `Double` singleton type.
* ```scala
Expand All @@ -126,7 +126,7 @@ object double:
* ```
* @syntax markdown
*/
type Negate[+X <: Double] <: Double
type Negate[X <: Double] <: Double

/** Minimum of two `Double` singleton types.
* ```scala
Expand All @@ -137,7 +137,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
Expand All @@ -148,7 +148,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
Expand All @@ -159,7 +159,7 @@ object double:
* ```
* @syntax markdown
*/
type ToInt[+X <: Double] <: Int
type ToInt[X <: Double] <: Int

/** Long conversion of a `Double` singleton type.
* ```scala
Expand All @@ -170,7 +170,7 @@ object double:
* ```
* @syntax markdown
*/
type ToLong[+X <: Double] <: Long
type ToLong[X <: Double] <: Long

/** Float conversion of a `Double` singleton type.
* ```scala
Expand All @@ -181,4 +181,4 @@ object double:
* ```
* @syntax markdown
*/
type ToFloat[+X <: Double] <: Float
type ToFloat[X <: Double] <: Float
Loading

0 comments on commit 80a1e95

Please sign in to comment.