diff options
Diffstat (limited to 'src/dotty/tools/dotc')
-rw-r--r-- | src/dotty/tools/dotc/core/Denotations.scala | 77 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Checking.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/TypeAssigner.scala | 3 |
3 files changed, 44 insertions, 38 deletions
diff --git a/src/dotty/tools/dotc/core/Denotations.scala b/src/dotty/tools/dotc/core/Denotations.scala index 16a151e89..cd46918cf 100644 --- a/src/dotty/tools/dotc/core/Denotations.scala +++ b/src/dotty/tools/dotc/core/Denotations.scala @@ -268,50 +268,52 @@ object Denotations { } case denot1: SingleDenotation => if (denot1 eq denot2) denot1 - else if (denot1.signature matches denot2.signature) { + else { val info1 = denot1.info val info2 = denot2.info - val sym1 = denot1.symbol - val sym2 = denot2.symbol - 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 { - case bc :: bcs1 => (sym1 eq bc) || !(sym2 eq bc) && precedesIn(bcs1) - case Nil => true + if (denot1.signature.matches(denot2.signature) && + denot1.info.matches(denot2.info)) { + val sym1 = denot1.symbol + val sym2 = denot2.symbol + 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 { + case bc :: bcs1 => (sym1 eq bc) || !(sym2 eq bc) && precedesIn(bcs1) + case Nil => true + } + sym1.derivesFrom(sym2) || + !sym2.derivesFrom(sym1) && precedesIn(pre.baseClasses) } - sym1.derivesFrom(sym2) || - !sym2.derivesFrom(sym1) && precedesIn(pre.baseClasses) - } - /** Preference according to partial pre-order (isConcrete, precedes) */ - def preferSym(sym1: Symbol, sym2: Symbol) = - sym1.eq(sym2) || - sym1.isAsConcrete(sym2) && - (!sym2.isAsConcrete(sym1) || precedes(sym1.owner, sym2.owner)) + /** Preference according to partial pre-order (isConcrete, precedes) */ + def preferSym(sym1: Symbol, sym2: Symbol) = + sym1.eq(sym2) || + sym1.isAsConcrete(sym2) && + (!sym2.isAsConcrete(sym1) || precedes(sym1.owner, sym2.owner)) - /** Sym preference provided types also override */ - def prefer(sym1: Symbol, sym2: Symbol, info1: Type, info2: Type) = - preferSym(sym1, sym2) && info1.overrides(info2) + /** Sym preference provided types also override */ + def prefer(sym1: Symbol, sym2: Symbol, info1: Type, info2: Type) = + preferSym(sym1, sym2) && info1.overrides(info2) - if (sym2Accessible && prefer(sym2, sym1, info2, info1)) denot2 - else { - val sym1Accessible = sym1.isAccessibleFrom(pre) - if (sym1Accessible && prefer(sym1, sym2, info1, info2)) denot1 - else if (sym1Accessible && sym2.exists && !sym2Accessible) denot1 - else if (sym2Accessible && sym1.exists && !sym1Accessible) denot2 + if (sym2Accessible && prefer(sym2, sym1, info2, info1)) denot2 else { - val sym = - if (!sym1.exists) sym2 - else if (!sym2.exists) sym1 - else if (preferSym(sym2, sym1)) sym2 - else sym1 - new JointRefDenotation(sym, info1 & info2, denot1.validFor & denot2.validFor) + val sym1Accessible = sym1.isAccessibleFrom(pre) + if (sym1Accessible && prefer(sym1, sym2, info1, info2)) denot1 + else if (sym1Accessible && sym2.exists && !sym2Accessible) denot1 + else if (sym2Accessible && sym1.exists && !sym1Accessible) denot2 + else { + val sym = + if (!sym1.exists) sym2 + else if (!sym2.exists) sym1 + else if (preferSym(sym2, sym1)) sym2 + else sym1 + new JointRefDenotation(sym, info1 & info2, denot1.validFor & denot2.validFor) + } } - } + } else NoDenotation } - else NoDenotation } if (this eq that) this @@ -333,7 +335,7 @@ object Denotations { def | (that: Denotation, pre: Type)(implicit ctx: Context): Denotation = { def unionDenot(denot1: SingleDenotation, denot2: SingleDenotation): Denotation = - if (denot1.signature matches denot2.signature) { + if (denot1.matches(denot2)) { val sym1 = denot1.symbol val sym2 = denot2.symbol val info1 = denot1.info @@ -472,6 +474,9 @@ object Denotations { if (sig matches situated.signature) this else NoDenotation } + def matches(other: SingleDenotation)(implicit ctx: Context): Boolean = + signature.matches(other.signature) && info.matches(other.info) + // ------ Forming types ------------------------------------------- /** The TypeRef representing this type denotation at its original location. */ diff --git a/src/dotty/tools/dotc/typer/Checking.scala b/src/dotty/tools/dotc/typer/Checking.scala index 8376dd4e9..9092523db 100644 --- a/src/dotty/tools/dotc/typer/Checking.scala +++ b/src/dotty/tools/dotc/typer/Checking.scala @@ -312,7 +312,7 @@ trait Checking { def checkDecl(decl: Symbol): Unit = { for (other <- seen(decl.name)) { typr.println(i"conflict? $decl $other") - if (decl.signature matches other.signature) { + if (decl.matches(other)) { def doubleDefError(decl: Symbol, other: Symbol): Unit = { def ofType = if (decl.isType) "" else d": ${other.info}" def explanation = diff --git a/src/dotty/tools/dotc/typer/TypeAssigner.scala b/src/dotty/tools/dotc/typer/TypeAssigner.scala index 1ae0bec0c..3247592c3 100644 --- a/src/dotty/tools/dotc/typer/TypeAssigner.scala +++ b/src/dotty/tools/dotc/typer/TypeAssigner.scala @@ -63,7 +63,8 @@ trait TypeAssigner { val parentType = info.instantiatedParents.reduceLeft(ctx.typeComparer.andType(_, _)) def addRefinement(parent: Type, decl: Symbol) = { val inherited = parentType.findMember(decl.name, info.cls.thisType, Private) - val inheritedInfo = inherited.atSignature(decl.info .signature).info + val inheritedInfo = inherited.atSignature(decl.info.signature).info + // @smarter atSignature probably wrong now; we are now missing out on types that refine the result type if (inheritedInfo.exists && decl.info <:< inheritedInfo && !(inheritedInfo <:< decl.info)) typr.echo( i"add ref $parent $decl --> ", |