Skip to content

Fix bootstrap 2 #1271

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 26 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
f36c21e
Avoid merging denotations of different symbols in same class
odersky May 1, 2016
cc0f629
Don't copy Any constructor to Object in Erasure
odersky May 1, 2016
d0f05ad
ResolveOverloaded should handle alternatives that are the same TermRef
odersky May 1, 2016
2dd6a7a
Test case
odersky May 1, 2016
968f1ab
Fix test case
odersky May 2, 2016
48b7160
Issue MergeError exception for double def situations
odersky May 2, 2016
f722de7
A test case for overloading/overriding interactions
odersky May 2, 2016
fe5f4f3
Revert: ResolveOverloaded should handle alternatives that are the sam…
odersky May 2, 2016
9aa800f
Refined handling of atSignature
odersky May 2, 2016
3a97b3f
Another test case involving super accessors
odersky May 3, 2016
b26b725
Handle MergeErrors in RefChecks
odersky May 3, 2016
c9ac3d7
Remove stray test
odersky May 16, 2016
c29e975
Fix dotc bootstrap failure
odersky May 19, 2016
f1d95c2
Fix test
odersky May 19, 2016
c87c030
Better doc comment
odersky May 19, 2016
77642b9
Two more tests
odersky May 19, 2016
f4e7f84
Use source module ref as assumed self type when reading Tasty
odersky May 19, 2016
ad73126
Disable stub checking
odersky May 19, 2016
87489f5
Further improve doc comment
odersky May 20, 2016
1e3b0e1
Decouple annotation transformers from info transformers
odersky May 20, 2016
40696ba
Instrument Denotations#current to find CyclicReference
odersky May 20, 2016
2443760
Don't force a symbol's denotation for isTerm/isType
odersky May 20, 2016
09eddd0
Make sure local data is unpickled at right phase
odersky May 20, 2016
daf736c
Replace aliases to Unit by Unit
odersky May 20, 2016
4755570
Fix withPhaseNoLater
odersky May 20, 2016
e0c2e4d
Remove fingerprinting
odersky May 20, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion src/dotty/annotation/internal/Child.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,15 @@ package dotty.annotation.internal

import scala.annotation.Annotation

