Skip to content

Commit 71b0aea

Browse files
authored
Optimise SpaceEngine.signature (#21791)
2 parents 7d8f0d4 + b00649a commit 71b0aea

File tree

8 files changed

+3102
-11
lines changed

8 files changed

+3102
-11
lines changed

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

+3-1
Original file line numberDiff line numberDiff line change
@@ -902,7 +902,9 @@ object TypeOps:
902902
}
903903

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

908910
if gadtSyms.nonEmpty then

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

+8-3
Original file line numberDiff line numberDiff line change
@@ -4398,9 +4398,11 @@ object Types extends TypeUtils {
43984398

43994399
/** Distributes Lambda inside type bounds. Examples:
44004400
*
4401-
* type T[X] = U becomes type T = [X] -> U
4402-
* type T[X] <: U becomes type T >: Nothing <: ([X] -> U)
4403-
* type T[X] >: L <: U becomes type T >: ([X] -> L) <: ([X] -> U)
4401+
* {{{
4402+
* type T[X] = U becomes type T = [X] =>> U
4403+
* type T[X] <: U becomes type T >: Nothing <: ([X] =>> U)
4404+
* type T[X] >: L <: U becomes type T >: ([X] =>> L) <: ([X] =>> U)
4405+
* }}}
44044406
*
44054407
* The variances of regular TypeBounds types, as well as of match aliases
44064408
* and of opaque aliases are always determined from the given parameters
@@ -4412,13 +4414,15 @@ object Types extends TypeUtils {
44124414
*
44134415
* Examples:
44144416
*
4417+
* {{{
44154418
* type T[X] >: A // X is invariant
44164419
* type T[X] <: List[X] // X is invariant
44174420
* type T[X] = List[X] // X is covariant (determined structurally)
44184421
* opaque type T[X] = List[X] // X is invariant
44194422
* opaque type T[+X] = List[X] // X is covariant
44204423
* type T[A, B] = A => B // A is contravariant, B is covariant (determined structurally)
44214424
* type T[A, +B] = A => B // A is invariant, B is covariant
4425+
* }}}
44224426
*/
44234427
def boundsFromParams[PI <: ParamInfo.Of[TypeName]](params: List[PI], bounds: TypeBounds)(using Context): TypeBounds = {
44244428
def expand(tp: Type, useVariances: Boolean) =
@@ -4705,6 +4709,7 @@ object Types extends TypeUtils {
47054709
type BT <: LambdaType
47064710
def paramNum: Int
47074711
def paramName: binder.ThisName = binder.paramNames(paramNum)
4712+
def paramInfo: binder.PInfo = binder.paramInfos(paramNum)
47084713

47094714
override def underlying(using Context): Type = {
47104715
// TODO: update paramInfos's type to nullable

compiler/src/dotty/tools/dotc/printing/Formatting.scala

+2
Original file line numberDiff line numberDiff line change
@@ -115,13 +115,15 @@ object Formatting {
115115
given Show[Char] = ShowAny
116116
given Show[Boolean] = ShowAny
117117
given Show[Integer] = ShowAny
118+
given Show[Long] = ShowAny
118119
given Show[String] = ShowAny
119120
given Show[Class[?]] = ShowAny
120121
given Show[Throwable] = ShowAny
121122
given Show[StringBuffer] = ShowAny
122123
given Show[CompilationUnit] = ShowAny
123124
given Show[Phases.Phase] = ShowAny
124125
given Show[TyperState] = ShowAny
126+
given Show[Unit] = ShowAny
125127
given Show[config.ScalaVersion] = ShowAny
126128
given Show[io.AbstractFile] = ShowAny
127129
given Show[parsing.Scanners.Scanner] = ShowAny

compiler/src/dotty/tools/dotc/reporting/trace.scala

+8-1
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ trait TraceSyntax:
9696
(op: => T)(using Context): T =
9797
if ctx.mode.is(Mode.Printing) || !isForced && (printer eq Printers.noPrinter) then op
9898
else
99+
val start = System.nanoTime
99100
// Avoid evaluating question multiple time, since each evaluation
100101
// may cause some extra logging output.
101102
val q = question
@@ -109,7 +110,13 @@ trait TraceSyntax:
109110
def finalize(msg: String) =
110111
if !finalized then
111112
ctx.base.indent -= 1
112-
doLog(s"$margin$msg")
113+
val stop = System.nanoTime
114+
val diffNs = stop - start
115+
val diffS = (diffNs / 1000 / 1000).toInt / 1000.0
116+
if diffS > 0.1 then
117+
doLog(s"$margin$msg (${"%.2f".format(diffS)} s)")
118+
else
119+
doLog(s"$margin$msg")
113120
finalized = true
114121
try
115122
doLog(s"$margin$leading")

compiler/src/dotty/tools/dotc/transform/patmat/Space.scala

+16-5
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import core.*
77
import Constants.*, Contexts.*, Decorators.*, Flags.*, NullOpsDecorator.*, Symbols.*, Types.*
88
import Names.*, NameOps.*, StdNames.*
99
import ast.*, tpd.*
10-
import config.Printers.*
10+
import config.Printers.exhaustivity
1111
import printing.{ Printer, * }, Texts.*
1212
import reporting.*
1313
import typer.*, Applications.*, Inferencing.*, ProtoTypes.*
@@ -525,14 +525,25 @@ object SpaceEngine {
525525
val mt: MethodType = unapp.widen match {
526526
case mt: MethodType => mt
527527
case pt: PolyType =>
528+
scrutineeTp match
529+
case AppliedType(tycon, targs)
530+
if unappSym.is(Synthetic)
531+
&& (pt.resultType.asInstanceOf[MethodType].paramInfos.head.typeConstructor eq tycon) =>
532+
// Special case synthetic unapply/unapplySeq's
533+
// Provided the shapes of the types match:
534+
// the scrutinee type being unapplied and
535+
// the unapply parameter type
536+
pt.instantiate(targs).asInstanceOf[MethodType]
537+
case _ =>
528538
val locked = ctx.typerState.ownedVars
529539
val tvars = constrained(pt)
530540
val mt = pt.instantiate(tvars).asInstanceOf[MethodType]
531-
scrutineeTp <:< mt.paramInfos(0)
541+
val unapplyArgType = mt.paramInfos.head
542+
scrutineeTp <:< unapplyArgType
532543
// force type inference to infer a narrower type: could be singleton
533544
// see tests/patmat/i4227.scala
534-
mt.paramInfos(0) <:< scrutineeTp
535-
maximizeType(mt.paramInfos(0), Spans.NoSpan)
545+
unapplyArgType <:< scrutineeTp
546+
maximizeType(unapplyArgType, Spans.NoSpan)
536547
if !(ctx.typerState.ownedVars -- locked).isEmpty then
537548
// constraining can create type vars out of wildcard types
538549
// (in legalBound, by using a LevelAvoidMap)
@@ -544,7 +555,7 @@ object SpaceEngine {
544555
// but I'd rather have an unassigned new-new type var, than an infinite loop.
545556
// After all, there's nothing strictly "wrong" with unassigned type vars,
546557
// it just fails TreeChecker's linting.
547-
maximizeType(mt.paramInfos(0), Spans.NoSpan)
558+
maximizeType(unapplyArgType, Spans.NoSpan)
548559
mt
549560
}
550561

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ trait ImportSuggestions:
264264
end importSuggestions
265265

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

0 commit comments

Comments
 (0)