Skip to content

Commit

Permalink
Backport "Optimise SpaceEngine.signature" to 3.6.2 (#21899)
Browse files Browse the repository at this point in the history
Backports #21791 to the 3.6.2 branch.

PR submitted by the release tooling.
[skip ci]
  • Loading branch information
WojciechMazur authored Nov 8, 2024
2 parents b04616a + 9ea1e9b commit 5f3e0df
Show file tree
Hide file tree
Showing 8 changed files with 3,102 additions and 11 deletions.
4 changes: 3 additions & 1 deletion compiler/src/dotty/tools/dotc/core/TypeOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -902,7 +902,9 @@ object TypeOps:
}

val inferThisMap = new InferPrefixMap
val tvars = tp1.typeParams.map { tparam => newTypeVar(tparam.paramInfo.bounds, DepParamName.fresh(tparam.paramName)) }
val tvars = tp1.etaExpand match
case eta: TypeLambda => constrained(eta)
case _ => Nil
val protoTp1 = inferThisMap.apply(tp1).appliedTo(tvars)

if gadtSyms.nonEmpty then
Expand Down
11 changes: 8 additions & 3 deletions compiler/src/dotty/tools/dotc/core/Types.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4395,9 +4395,11 @@ object Types extends TypeUtils {

/** Distributes Lambda inside type bounds. Examples:
*
* type T[X] = U becomes type T = [X] -> U
* type T[X] <: U becomes type T >: Nothing <: ([X] -> U)
* type T[X] >: L <: U becomes type T >: ([X] -> L) <: ([X] -> U)
* {{{
* type T[X] = U becomes type T = [X] =>> U
* type T[X] <: U becomes type T >: Nothing <: ([X] =>> U)
* type T[X] >: L <: U becomes type T >: ([X] =>> L) <: ([X] =>> U)
* }}}
*
* The variances of regular TypeBounds types, as well as of match aliases
* and of opaque aliases are always determined from the given parameters
Expand All @@ -4409,13 +4411,15 @@ object Types extends TypeUtils {
*
* Examples:
*
* {{{
* type T[X] >: A // X is invariant
* type T[X] <: List[X] // X is invariant
* type T[X] = List[X] // X is covariant (determined structurally)
* opaque type T[X] = List[X] // X is invariant
* opaque type T[+X] = List[X] // X is covariant
* type T[A, B] = A => B // A is contravariant, B is covariant (determined structurally)
* type T[A, +B] = A => B // A is invariant, B is covariant
* }}}
*/
def boundsFromParams[PI <: ParamInfo.Of[TypeName]](params: List[PI], bounds: TypeBounds)(using Context): TypeBounds = {
def expand(tp: Type, useVariances: Boolean) =
Expand Down Expand Up @@ -4702,6 +4706,7 @@ object Types extends TypeUtils {
type BT <: LambdaType
def paramNum: Int
def paramName: binder.ThisName = binder.paramNames(paramNum)
def paramInfo: binder.PInfo = binder.paramInfos(paramNum)

override def underlying(using Context): Type = {
// TODO: update paramInfos's type to nullable
Expand Down
2 changes: 2 additions & 0 deletions compiler/src/dotty/tools/dotc/printing/Formatting.scala
Original file line number Diff line number Diff line change
Expand Up @@ -115,13 +115,15 @@ object Formatting {
given Show[Char] = ShowAny
given Show[Boolean] = ShowAny
given Show[Integer] = ShowAny
given Show[Long] = ShowAny
given Show[String] = ShowAny
given Show[Class[?]] = ShowAny
given Show[Throwable] = ShowAny
given Show[StringBuffer] = ShowAny
given Show[CompilationUnit] = ShowAny
given Show[Phases.Phase] = ShowAny
given Show[TyperState] = ShowAny
given Show[Unit] = ShowAny
given Show[config.ScalaVersion] = ShowAny
given Show[io.AbstractFile] = ShowAny
given Show[parsing.Scanners.Scanner] = ShowAny
Expand Down
9 changes: 8 additions & 1 deletion compiler/src/dotty/tools/dotc/reporting/trace.scala
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ trait TraceSyntax:
(op: => T)(using Context): T =
if ctx.mode.is(Mode.Printing) || !isForced && (printer eq Printers.noPrinter) then op
else
val start = System.nanoTime
// Avoid evaluating question multiple time, since each evaluation
// may cause some extra logging output.
val q = question
Expand All @@ -109,7 +110,13 @@ trait TraceSyntax:
def finalize(msg: String) =
if !finalized then
ctx.base.indent -= 1
doLog(s"$margin$msg")
val stop = System.nanoTime
val diffNs = stop - start
val diffS = (diffNs / 1000 / 1000).toInt / 1000.0
if diffS > 0.1 then
doLog(s"$margin$msg (${"%.2f".format(diffS)} s)")
else
doLog(s"$margin$msg")
finalized = true
try
doLog(s"$margin$leading")
Expand Down
21 changes: 16 additions & 5 deletions compiler/src/dotty/tools/dotc/transform/patmat/Space.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import core.*
import Constants.*, Contexts.*, Decorators.*, Flags.*, NullOpsDecorator.*, Symbols.*, Types.*
import Names.*, NameOps.*, StdNames.*
import ast.*, tpd.*
import config.Printers.*
import config.Printers.exhaustivity
import printing.{ Printer, * }, Texts.*
import reporting.*
import typer.*, Applications.*, Inferencing.*, ProtoTypes.*
Expand Down Expand Up @@ -524,14 +524,25 @@ object SpaceEngine {
val mt: MethodType = unapp.widen match {
case mt: MethodType => mt
case pt: PolyType =>
scrutineeTp match
case AppliedType(tycon, targs)
if unappSym.is(Synthetic)
&& (pt.resultType.asInstanceOf[MethodType].paramInfos.head.typeConstructor eq tycon) =>
// Special case synthetic unapply/unapplySeq's
// Provided the shapes of the types match:
// the scrutinee type being unapplied and
// the unapply parameter type
pt.instantiate(targs).asInstanceOf[MethodType]
case _ =>
val locked = ctx.typerState.ownedVars
val tvars = constrained(pt)
val mt = pt.instantiate(tvars).asInstanceOf[MethodType]
scrutineeTp <:< mt.paramInfos(0)
val unapplyArgType = mt.paramInfos.head
scrutineeTp <:< unapplyArgType
// force type inference to infer a narrower type: could be singleton
// see tests/patmat/i4227.scala
mt.paramInfos(0) <:< scrutineeTp
maximizeType(mt.paramInfos(0), Spans.NoSpan)
unapplyArgType <:< scrutineeTp
maximizeType(unapplyArgType, Spans.NoSpan)
if !(ctx.typerState.ownedVars -- locked).isEmpty then
// constraining can create type vars out of wildcard types
// (in legalBound, by using a LevelAvoidMap)
Expand All @@ -543,7 +554,7 @@ object SpaceEngine {
// but I'd rather have an unassigned new-new type var, than an infinite loop.
// After all, there's nothing strictly "wrong" with unassigned type vars,
// it just fails TreeChecker's linting.
maximizeType(mt.paramInfos(0), Spans.NoSpan)
maximizeType(unapplyArgType, Spans.NoSpan)
mt
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ trait ImportSuggestions:
end importSuggestions

/** Reduce next timeout for import suggestions by the amount of time it took
* for current search, but but never less than to half of the previous budget.
* for current search, but never less than to half of the previous budget.
*/
private def reduceTimeBudget(used: Int)(using Context) =
val run = ctx.run.nn
Expand Down
Loading

0 comments on commit 5f3e0df

Please sign in to comment.