/** An annotation to indicate a child class or object of the annotated class. */
/** An annotation to indicate a child class or object of the annotated class.
* E.g. if we have
*
* sealed class A
* case class B() extends A
* case class C() extends A
*
* Then the class symbol `A` would carry the annotations
* `@Child[Bref] @Child[Cref]` where `Bref`, `Cref` are TypeRefs
* referring to the class symbols of `B` and `C`
*/
class Child[T] extends Annotation
1 change: 0 additions & 1 deletion src/dotty/tools/dotc/config/Config.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ object Config {

final val cacheMembersNamed = true
final val cacheAsSeenFrom = true
final val useFingerPrints = true // note: it currently seems to be slightly faster not to use them! my junit test: 548s without, 560s with.
final val cacheMemberNames = true
final val cacheImplicitScopes = true

Expand Down
2 changes: 1 addition & 1 deletion src/dotty/tools/dotc/core/Contexts.scala
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ object Contexts {
withPhase(phase.id)

final def withPhaseNoLater(phase: Phase) =
if (ctx.phase.id > phase.id) withPhase(phase) else ctx
if (phase.exists && ctx.phase.id > phase.id) withPhase(phase) else ctx

/** If -Ydebug is on, the top of the stack trace where this context
* was created, otherwise `null`.
Expand Down
72 changes: 55 additions & 17 deletions src/dotty/tools/dotc/core/Denotations.scala
Original file line number Diff line number Diff line change
Expand Up @@ -122,11 +122,11 @@ object Denotations {
/** The signature of the denotation. */
def signature(implicit ctx: Context): Signature

/** Resolve overloaded denotation to pick the one with the given signature
/** Resolve overloaded denotation to pick the ones with the given signature
* when seen from prefix `site`.
* @param relaxed When true, consider only parameter signatures for a match.
*/
def atSignature(sig: Signature, site: Type = NoPrefix, relaxed: Boolean = false)(implicit ctx: Context): SingleDenotation
def atSignature(sig: Signature, site: Type = NoPrefix, relaxed: Boolean = false)(implicit ctx: Context): Denotation

/** The variant of this denotation that's current in the given context, or
* `NotDefinedHereDenotation` if this denotation does not exist at current phase, but
Expand Down Expand Up @@ -157,7 +157,10 @@ object Denotations {
* or NoDenotation if no satisfying alternative exists.
* @throws TypeError if there is at more than one alternative that satisfies `p`.
*/
def suchThat(p: Symbol => Boolean): SingleDenotation
def suchThat(p: Symbol => Boolean)(implicit ctx: Context): SingleDenotation

/** If this is a SingleDenotation, return it, otherwise throw a TypeError */
def checkUnique(implicit ctx: Context): SingleDenotation = suchThat(alwaysTrue)

/** Does this denotation have an alternative that satisfies the predicate `p`? */
def hasAltWith(p: SingleDenotation => Boolean): Boolean
Expand Down Expand Up @@ -227,13 +230,17 @@ object Denotations {
/** The alternative of this denotation that has a type matching `targetType` when seen
* as a member of type `site`, `NoDenotation` if none exists.
*/
def matchingDenotation(site: Type, targetType: Type)(implicit ctx: Context): SingleDenotation =
if (isOverloaded)
atSignature(targetType.signature, site, relaxed = true).matchingDenotation(site, targetType)
else if (exists && !site.memberInfo(symbol).matchesLoosely(targetType))
NoDenotation
else
asSingleDenotation
def matchingDenotation(site: Type, targetType: Type)(implicit ctx: Context): SingleDenotation = {
def qualifies(sym: Symbol) = site.memberInfo(sym).matchesLoosely(targetType)
if (isOverloaded) {
atSignature(targetType.signature, site, relaxed = true) match {
case sd: SingleDenotation => sd.matchingDenotation(site, targetType)
case md => md.suchThat(qualifies(_))
}
}
else if (exists && !qualifies(symbol)) NoDenotation
else asSingleDenotation
}

/** Form a denotation by conjoining with denotation `that`.
*
Expand Down Expand Up @@ -282,8 +289,10 @@ object Denotations {
val info2 = denot2.info
val sym1 = denot1.symbol
val sym2 = denot2.symbol
val sym2Accessible = sym2.isAccessibleFrom(pre)

if (isDoubleDef(sym1, sym2)) doubleDefError(denot1, denot2, pre)

val sym2Accessible = sym2.isAccessibleFrom(pre)
/** Does `sym1` come before `sym2` in the linearization of `pre`? */
def precedes(sym1: Symbol, sym2: Symbol) = {
def precedesIn(bcs: List[ClassSymbol]): Boolean = bcs match {
Expand Down Expand Up @@ -418,19 +427,21 @@ object Denotations {
final def validFor = denot1.validFor & denot2.validFor
final def isType = false
final def signature(implicit ctx: Context) = Signature.OverloadedSignature
def atSignature(sig: Signature, site: Type, relaxed: Boolean)(implicit ctx: Context): SingleDenotation =
denot1.atSignature(sig, site, relaxed) orElse denot2.atSignature(sig, site, relaxed)
def atSignature(sig: Signature, site: Type, relaxed: Boolean)(implicit ctx: Context): Denotation =
derivedMultiDenotation(denot1.atSignature(sig, site, relaxed), denot2.atSignature(sig, site, relaxed))
def currentIfExists(implicit ctx: Context): Denotation =
derivedMultiDenotation(denot1.currentIfExists, denot2.currentIfExists)
def current(implicit ctx: Context): Denotation =
derivedMultiDenotation(denot1.current, denot2.current)
def altsWith(p: Symbol => Boolean): List[SingleDenotation] =
denot1.altsWith(p) ++ denot2.altsWith(p)
def suchThat(p: Symbol => Boolean): SingleDenotation = {
def suchThat(p: Symbol => Boolean)(implicit ctx: Context): SingleDenotation = {
val sd1 = denot1.suchThat(p)
val sd2 = denot2.suchThat(p)
if (sd1.exists)
if (sd2.exists) throw new TypeError(s"failure to disambiguate overloaded reference $this")
if (sd2.exists)
if (isDoubleDef(denot1.symbol, denot2.symbol)) doubleDefError(denot1, denot2)
else throw new TypeError(s"failure to disambiguate overloaded reference $this")
else sd1
else sd2
}
Expand Down Expand Up @@ -480,7 +491,7 @@ object Denotations {
def altsWith(p: Symbol => Boolean): List[SingleDenotation] =
if (exists && p(symbol)) this :: Nil else Nil

def suchThat(p: Symbol => Boolean): SingleDenotation =
def suchThat(p: Symbol => Boolean)(implicit ctx: Context): SingleDenotation =
if (exists && p(symbol)) this else NoDenotation

def hasAltWith(p: SingleDenotation => Boolean): Boolean =
Expand Down Expand Up @@ -645,7 +656,13 @@ object Denotations {
var startPid = nextTransformerId + 1
val transformer = ctx.denotTransformers(nextTransformerId)
//println(s"transforming $this with $transformer")
next = transformer.transform(cur)(ctx.withPhase(transformer)).syncWithParents
try {
next = transformer.transform(cur)(ctx.withPhase(transformer)).syncWithParents
} catch {
case ex: CyclicReference =>
println(s"error while transforming $this") // DEBUG
throw ex
}
if (next eq cur)
startPid = cur.validFor.firstPhaseId
else {
Expand Down Expand Up @@ -900,6 +917,27 @@ object Denotations {
*/
case class NoQualifyingRef(alts: List[SingleDenotation])(implicit ctx: Context) extends ErrorDenotation

/** A double definition
*/
def isDoubleDef(sym1: Symbol, sym2: Symbol)(implicit ctx: Context): Boolean =
(sym1.exists && sym2.exists &&
(sym1 ne sym2) && (sym1.owner eq sym2.owner) &&
!sym1.is(Bridge) && !sym2.is(Bridge))

def doubleDefError(denot1: Denotation, denot2: Denotation, pre: Type = NoPrefix)(implicit ctx: Context): Nothing = {
val sym1 = denot1.symbol
val sym2 = denot2.symbol
def fromWhere = if (pre == NoPrefix) "" else i"\nwhen seen as members of $pre"
throw new MergeError(
i"""cannot merge
| $sym1: ${sym1.info} and
| $sym2: ${sym2.info};
|they are both defined in ${sym1.owner} but have matching signatures
| ${denot1.info} and
| ${denot2.info}$fromWhere""".stripMargin,
denot2.info, denot2.info)
}

// --------------- PreDenotations -------------------------------------------------

/** A PreDenotation represents a group of single denotations
Expand Down
92 changes: 24 additions & 68 deletions src/dotty/tools/dotc/core/SymDenotations.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1299,7 +1299,6 @@ object SymDenotations {
override def invalidateInheritedInfo(): Unit = {
myBaseClasses = null
mySuperClassBits = null
myMemberFingerPrint = FingerPrint.unknown
myMemberCache = null
myMemberCachePeriod = Nowhere
memberNamesCache = SimpleMap.Empty
Expand Down Expand Up @@ -1418,42 +1417,6 @@ object SymDenotations {

final override def typeParamCreationFlags = ClassTypeParamCreationFlags

private[this] var myMemberFingerPrint: FingerPrint = FingerPrint.unknown

private def computeMemberFingerPrint(implicit ctx: Context): FingerPrint = {
var fp = FingerPrint()
var e = info.decls.lastEntry
while (e != null) {
fp.include(e.name)
e = e.prev
}
var ps = classParents
while (ps.nonEmpty) {
val parent = ps.head.typeSymbol
parent.denot match {
case parentDenot: ClassDenotation =>
fp.include(parentDenot.memberFingerPrint)
if (parentDenot.isFullyCompleted) parentDenot.setFlag(Frozen)
case _ =>
}
ps = ps.tail
}
fp
}

/** A bloom filter for the names of all members in this class.
* Makes sense only for parent classes, and should definitely
* not be used for package classes because cache never
* gets invalidated.
*/
def memberFingerPrint(implicit ctx: Context): FingerPrint =
if (myMemberFingerPrint != FingerPrint.unknown) myMemberFingerPrint
else {
val fp = computeMemberFingerPrint
if (isFullyCompleted) myMemberFingerPrint = fp
fp
}

private[this] var myMemberCache: LRUCache[Name, PreDenotation] = null
private[this] var myMemberCachePeriod: Period = Nowhere

Expand Down Expand Up @@ -1499,13 +1462,12 @@ object SymDenotations {

/** Enter a symbol in given `scope` without potentially replacing the old copy. */
def enterNoReplace(sym: Symbol, scope: MutableScope)(implicit ctx: Context): Unit = {
require((sym.denot.flagsUNSAFE is Private) || !(this is Frozen) || (scope ne this.unforcedDecls))
require((sym.denot.flagsUNSAFE is Private) ||
!(this is Frozen) ||
(scope ne this.unforcedDecls))
scope.enter(sym)

if (myMemberFingerPrint != FingerPrint.unknown)
myMemberFingerPrint.include(sym.name)
if (myMemberCache != null)
myMemberCache invalidate sym.name
if (myMemberCache != null) myMemberCache invalidate sym.name
}

/** Replace symbol `prev` (if defined in current class) by symbol `replacement`.
Expand All @@ -1526,7 +1488,6 @@ object SymDenotations {
def delete(sym: Symbol)(implicit ctx: Context) = {
require(!(this is Frozen))
info.decls.openForMutations.unlink(sym)
myMemberFingerPrint = FingerPrint.unknown
if (myMemberCache != null) myMemberCache invalidate sym.name
}

Expand Down Expand Up @@ -1574,31 +1535,26 @@ object SymDenotations {
}

private[core] def computeNPMembersNamed(name: Name, inherited: Boolean)(implicit ctx: Context): PreDenotation = /*>|>*/ Stats.track("computeNPMembersNamed") /*<|<*/ {
if (!inherited ||
!Config.useFingerPrints ||
(memberFingerPrint contains name)) {
Stats.record("computeNPMembersNamed after fingerprint")
ensureCompleted()
val ownDenots = info.decls.denotsNamed(name, selectNonPrivate)
if (debugTrace) // DEBUG
println(s"$this.member($name), ownDenots = $ownDenots")
def collect(denots: PreDenotation, parents: List[TypeRef]): PreDenotation = parents match {
case p :: ps =>
val denots1 = collect(denots, ps)
p.symbol.denot match {
case parentd: ClassDenotation =>
denots1 union
parentd.nonPrivateMembersNamed(name, inherited = true)
.mapInherited(ownDenots, denots1, thisType)
case _ =>
denots1
}
case nil =>
denots
}
if (name.isConstructorName) ownDenots
else collect(ownDenots, classParents)
} else NoDenotation
Stats.record("computeNPMembersNamed after fingerprint")
ensureCompleted()
val ownDenots = info.decls.denotsNamed(name, selectNonPrivate)
if (debugTrace) // DEBUG
println(s"$this.member($name), ownDenots = $ownDenots")
def collect(denots: PreDenotation, parents: List[TypeRef]): PreDenotation = parents match {
case p :: ps =>
val denots1 = collect(denots, ps)
p.symbol.denot match {
case parentd: ClassDenotation =>
denots1 union
parentd.nonPrivateMembersNamed(name, inherited = true)
.mapInherited(ownDenots, denots1, thisType)
case _ =>
denots1
}
case nil =>
denots
}
if (name.isConstructorName) ownDenots else collect(ownDenots, classParents)
}

override final def findMember(name: Name, pre: Type, excluded: FlagSet)(implicit ctx: Context): Denotation = {
Expand Down
4 changes: 2 additions & 2 deletions src/dotty/tools/dotc/core/Symbols.scala
Original file line number Diff line number Diff line change
Expand Up @@ -398,10 +398,10 @@ object Symbols {

/** Subclass tests and casts */
final def isTerm(implicit ctx: Context): Boolean =
(if(isDefinedInCurrentRun) lastDenot else denot).isTerm
(if (defRunId == ctx.runId) lastDenot else denot).isTerm

final def isType(implicit ctx: Context): Boolean =
(if(isDefinedInCurrentRun) lastDenot else denot).isType
(if (defRunId == ctx.runId) lastDenot else denot).isType

final def isClass: Boolean = isInstanceOf[ClassSymbol]

Expand Down
2 changes: 1 addition & 1 deletion src/dotty/tools/dotc/core/TypeErasure.scala
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,7 @@ class TypeErasure(isJava: Boolean, semiEraseVCs: Boolean, isConstructor: Boolean
tr1 :: trs1.filterNot(_ isRef defn.ObjectClass)
case nil => nil
}
val erasedDecls = decls.filteredScope(d => !d.isType || d.isClass)
val erasedDecls = decls.filteredScope(sym => !sym.isType || sym.isClass)
tp.derivedClassInfo(NoPrefix, parents, erasedDecls, erasedRef(tp.selfType))
// can't replace selftype by NoType because this would lose the sourceModule link
}
Expand Down
8 changes: 6 additions & 2 deletions src/dotty/tools/dotc/core/Types.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1437,7 +1437,11 @@ object Types {
asMemberOf(prefix) match {
case NoDenotation => d.current
case newd: SingleDenotation => newd
case newd => newd.atSignature(d.signature).orElse(d.current)
case newd =>
newd.atSignature(d.signature) match {
case newd1: SingleDenotation if newd1.exists => newd1
case _ => d.current
}
}

private def denotOfSym(sym: Symbol)(implicit ctx: Context): Denotation = {
Expand Down Expand Up @@ -1729,7 +1733,7 @@ object Types {
override def loadDenot(implicit ctx: Context): Denotation = {
val d = super.loadDenot
if (sig eq Signature.OverloadedSignature) d
else d.atSignature(sig)
else d.atSignature(sig).checkUnique
}

override def newLikeThis(prefix: Type)(implicit ctx: Context): TermRef = {
Expand Down
Loading