diff --git a/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala b/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala index 4171ff2c5886..2158056ea0fa 100644 --- a/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala +++ b/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala @@ -125,7 +125,6 @@ class ScalaSettings extends Settings.SettingGroup { val YtraceContextCreation: Setting[Boolean] = BooleanSetting("-Ytrace-context-creation", "Store stack trace of context creations.") val YshowSuppressedErrors: Setting[Boolean] = BooleanSetting("-Yshow-suppressed-errors", "Also show follow-on errors and warnings that are normally suppressed.") val YdetailedStats: Setting[Boolean] = BooleanSetting("-Ydetailed-stats", "show detailed internal compiler stats (needs Stats.enabled to be set to true).") - val Yheartbeat: Setting[Boolean] = BooleanSetting("-Yheartbeat", "show heartbeat stack trace of compiler operations (needs Stats.enabled to be set to true).") val YkindProjector: Setting[Boolean] = BooleanSetting("-Ykind-projector", "allow `*` as wildcard to be compatible with kind projector") val YprintPos: Setting[Boolean] = BooleanSetting("-Yprint-pos", "show tree positions.") val YprintPosSyms: Setting[Boolean] = BooleanSetting("-Yprint-pos-syms", "show symbol definitions positions.") diff --git a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala index b40468716616..7c62a812595c 100644 --- a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala +++ b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala @@ -1783,7 +1783,7 @@ object SymDenotations { } else computeNPMembersNamed(name) } - private[core] def computeNPMembersNamed(name: Name)(implicit ctx: Context): PreDenotation = /*>|>*/ Stats.track("computeNPMembersNamed") /*<|<*/ { + private[core] def computeNPMembersNamed(name: Name)(implicit ctx: Context): PreDenotation = { Stats.record("computeNPMembersNamed after fingerprint") ensureCompleted() val ownDenots = info.decls.denotsNamed(name, selectNonPrivate) diff --git a/compiler/src/dotty/tools/dotc/core/TypeApplications.scala b/compiler/src/dotty/tools/dotc/core/TypeApplications.scala index cb10510871f3..8e01d30039cd 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeApplications.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeApplications.scala @@ -161,7 +161,8 @@ class TypeApplications(val self: Type) extends AnyVal { * For a refinement type, the type parameters of its parent, dropping * any type parameter that is-rebound by the refinement. */ - final def typeParams(implicit ctx: Context): List[TypeParamInfo] = /*>|>*/ track("typeParams") /*<|<*/ { + final def typeParams(implicit ctx: Context): List[TypeParamInfo] = { + record("typeParams") def isTrivial(prefix: Type, tycon: Symbol) = prefix match { case prefix: ThisType => prefix.cls `eq` tycon.owner case NoPrefix => true @@ -353,7 +354,8 @@ class TypeApplications(val self: Type) extends AnyVal { * @param self = `T` * @param args = `U1,...,Un` */ - final def appliedTo(args: List[Type])(implicit ctx: Context): Type = /*>|>*/ track("appliedTo") /*<|<*/ { + final def appliedTo(args: List[Type])(implicit ctx: Context): Type = { + record("appliedTo") val typParams = self.typeParams val stripped = self.stripTypeVar val dealiased = stripped.safeDealias diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index 802aad722f69..322a46f6dff4 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -472,7 +472,8 @@ object Types { * Inherited by all type proxies. Overridden for And and Or types. * `Nil` for all other types. */ - def baseClasses(implicit ctx: Context): List[ClassSymbol] = track("baseClasses") { + def baseClasses(implicit ctx: Context): List[ClassSymbol] = { + record("baseClasses") this match { case tp: TypeProxy => tp.underlying.baseClasses @@ -501,12 +502,13 @@ object Types { * The result is either a SymDenotation or a MultiDenotation of SymDenotations. * The info(s) are the original symbol infos, no translation takes place. */ - final def decl(name: Name)(implicit ctx: Context): Denotation = track("decl") { + final def decl(name: Name)(implicit ctx: Context): Denotation = { + record("decl") findDecl(name, EmptyFlags) } /** A denotation containing the non-private declaration(s) in this type with the given name */ - final def nonPrivateDecl(name: Name)(implicit ctx: Context): Denotation = track("nonPrivateDecl") { + final def nonPrivateDecl(name: Name)(implicit ctx: Context): Denotation = { findDecl(name, Private) } @@ -526,12 +528,14 @@ object Types { } /** The member of this type with the given name */ - final def member(name: Name)(implicit ctx: Context): Denotation = /*>|>*/ track("member") /*<|<*/ { + final def member(name: Name)(implicit ctx: Context): Denotation = /*>|>*/ { + record("member") memberBasedOnFlags(name, required = EmptyFlags, excluded = EmptyFlags) } /** The non-private member of this type with the given name. */ - final def nonPrivateMember(name: Name)(implicit ctx: Context): Denotation = track("nonPrivateMember") { + final def nonPrivateMember(name: Name)(implicit ctx: Context): Denotation = { + record("nonPrivateMember") memberBasedOnFlags(name, required = EmptyFlags, excluded = Flags.Private) } @@ -759,31 +763,36 @@ object Types { } /** The set of abstract term members of this type. */ - final def abstractTermMembers(implicit ctx: Context): Seq[SingleDenotation] = track("abstractTermMembers") { + final def abstractTermMembers(implicit ctx: Context): Seq[SingleDenotation] = { + record("abstractTermMembers") memberDenots(abstractTermNameFilter, (name, buf) => buf ++= nonPrivateMember(name).altsWith(_.is(Deferred))) } /** The set of abstract type members of this type. */ - final def abstractTypeMembers(implicit ctx: Context): Seq[SingleDenotation] = track("abstractTypeMembers") { + final def abstractTypeMembers(implicit ctx: Context): Seq[SingleDenotation] = { + record("abstractTypeMembers") memberDenots(abstractTypeNameFilter, (name, buf) => buf += nonPrivateMember(name).asSingleDenotation) } /** The set of abstract type members of this type. */ - final def nonClassTypeMembers(implicit ctx: Context): Seq[SingleDenotation] = track("nonClassTypeMembers") { + final def nonClassTypeMembers(implicit ctx: Context): Seq[SingleDenotation] = { + record("nonClassTypeMembers") memberDenots(nonClassTypeNameFilter, (name, buf) => buf += member(name).asSingleDenotation) } /** The set of type alias members of this type */ - final def typeAliasMembers(implicit ctx: Context): Seq[SingleDenotation] = track("typeAlias") { + final def typeAliasMembers(implicit ctx: Context): Seq[SingleDenotation] = { + record("typeAliasMembers") memberDenots(typeAliasNameFilter, (name, buf) => buf += member(name).asSingleDenotation) } /** The set of type members of this type */ - final def typeMembers(implicit ctx: Context): Seq[SingleDenotation] = track("typeMembers") { + final def typeMembers(implicit ctx: Context): Seq[SingleDenotation] = { + record("typeMembers") memberDenots(typeNameFilter, (name, buf) => buf += member(name).asSingleDenotation) } @@ -792,31 +801,36 @@ object Types { * @param kind A subset of {Implicit, Given} that specifies what kind of implicit should * be returned */ - final def implicitMembers(kind: FlagSet)(implicit ctx: Context): List[TermRef] = track("implicitMembers") { + final def implicitMembers(kind: FlagSet)(implicit ctx: Context): List[TermRef] = { + record("implicitMembers") memberDenots(implicitFilter, (name, buf) => buf ++= member(name).altsWith(_.isOneOf(GivenOrImplicitVal & kind))) .toList.map(d => TermRef(this, d.symbol.asTerm)) } /** The set of member classes of this type */ - final def memberClasses(implicit ctx: Context): Seq[SingleDenotation] = track("memberClasses") { + final def memberClasses(implicit ctx: Context): Seq[SingleDenotation] = { + record("memberClasses") memberDenots(typeNameFilter, (name, buf) => buf ++= member(name).altsWith(x => x.isClass)) } - final def fields(implicit ctx: Context): Seq[SingleDenotation] = track("fields") { + final def fields(implicit ctx: Context): Seq[SingleDenotation] = { + record("fields") memberDenots(fieldFilter, (name, buf) => buf ++= member(name).altsWith(x => !x.is(Method))) } /** The set of members of this type that have all of `required` flags but none of `excluded` flags set. */ - final def membersBasedOnFlags(required: FlagSet, excluded: FlagSet)(implicit ctx: Context): Seq[SingleDenotation] = track("membersBasedOnFlags") { + final def membersBasedOnFlags(required: FlagSet, excluded: FlagSet)(implicit ctx: Context): Seq[SingleDenotation] = { + record("membersBasedOnFlags") memberDenots(takeAllFilter, (name, buf) => buf ++= memberBasedOnFlags(name, required, excluded).alternatives) } /** All members of this type. Warning: this can be expensive to compute! */ - final def allMembers(implicit ctx: Context): Seq[SingleDenotation] = track("allMembers") { + final def allMembers(implicit ctx: Context): Seq[SingleDenotation] = { + record("allMembers") memberDenots(takeAllFilter, (name, buf) => buf ++= member(name).alternatives) } @@ -827,7 +841,8 @@ object Types { /** This type seen as if it were the type of a member of prefix type `pre` * declared in class `cls`. */ - final def asSeenFrom(pre: Type, cls: Symbol)(implicit ctx: Context): Type = track("asSeenFrom") { + final def asSeenFrom(pre: Type, cls: Symbol)(implicit ctx: Context): Type = { + record("asSeenFrom") if (!cls.membersNeedAsSeenFrom(pre)) this else ctx.asSeenFrom(this, pre, cls) } @@ -835,19 +850,22 @@ object Types { // ----- Subtype-related -------------------------------------------- /** Is this type a subtype of that type? */ - final def <:<(that: Type)(implicit ctx: Context): Boolean = track("<:<") { + final def <:<(that: Type)(implicit ctx: Context): Boolean = { + record("<:<") ctx.typeComparer.topLevelSubType(this, that) } /** Is this type a subtype of that type? */ - final def frozen_<:<(that: Type)(implicit ctx: Context): Boolean = track("frozen_<:<") { + final def frozen_<:<(that: Type)(implicit ctx: Context): Boolean = { + record("frozen_<:<") ctx.typeComparer.isSubTypeWhenFrozen(this, that) } /** Is this type the same as that type? * This is the case iff `this <:< that` and `that <:< this`. */ - final def =:=(that: Type)(implicit ctx: Context): Boolean = track("=:=") { + final def =:=(that: Type)(implicit ctx: Context): Boolean = { + record("=:=") ctx.typeComparer.isSameType(this, that) } @@ -905,7 +923,8 @@ object Types { * (*) when matching with a Java method, we also regard Any and Object as equivalent * parameter types. */ - def matches(that: Type)(implicit ctx: Context): Boolean = track("matches") { + def matches(that: Type)(implicit ctx: Context): Boolean = { + record("matches") ctx.typeComparer.matchesType(this, that, relaxed = !ctx.phase.erasedTypes) } @@ -920,14 +939,16 @@ object Types { } /** The basetype of this type with given class symbol, NoType if `base` is not a class. */ - final def baseType(base: Symbol)(implicit ctx: Context): Type = /*trace(s"$this baseType $base")*/ /*>|>*/ track("base type") /*<|<*/ { + final def baseType(base: Symbol)(implicit ctx: Context): Type = { + record("baseType") base.denot match { case classd: ClassDenotation => classd.baseTypeOf(this) case _ => NoType } } - def & (that: Type)(implicit ctx: Context): Type = track("&") { + def & (that: Type)(implicit ctx: Context): Type = { + record("&") ctx.typeComparer.glb(this, that) } @@ -956,7 +977,8 @@ object Types { // superclass. } - def | (that: Type)(implicit ctx: Context): Type = track("|") { + def | (that: Type)(implicit ctx: Context): Type = { + record("|") ctx.typeComparer.lub(this, that) } diff --git a/compiler/src/dotty/tools/dotc/typer/Applications.scala b/compiler/src/dotty/tools/dotc/typer/Applications.scala index 61336256f20a..b00dfabf08d4 100644 --- a/compiler/src/dotty/tools/dotc/typer/Applications.scala +++ b/compiler/src/dotty/tools/dotc/typer/Applications.scala @@ -5,7 +5,7 @@ package typer import core._ import ast.{Trees, tpd, untpd} import util.Spans._ -import util.Stats.{track, record} +import util.Stats.record import util.{SourcePosition, NoSourcePosition, SourceFile} import Trees.Untyped import Contexts._ @@ -805,7 +805,7 @@ trait Applications extends Compatibility { self: Typer with Dynamic => */ def typedApply(tree: untpd.Apply, pt: Type)(implicit ctx: Context): Tree = { - def realApply(implicit ctx: Context): Tree = track("realApply") { + def realApply(implicit ctx: Context): Tree = { val originalProto = new FunProto(tree.args, IgnoredProto(pt))(this, tree.isGivenApply)(argCtx(tree)) record("typedApply") val fun1 = typedFunPart(tree.fun, originalProto) @@ -888,7 +888,7 @@ trait Applications extends Compatibility { self: Typer with Dynamic => * * { val xs = es; e' = e' + args } */ - def typedOpAssign(implicit ctx: Context): Tree = track("typedOpAssign") { + def typedOpAssign(implicit ctx: Context): Tree = { val Apply(Select(lhs, name), rhss) = tree val lhs1 = typedExpr(lhs) val liftedDefs = new mutable.ListBuffer[Tree] @@ -939,7 +939,7 @@ trait Applications extends Compatibility { self: Typer with Dynamic => cpy.NamedArg(arg)(id, argtpt1).withType(argtpt1.tpe) } - def typedTypeApply(tree: untpd.TypeApply, pt: Type)(implicit ctx: Context): Tree = track("typedTypeApply") { + def typedTypeApply(tree: untpd.TypeApply, pt: Type)(implicit ctx: Context): Tree = { if (ctx.mode.is(Mode.Pattern)) { return errorTree(tree, "invalid pattern") } @@ -992,7 +992,8 @@ trait Applications extends Compatibility { self: Typer with Dynamic => tree } - def typedUnApply(tree: untpd.Apply, selType: Type)(implicit ctx: Context): Tree = track("typedUnApply") { + def typedUnApply(tree: untpd.Apply, selType: Type)(implicit ctx: Context): Tree = { + record("typedUnApply") val Apply(qual, args) = tree def notAnExtractor(tree: Tree) = @@ -1239,8 +1240,8 @@ trait Applications extends Compatibility { self: Typer with Dynamic => * an alternative that takes more implicit parameters wins over one * that takes fewer. */ - def compare(alt1: TermRef, alt2: TermRef)(implicit ctx: Context): Int = track("compare") { trace(i"compare($alt1, $alt2)", overload) { - + def compare(alt1: TermRef, alt2: TermRef)(implicit ctx: Context): Int = trace(i"compare($alt1, $alt2)", overload) { + record("compare") assert(alt1 ne alt2) /** Is alternative `alt1` with type `tp1` as specific as alternative @@ -1412,9 +1413,10 @@ trait Applications extends Compatibility { self: Typer with Dynamic => else 1 // prefer 1st alternative with no implicits else if (strippedType2 eq fullType2) -1 // prefer 2nd alternative with no implicits else compareWithTypes(fullType1, fullType2) // continue by comparing implicits parameters - }} + } - def narrowMostSpecific(alts: List[TermRef])(implicit ctx: Context): List[TermRef] = track("narrowMostSpecific") { + def narrowMostSpecific(alts: List[TermRef])(implicit ctx: Context): List[TermRef] = { + record("narrowMostSpecific") alts match { case Nil => alts case _ :: Nil => alts @@ -1451,7 +1453,8 @@ trait Applications extends Compatibility { self: Typer with Dynamic => * Two trials: First, without implicits or SAM conversions enabled. Then, * if the first finds no eligible candidates, with implicits and SAM conversions enabled. */ - def resolveOverloaded(alts: List[TermRef], pt: Type)(implicit ctx: Context): List[TermRef] = track("resolveOverloaded") { + def resolveOverloaded(alts: List[TermRef], pt: Type)(implicit ctx: Context): List[TermRef] = { + record("resolveOverloaded") /** Is `alt` a method or polytype whose result type after the first value parameter * section conforms to the expected type `resultType`? If `resultType` @@ -1547,7 +1550,8 @@ trait Applications extends Compatibility { self: Typer with Dynamic => * called twice from the public `resolveOverloaded` method, once with * implicits and SAM conversions enabled, and once without. */ - private def resolveOverloaded(alts: List[TermRef], pt: Type, targs: List[Type])(implicit ctx: Context): List[TermRef] = track("resolveOverloaded") { + private def resolveOverloaded(alts: List[TermRef], pt: Type, targs: List[Type])(implicit ctx: Context): List[TermRef] = { + record("resolveOverloaded/2") def isDetermined(alts: List[TermRef]) = alts.isEmpty || alts.tail.isEmpty diff --git a/compiler/src/dotty/tools/dotc/typer/Implicits.scala b/compiler/src/dotty/tools/dotc/typer/Implicits.scala index 9c34f6c6c494..155d7fe237f1 100644 --- a/compiler/src/dotty/tools/dotc/typer/Implicits.scala +++ b/compiler/src/dotty/tools/dotc/typer/Implicits.scala @@ -5,7 +5,7 @@ package typer import core._ import ast.{Trees, TreeTypeMap, untpd, tpd, DesugarEnums} import util.Spans._ -import util.Stats.{track, record, monitored} +import util.Stats.{record, monitored} import printing.{Showable, Printer} import printing.Texts._ import Contexts._ @@ -90,7 +90,8 @@ object Implicits { } /** Return those references in `refs` that are compatible with type `pt`. */ - protected def filterMatching(pt: Type)(implicit ctx: Context): List[Candidate] = track("filterMatching") { + protected def filterMatching(pt: Type)(implicit ctx: Context): List[Candidate] = { + record("filterMatching") def candidateKind(ref: TermRef)(implicit ctx: Context): Candidate.Kind = /*trace(i"candidateKind $ref $pt")*/ { @@ -241,11 +242,9 @@ object Implicits { /** The candidates that are eligible for expected type `tp` */ @threadUnsafe lazy val eligible: List[Candidate] = - /*>|>*/ track("eligible in tpe") /*<|<*/ { - /*>|>*/ trace(i"eligible($tp), companions = ${companionRefs.toList}%, %", implicitsDetailed, show = true) /*<|<*/ { - if (refs.nonEmpty && monitored) record(s"check eligible refs in tpe", refs.length) - filterMatching(tp) - } + trace(i"eligible($tp), companions = ${companionRefs.toList}%, %", implicitsDetailed, show = true) { + if (refs.nonEmpty && monitored) record(s"check eligible refs in tpe", refs.length) + filterMatching(tp) } override def toString: String = @@ -283,7 +282,7 @@ object Implicits { } /** The implicit references that are eligible for type `tp`. */ - def eligible(tp: Type): List[Candidate] = /*>|>*/ track(s"eligible in ctx") /*<|<*/ { + def eligible(tp: Type): List[Candidate] = { if (tp.hash == NotCached) computeEligible(tp) else { val eligibles = eligibleCache.get(tp) @@ -540,8 +539,9 @@ trait ImplicitRunInfo { self: Run => } } - def collectCompanions(tp: Type): TermRefSet = track("computeImplicitScope") { + def collectCompanions(tp: Type): TermRefSet = trace(i"collectCompanions($tp)", implicitsDetailed) { + record("collectCompanions") def iscopeRefs(t: Type): TermRefSet = implicitScopeCache.get(t) match { case Some(is) => @@ -597,7 +597,6 @@ trait ImplicitRunInfo { self: Run => } comps } - } /** The implicit scope of type `tp` * @param isLifted Type `tp` is the result of a `liftToAnchors` application @@ -653,7 +652,8 @@ trait Implicits { self: Typer => /** Find an implicit conversion to apply to given tree `from` so that the * result is compatible with type `to`. */ - def inferView(from: Tree, to: Type)(implicit ctx: Context): SearchResult = track("inferView") { + def inferView(from: Tree, to: Type)(implicit ctx: Context): SearchResult = { + record("inferView") if ( (to isRef defn.AnyClass) || (to isRef defn.ObjectClass) || (to isRef defn.UnitClass) @@ -1287,11 +1287,12 @@ trait Implicits { self: Typer => * it should be applied, EmptyTree otherwise. * @param span The position where errors should be reported. */ - def inferImplicit(pt: Type, argument: Tree, span: Span)(implicit ctx: Context): SearchResult = track("inferImplicit") { - assert(ctx.phase.allowsImplicitSearch, - if (argument.isEmpty) i"missing implicit parameter of type $pt after typer" - else i"type error: ${argument.tpe} does not conform to $pt${err.whyNoMatchStr(argument.tpe, pt)}") + def inferImplicit(pt: Type, argument: Tree, span: Span)(implicit ctx: Context): SearchResult = trace(s"search implicit ${pt.show}, arg = ${argument.show}: ${argument.tpe.show}", implicits, show = true) { + record("inferImplicit") + assert(ctx.phase.allowsImplicitSearch, + if (argument.isEmpty) i"missing implicit parameter of type $pt after typer" + else i"type error: ${argument.tpe} does not conform to $pt${err.whyNoMatchStr(argument.tpe, pt)}") val result0 = try { new ImplicitSearch(pt, argument, span).bestImplicit(contextual = true) @@ -1332,7 +1333,6 @@ trait Implicits { self: Typer => // If we are at the outermost implicit search then emit the implicit dictionary, if any. ctx.searchHistory.emitDictionary(span, result) } - } /** An implicit search; parameters as in `inferImplicit` */ class ImplicitSearch(protected val pt: Type, protected val argument: Tree, span: Span)(implicit ctx: Context) { @@ -1359,48 +1359,50 @@ trait Implicits { self: Typer => //println(i"search implicits $pt / ${eligible.map(_.ref)}") /** Try to typecheck an implicit reference */ - def typedImplicit(cand: Candidate, contextual: Boolean)(implicit ctx: Context): SearchResult = track("typedImplicit") { trace(i"typed implicit ${cand.ref}, pt = $pt, implicitsEnabled == ${ctx.mode is ImplicitsEnabled}", implicits, show = true) { - val ref = cand.ref - val generated: Tree = tpd.ref(ref).withSpan(span.startPos) - val locked = ctx.typerState.ownedVars - val adapted = - if (argument.isEmpty) - adapt(generated, pt.widenExpr, locked) - else { - val untpdGenerated = untpd.TypedSplice(generated) - def tryConversion(implicit ctx: Context) = - typed( - untpd.Apply(untpdGenerated, untpd.TypedSplice(argument) :: Nil), - pt, locked) - if (cand.isExtension) { - val SelectionProto(name: TermName, mbrType, _, _) = pt - val result = extMethodApply(untpd.Select(untpdGenerated, name), argument, mbrType) - if (!ctx.reporter.hasErrors && cand.isConversion) { - val testCtx = ctx.fresh.setExploreTyperState() - tryConversion(testCtx) - if (testCtx.reporter.hasErrors) - ctx.error(em"ambiguous implicit: $generated is eligible both as an implicit conversion and as an extension method container") + def typedImplicit(cand: Candidate, contextual: Boolean)(implicit ctx: Context): SearchResult = + trace(i"typed implicit ${cand.ref}, pt = $pt, implicitsEnabled == ${ctx.mode is ImplicitsEnabled}", implicits, show = true) { + record("typedImplicit") + val ref = cand.ref + val generated: Tree = tpd.ref(ref).withSpan(span.startPos) + val locked = ctx.typerState.ownedVars + val adapted = + if (argument.isEmpty) + adapt(generated, pt.widenExpr, locked) + else { + val untpdGenerated = untpd.TypedSplice(generated) + def tryConversion(implicit ctx: Context) = + typed( + untpd.Apply(untpdGenerated, untpd.TypedSplice(argument) :: Nil), + pt, locked) + if (cand.isExtension) { + val SelectionProto(name: TermName, mbrType, _, _) = pt + val result = extMethodApply(untpd.Select(untpdGenerated, name), argument, mbrType) + if (!ctx.reporter.hasErrors && cand.isConversion) { + val testCtx = ctx.fresh.setExploreTyperState() + tryConversion(testCtx) + if (testCtx.reporter.hasErrors) + ctx.error(em"ambiguous implicit: $generated is eligible both as an implicit conversion and as an extension method container") + } + result } - result + else tryConversion } - else tryConversion - } - if (ctx.reporter.hasErrors) { - ctx.reporter.removeBufferedMessages - SearchFailure { - adapted.tpe match { - case _: SearchFailureType => adapted - case _ => adapted.withType(new MismatchedImplicit(ref, pt, argument)) + if (ctx.reporter.hasErrors) { + ctx.reporter.removeBufferedMessages + SearchFailure { + adapted.tpe match { + case _: SearchFailureType => adapted + case _ => adapted.withType(new MismatchedImplicit(ref, pt, argument)) + } } } + else { + val returned = + if (cand.isExtension) Applications.ExtMethodApply(adapted) + else adapted + SearchSuccess(returned, ref, cand.level)(ctx.typerState, ctx.gadt) + } } - else { - val returned = - if (cand.isExtension) Applications.ExtMethodApply(adapted) - else adapted - SearchSuccess(returned, ref, cand.level)(ctx.typerState, ctx.gadt) - } - }} /** Try to type-check implicit reference, after checking that this is not * a diverging search diff --git a/compiler/src/dotty/tools/dotc/typer/Inferencing.scala b/compiler/src/dotty/tools/dotc/typer/Inferencing.scala index 21112947297b..45c7c74ae459 100644 --- a/compiler/src/dotty/tools/dotc/typer/Inferencing.scala +++ b/compiler/src/dotty/tools/dotc/typer/Inferencing.scala @@ -258,7 +258,8 @@ object Inferencing { * @return The list of type symbols that were created * to instantiate undetermined type variables that occur non-variantly */ - def maximizeType(tp: Type, span: Span, fromScala2x: Boolean)(implicit ctx: Context): List[Symbol] = Stats.track("maximizeType") { + def maximizeType(tp: Type, span: Span, fromScala2x: Boolean)(implicit ctx: Context): List[Symbol] = { + Stats.record("maximizeType") val vs = variances(tp) val patternBound = new mutable.ListBuffer[Symbol] vs foreachBinding { (tvar, v) => @@ -301,7 +302,8 @@ object Inferencing { * * we want to instantiate U to x.type right away. No need to wait further. */ - private def variances(tp: Type)(implicit ctx: Context): VarianceMap = Stats.track("variances") { + private def variances(tp: Type)(implicit ctx: Context): VarianceMap = { + Stats.record("variances") val constraint = ctx.typerState.constraint object accu extends TypeAccumulator[VarianceMap] { diff --git a/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala b/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala index 9f83157981b5..398376aa0de3 100644 --- a/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala +++ b/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala @@ -544,7 +544,8 @@ object ProtoTypes { * of toString method. The problem is solved by dereferencing nullary method types if the corresponding * function type is not compatible with the prototype. */ - def normalize(tp: Type, pt: Type)(implicit ctx: Context): Type = Stats.track("normalize") { + def normalize(tp: Type, pt: Type)(implicit ctx: Context): Type = { + Stats.record("normalize") tp.widenSingleton match { case poly: PolyType => normalize(constrained(poly).resultType, pt) diff --git a/compiler/src/dotty/tools/dotc/typer/QuotesAndSplices.scala b/compiler/src/dotty/tools/dotc/typer/QuotesAndSplices.scala index 9d4302fb8df3..e10303726109 100644 --- a/compiler/src/dotty/tools/dotc/typer/QuotesAndSplices.scala +++ b/compiler/src/dotty/tools/dotc/typer/QuotesAndSplices.scala @@ -18,7 +18,7 @@ import dotty.tools.dotc.reporting._ import dotty.tools.dotc.typer.Implicits._ import dotty.tools.dotc.typer.Inferencing._ import dotty.tools.dotc.util.Spans._ -import dotty.tools.dotc.util.Stats.track +import dotty.tools.dotc.util.Stats.record import scala.collection.mutable @@ -34,7 +34,8 @@ trait QuotesAndSplices { self: Typer => /** Translate `'{ t }` into `scala.quoted.Expr.apply(t)` and `'[T]` into `scala.quoted.Type.apply[T]` * while tracking the quotation level in the context. */ - def typedQuote(tree: untpd.Quote, pt: Type)(implicit ctx: Context): Tree = track("typedQuote") { + def typedQuote(tree: untpd.Quote, pt: Type)(implicit ctx: Context): Tree = { + record("typedQuote") val qctx = inferImplicitArg(defn.QuoteContextClass.typeRef, tree.span) if (level == 0 && qctx.tpe.isInstanceOf[SearchFailureType]) ctx.error(missingArgMsg(qctx, defn.QuoteContextClass.typeRef, ""), ctx.source.atSpan(tree.span)) @@ -57,7 +58,8 @@ trait QuotesAndSplices { self: Typer => } /** Translate `${ t: Expr[T] }` into expression `t.splice` while tracking the quotation level in the context */ - def typedSplice(tree: untpd.Splice, pt: Type)(implicit ctx: Context): Tree = track("typedSplice") { + def typedSplice(tree: untpd.Splice, pt: Type)(implicit ctx: Context): Tree = { + record("typedSplice") checkSpliceOutsideQuote(tree) tree.expr match { case untpd.Quote(innerExpr) if innerExpr.isTerm => @@ -92,7 +94,8 @@ trait QuotesAndSplices { self: Typer => } /** Translate ${ t: Type[T] }` into type `t.splice` while tracking the quotation level in the context */ - def typedTypSplice(tree: untpd.TypSplice, pt: Type)(implicit ctx: Context): Tree = track("typedTypSplice") { + def typedTypSplice(tree: untpd.TypSplice, pt: Type)(implicit ctx: Context): Tree = { + record("typedTypSplice") ctx.compilationUnit.needsStaging = true checkSpliceOutsideQuote(tree) tree.expr match { diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index 00289794ee73..237531d01fcb 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -32,7 +32,7 @@ import Applications.{ExtMethodApply, IntegratedTypeArgs, productSelectorTypes, w import collection.mutable import annotation.tailrec import Implicits._ -import util.Stats.{record, track} +import util.Stats.record import config.Printers.{gadts, typr} import rewrites.Rewrites.patch import NavigateAST._ @@ -363,10 +363,9 @@ class Typer extends Namer * (2) Change imported symbols to selections. * (3) Change pattern Idents id (but not wildcards) to id @ _ */ - def typedIdent(tree: untpd.Ident, pt: Type)(implicit ctx: Context): Tree = track("typedIdent") { + def typedIdent(tree: untpd.Ident, pt: Type)(implicit ctx: Context): Tree = { + record("typedIdent") val name = tree.name - - // begin typedIdent def kind = if (name.isTermName) "" else "type " typr.println(s"typed ident $kind$name in ${ctx.owner}") if (ctx.mode is Mode.Pattern) { @@ -458,7 +457,8 @@ class Typer extends Namer else typedDynamicSelect(tree, Nil, pt) } - def typedSelect(tree: untpd.Select, pt: Type)(implicit ctx: Context): Tree = track("typedSelect") { + def typedSelect(tree: untpd.Select, pt: Type)(implicit ctx: Context): Tree = { + record("typedSelect") def typeSelectOnTerm(implicit ctx: Context): Tree = typedSelect(tree, pt, typedExpr(tree.qualifier, selectionProto(tree.name, pt, this))) @@ -487,11 +487,12 @@ class Typer extends Namer typeSelectOnTerm(ctx) } - def typedThis(tree: untpd.This)(implicit ctx: Context): Tree = track("typedThis") { + def typedThis(tree: untpd.This)(implicit ctx: Context): Tree = { + record("typedThis") assignType(tree) } - def typedSuper(tree: untpd.Super, pt: Type)(implicit ctx: Context): Tree = track("typedSuper") { + def typedSuper(tree: untpd.Super, pt: Type)(implicit ctx: Context): Tree = { val qual1 = typed(tree.qual) val inConstrCall = pt match { case pt: SelectionProto if pt.name == nme.CONSTRUCTOR => true @@ -508,13 +509,13 @@ class Typer extends Namer } } - def typedLiteral(tree: untpd.Literal)(implicit ctx: Context): Tree = track("typedLiteral") { + def typedLiteral(tree: untpd.Literal)(implicit ctx: Context): Tree = { val tree1 = assignType(tree) if (ctx.mode.is(Mode.Type)) tpd.SingletonTypeTree(tree1) // this ensures that tree is classified as a type tree else tree1 } - def typedNew(tree: untpd.New, pt: Type)(implicit ctx: Context): Tree = track("typedNew") { + def typedNew(tree: untpd.New, pt: Type)(implicit ctx: Context): Tree = { tree.tpt match { case templ: untpd.Template => import untpd._ @@ -551,7 +552,8 @@ class Typer extends Namer } } - def typedTyped(tree: untpd.Typed, pt: Type)(implicit ctx: Context): Tree = track("typedTyped") { + def typedTyped(tree: untpd.Typed, pt: Type)(implicit ctx: Context): Tree = { + /* Handles three cases: * @param ifPat how to handle a pattern (_: T) * @param ifExpr how to handle an expression (e: T) @@ -635,12 +637,12 @@ class Typer extends Namer case _ => tree } - def typedNamedArg(tree: untpd.NamedArg, pt: Type)(implicit ctx: Context): NamedArg = track("typedNamedArg") { + def typedNamedArg(tree: untpd.NamedArg, pt: Type)(implicit ctx: Context): NamedArg = { val arg1 = typed(tree.arg, pt) assignType(cpy.NamedArg(tree)(tree.name, arg1), arg1) } - def typedAssign(tree: untpd.Assign, pt: Type)(implicit ctx: Context): Tree = track("typedAssign") { + def typedAssign(tree: untpd.Assign, pt: Type)(implicit ctx: Context): Tree = { tree.lhs match { case lhs @ Apply(fn, args) => typed(untpd.Apply(untpd.Select(fn, nme.update), args :+ tree.rhs), pt) @@ -702,7 +704,7 @@ class Typer extends Namer def typedBlockStats(stats: List[untpd.Tree])(implicit ctx: Context): (Context, List[tpd.Tree]) = (index(stats), typedStats(stats, ctx.owner)) - def typedBlock(tree: untpd.Block, pt: Type)(implicit ctx: Context): Tree = track("typedBlock") { + def typedBlock(tree: untpd.Block, pt: Type)(implicit ctx: Context): Tree = { val (exprCtx, stats1) = typedBlockStats(tree.stats) val expr1 = typedExpr(tree.expr, pt.dropIfProto)(exprCtx) ensureNoLocalRefs( @@ -747,7 +749,7 @@ class Typer extends Namer } } - def typedIf(tree: untpd.If, pt: Type)(implicit ctx: Context): Tree = track("typedIf") { + def typedIf(tree: untpd.If, pt: Type)(implicit ctx: Context): Tree = { if (tree.isInline) checkInInlineContext("inline if", tree.posd) val cond1 = typed(tree.cond, defn.BooleanType) @@ -796,7 +798,7 @@ class Typer extends Namer } } - def typedFunction(tree: untpd.Function, pt: Type)(implicit ctx: Context): Tree = track("typedFunction") { + def typedFunction(tree: untpd.Function, pt: Type)(implicit ctx: Context): Tree = { if (ctx.mode is Mode.Type) typedFunctionType(tree, pt) else typedFunctionValue(tree, pt) } @@ -979,7 +981,7 @@ class Typer extends Namer typed(desugared, pt) } - def typedClosure(tree: untpd.Closure, pt: Type)(implicit ctx: Context): Tree = track("typedClosure") { + def typedClosure(tree: untpd.Closure, pt: Type)(implicit ctx: Context): Tree = { val env1 = tree.env mapconserve (typed(_)) val meth1 = typedUnadapted(tree.meth) val target = @@ -1017,7 +1019,7 @@ class Typer extends Namer assignType(cpy.Closure(tree)(env1, meth1, target), meth1, target) } - def typedMatch(tree: untpd.Match, pt: Type)(implicit ctx: Context): Tree = track("typedMatch") { + def typedMatch(tree: untpd.Match, pt: Type)(implicit ctx: Context): Tree = { tree.selector match { case EmptyTree => if (tree.isInline) { @@ -1094,7 +1096,7 @@ class Typer extends Namer } /** Type a case. */ - def typedCase(tree: untpd.CaseDef, selType: Type, pt: Type)(implicit ctx: Context): CaseDef = track("typedCase") { + def typedCase(tree: untpd.CaseDef, selType: Type, pt: Type)(implicit ctx: Context): CaseDef = { val originalCtx = ctx val gadtCtx: Context = ctx.fresh.setFreshGADTBounds @@ -1111,7 +1113,7 @@ class Typer extends Namer caseRest(pat1)(gadtCtx.fresh.setNewScope) } - def typedLabeled(tree: untpd.Labeled)(implicit ctx: Context): Labeled = track("typedLabeled") { + def typedLabeled(tree: untpd.Labeled)(implicit ctx: Context): Labeled = { val bind1 = typedBind(tree.bind, WildcardType).asInstanceOf[Bind] val expr1 = typed(tree.expr, bind1.symbol.info) assignType(cpy.Labeled(tree)(bind1, expr1)) @@ -1129,7 +1131,7 @@ class Typer extends Namer } - def typedReturn(tree: untpd.Return)(implicit ctx: Context): Return = track("typedReturn") { + def typedReturn(tree: untpd.Return)(implicit ctx: Context): Return = { def returnProto(owner: Symbol, locals: Scope): Type = if (owner.isConstructor) defn.UnitType else owner.info match { @@ -1175,7 +1177,7 @@ class Typer extends Namer assignType(cpy.Return(tree)(expr1, from)) } - def typedWhileDo(tree: untpd.WhileDo)(implicit ctx: Context): Tree = track("typedWhileDo") { + def typedWhileDo(tree: untpd.WhileDo)(implicit ctx: Context): Tree = { val cond1 = if (tree.cond eq EmptyTree) EmptyTree else typed(tree.cond, defn.BooleanType) @@ -1183,7 +1185,7 @@ class Typer extends Namer assignType(cpy.WhileDo(tree)(cond1, body1)) } - def typedTry(tree: untpd.Try, pt: Type)(implicit ctx: Context): Try = track("typedTry") { + def typedTry(tree: untpd.Try, pt: Type)(implicit ctx: Context): Try = { val expr2 :: cases2x = harmonic(harmonize, pt) { val expr1 = typed(tree.expr, pt.dropIfProto) val cases1 = typedCases(tree.cases, defn.ThrowableType, pt.dropIfProto) @@ -1194,12 +1196,12 @@ class Typer extends Namer assignType(cpy.Try(tree)(expr2, cases2, finalizer1), expr2, cases2) } - def typedThrow(tree: untpd.Throw)(implicit ctx: Context): Tree = track("typedThrow") { + def typedThrow(tree: untpd.Throw)(implicit ctx: Context): Tree = { val expr1 = typed(tree.expr, defn.ThrowableType) Throw(expr1).withSpan(tree.span) } - def typedSeqLiteral(tree: untpd.SeqLiteral, pt: Type)(implicit ctx: Context): SeqLiteral = track("typedSeqLiteral") { + def typedSeqLiteral(tree: untpd.SeqLiteral, pt: Type)(implicit ctx: Context): SeqLiteral = { val elemProto = pt.elemType match { case NoType => WildcardType case bounds: TypeBounds => WildcardType(bounds) @@ -1234,7 +1236,7 @@ class Typer extends Namer bindings1, expansion1) } - def typedTypeTree(tree: untpd.TypeTree, pt: Type)(implicit ctx: Context): Tree = track("typedTypeTree") { + def typedTypeTree(tree: untpd.TypeTree, pt: Type)(implicit ctx: Context): Tree = { tree match { case tree: untpd.DerivedTypeTree => tree.ensureCompletions @@ -1256,13 +1258,13 @@ class Typer extends Namer } } - def typedSingletonTypeTree(tree: untpd.SingletonTypeTree)(implicit ctx: Context): SingletonTypeTree = track("typedSingletonTypeTree") { + def typedSingletonTypeTree(tree: untpd.SingletonTypeTree)(implicit ctx: Context): SingletonTypeTree = { val ref1 = typedExpr(tree.ref) checkStable(ref1.tpe, tree.sourcePos) assignType(cpy.SingletonTypeTree(tree)(ref1), ref1) } - def typedRefinedTypeTree(tree: untpd.RefinedTypeTree)(implicit ctx: Context): TypTree = track("typedRefinedTypeTree") { + def typedRefinedTypeTree(tree: untpd.RefinedTypeTree)(implicit ctx: Context): TypTree = { val tpt1 = if (tree.tpt.isEmpty) TypeTree(defn.ObjectType) else typedAheadType(tree.tpt) val refineClsDef = desugar.refinedTypeToClass(tpt1, tree.refinements).withSpan(tree.span) val refineCls = createSymbol(refineClsDef).asClass @@ -1287,7 +1289,7 @@ class Typer extends Namer assignType(cpy.RefinedTypeTree(tree)(tpt1, refinements1), tpt1, refinements1, refineCls) } - def typedAppliedTypeTree(tree: untpd.AppliedTypeTree)(implicit ctx: Context): Tree = track("typedAppliedTypeTree") { + def typedAppliedTypeTree(tree: untpd.AppliedTypeTree)(implicit ctx: Context): Tree = { val tpt1 = typed(tree.tpt, AnyTypeConstructorProto)(ctx.retractMode(Mode.Pattern)) val tparams = tpt1.tpe.typeParams if (tparams.isEmpty) { @@ -1355,7 +1357,7 @@ class Typer extends Namer } } - def typedLambdaTypeTree(tree: untpd.LambdaTypeTree)(implicit ctx: Context): Tree = track("typedLambdaTypeTree") { + def typedLambdaTypeTree(tree: untpd.LambdaTypeTree)(implicit ctx: Context): Tree = { val LambdaTypeTree(tparams, body) = tree index(tparams) val tparams1 = tparams.mapconserve(typed(_).asInstanceOf[TypeDef]) @@ -1373,12 +1375,12 @@ class Typer extends Namer assignType(cpy.MatchTypeTree(tree)(bound1, sel1, cases1), bound1, sel1, cases1) } - def typedByNameTypeTree(tree: untpd.ByNameTypeTree)(implicit ctx: Context): ByNameTypeTree = track("typedByNameTypeTree") { + def typedByNameTypeTree(tree: untpd.ByNameTypeTree)(implicit ctx: Context): ByNameTypeTree = { val result1 = typed(tree.result) assignType(cpy.ByNameTypeTree(tree)(result1), result1) } - def typedTypeBoundsTree(tree: untpd.TypeBoundsTree, pt: Type)(implicit ctx: Context): Tree = track("typedTypeBoundsTree") { + def typedTypeBoundsTree(tree: untpd.TypeBoundsTree, pt: Type)(implicit ctx: Context): Tree = { val TypeBoundsTree(lo, hi) = tree val lo1 = typed(lo) val hi1 = typed(hi) @@ -1403,7 +1405,7 @@ class Typer extends Namer else tree1 } - def typedBind(tree: untpd.Bind, pt: Type)(implicit ctx: Context): Tree = track("typedBind") { + def typedBind(tree: untpd.Bind, pt: Type)(implicit ctx: Context): Tree = { val pt1 = fullyDefinedType(pt, "pattern variable", tree.span) val body1 = typed(tree.body, pt1) body1 match { @@ -1431,7 +1433,7 @@ class Typer extends Namer } } - def typedAlternative(tree: untpd.Alternative, pt: Type)(implicit ctx: Context): Alternative = track("typedAlternative") { + def typedAlternative(tree: untpd.Alternative, pt: Type)(implicit ctx: Context): Alternative = { val nestedCtx = ctx.addMode(Mode.InPatternAlternative) val trees1 = tree.trees.mapconserve(typed(_, pt)(nestedCtx)) assignType(cpy.Alternative(tree)(trees1), trees1) @@ -1461,11 +1463,11 @@ class Typer extends Namer untpd.modsDeco(mdef).mods.annotations.foreach(typedAnnotation(_)(annotCtx)) } - def typedAnnotation(annot: untpd.Tree)(implicit ctx: Context): Tree = track("typedAnnotation") { + def typedAnnotation(annot: untpd.Tree)(implicit ctx: Context): Tree = { typed(annot, defn.AnnotationClass.typeRef) } - def typedValDef(vdef: untpd.ValDef, sym: Symbol)(implicit ctx: Context): Tree = track("typedValDef") { + def typedValDef(vdef: untpd.ValDef, sym: Symbol)(implicit ctx: Context): Tree = { val ValDef(name, tpt, _) = vdef completeAnnotations(vdef, sym) if (sym.isOneOf(GivenOrImplicit)) checkImplicitConversionDefOK(sym) @@ -1502,7 +1504,7 @@ class Typer extends Namer } } - def typedDefDef(ddef: untpd.DefDef, sym: Symbol)(implicit ctx: Context): Tree = track("typedDefDef") { + def typedDefDef(ddef: untpd.DefDef, sym: Symbol)(implicit ctx: Context): Tree = { if (!sym.info.exists) { // it's a discarded synthetic case class method, drop it assert(sym.is(Synthetic) && desugar.isRetractableCaseClassMethodName(sym.name)) sym.owner.info.decls.openForMutations.unlink(sym) @@ -1563,7 +1565,7 @@ class Typer extends Namer //todo: make sure dependent method types do not depend on implicits or by-name params } - def typedTypeDef(tdef: untpd.TypeDef, sym: Symbol)(implicit ctx: Context): Tree = track("typedTypeDef") { + def typedTypeDef(tdef: untpd.TypeDef, sym: Symbol)(implicit ctx: Context): Tree = { val TypeDef(name, rhs) = tdef completeAnnotations(tdef, sym) val rhs1 = tdef.rhs match { @@ -1577,7 +1579,7 @@ class Typer extends Namer assignType(cpy.TypeDef(tdef)(name, rhs1), sym) } - def typedClassDef(cdef: untpd.TypeDef, cls: ClassSymbol)(implicit ctx: Context): Tree = track("typedClassDef") { + def typedClassDef(cdef: untpd.TypeDef, cls: ClassSymbol)(implicit ctx: Context): Tree = { if (!cls.info.isInstanceOf[ClassInfo]) return EmptyTree.assertingErrorsReported val TypeDef(name, impl @ Template(constr, _, self, _)) = cdef @@ -1773,7 +1775,7 @@ class Typer extends Namer def localDummy(cls: ClassSymbol, impl: untpd.Template)(implicit ctx: Context): Symbol = ctx.newLocalDummy(cls, impl.span) - def typedImport(imp: untpd.Import, sym: Symbol)(implicit ctx: Context): Import = track("typedImport") { + def typedImport(imp: untpd.Import, sym: Symbol)(implicit ctx: Context): Import = { val expr1 = typedExpr(imp.expr, AnySelectionProto) checkLegalImportPath(expr1) val selectors1: List[untpd.Tree] = imp.selectors map { @@ -1784,7 +1786,7 @@ class Typer extends Namer assignType(cpy.Import(imp)(imp.importGiven, expr1, selectors1), sym) } - def typedPackageDef(tree: untpd.PackageDef)(implicit ctx: Context): Tree = track("typedPackageDef") { + def typedPackageDef(tree: untpd.PackageDef)(implicit ctx: Context): Tree = { val pid1 = typedExpr(tree.pid, AnySelectionProto)(ctx.addMode(Mode.InPackageClauseName)) val pkg = pid1.symbol pid1 match { @@ -1799,7 +1801,7 @@ class Typer extends Namer } } - def typedAnnotated(tree: untpd.Annotated, pt: Type)(implicit ctx: Context): Tree = track("typedAnnotated") { + def typedAnnotated(tree: untpd.Annotated, pt: Type)(implicit ctx: Context): Tree = { val annot1 = typedExpr(tree.annot, defn.AnnotationClass.typeRef) val arg1 = typed(tree.arg, pt) if (ctx.mode is Mode.Type) { @@ -2389,11 +2391,11 @@ class Typer extends Namer * If all this fails, error * Parameters as for `typedUnadapted`. */ - def adapt(tree: Tree, pt: Type, locked: TypeVars)(implicit ctx: Context): Tree = track("adapt") { + def adapt(tree: Tree, pt: Type, locked: TypeVars)(implicit ctx: Context): Tree = trace(i"adapting $tree to $pt", typr, show = true) { + record("adapt") adapt1(tree, pt, locked) } - } final def adapt(tree: Tree, pt: Type)(implicit ctx: Context): Tree = { adapt(tree, pt, ctx.typerState.ownedVars) diff --git a/compiler/src/dotty/tools/dotc/util/Stats.scala b/compiler/src/dotty/tools/dotc/util/Stats.scala index 746b5e554e8d..0f2bf8eeaf21 100644 --- a/compiler/src/dotty/tools/dotc/util/Stats.scala +++ b/compiler/src/dotty/tools/dotc/util/Stats.scala @@ -11,9 +11,6 @@ import collection.mutable final val enabled = false - /** The period in ms in which stack snapshots are displayed */ - final val HeartBeatPeriod = 250 - var monitored: Boolean = false @volatile private[this] var stack: List[String] = Nil @@ -32,18 +29,6 @@ import collection.mutable hits(name) += n } - @forceInline - def track[T](fn: String)(op: => T): T = - if (enabled) doTrack(fn)(op) else op - - def doTrack[T](fn: String)(op: => T): T = - if (monitored) { - stack = fn :: stack - record(fn) - try op - finally stack = stack.tail - } else op - @forceInline def trackTime[T](fn: String)(op: => T): T = if (enabled) doTrackTime(fn)(op) else op @@ -56,25 +41,6 @@ import collection.mutable } else op1 } - class HeartBeat extends Thread() { - @volatile private[Stats] var continue: Boolean = true - - private def printStack(stack: List[String]): Unit = stack match { - case str :: rest => - printStack(rest) - print(s"-> $str ") - case Nil => - println() - print("|") - } - - override final def run(): Unit = { - Thread.sleep(HeartBeatPeriod) - printStack(stack) - if (continue) run() - } - } - final val GroupChar = '/' /** Aggregate all counts of all keys with a common prefix, followed by `:` */ @@ -88,12 +54,9 @@ import collection.mutable def maybeMonitored[T](op: => T)(implicit ctx: Context): T = { if (ctx.settings.YdetailedStats.value) { - val hb = new HeartBeat() - if (ctx.settings.Yheartbeat.value) hb.start() monitored = true try op finally { - hb.continue = false aggregate() println() println(hits.toList.sortBy(_._2).map{ case (x, y) => s"$x -> $y" } mkString "\n")