diff options
Diffstat (limited to 'compiler')
5 files changed, 30 insertions, 16 deletions
diff --git a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala index c98b444d9..326f0e39e 100644 --- a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala +++ b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala @@ -957,6 +957,10 @@ object SymDenotations { else companionNamed(name)(ctx.outersIterator.dropWhile(_.scope eq ctx.scope).next) + /** Is this symbol the same or a linked class of `sym`? */ + final def isLinkedWith(sym: Symbol)(implicit ctx: Context): Boolean = + (symbol eq sym) || (linkedClass eq sym) + /** If this is a class, the module class of its companion object. * If this is a module class, its companion class. * NoSymbol otherwise. diff --git a/compiler/src/dotty/tools/dotc/core/TypeErasure.scala b/compiler/src/dotty/tools/dotc/core/TypeErasure.scala index 2140405b1..10587afd5 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeErasure.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeErasure.scala @@ -215,13 +215,13 @@ object TypeErasure { } /** The erased least upper bound is computed as follows - * - if both argument are arrays of objects, an array of the lub of the element types + * - if both argument are arrays of objects, an array of the erased lub of the element types * - if both arguments are arrays of same primitives, an array of this primitive * - if one argument is array of primitives and the other is array of objects, Object * - if one argument is an array, Object * - otherwise a common superclass or trait S of the argument classes, with the * following two properties: - * S is minimal: no other common superclass or trait derives from S] + * S is minimal: no other common superclass or trait derives from S * S is last : in the linearization of the first argument type `tp1` * there are no minimal common superclasses or traits that * come after S. diff --git a/compiler/src/dotty/tools/dotc/typer/Implicits.scala b/compiler/src/dotty/tools/dotc/typer/Implicits.scala index ebbcbcc95..681045cc4 100644 --- a/compiler/src/dotty/tools/dotc/typer/Implicits.scala +++ b/compiler/src/dotty/tools/dotc/typer/Implicits.scala @@ -516,8 +516,13 @@ trait Implicits { self: Typer => || (from.tpe isRef defn.NullClass) || !(ctx.mode is Mode.ImplicitsEnabled) || (from.tpe eq NoPrefix)) NoImplicitMatches - else - try inferImplicit(to.stripTypeVar.widenExpr, from, from.pos) + else { + def adjust(to: Type) = to.stripTypeVar.widenExpr match { + case SelectionProto(name, memberProto, compat, true) => + SelectionProto(name, memberProto, compat, privateOK = false) + case tp => tp + } + try inferImplicit(adjust(to), from, from.pos) catch { case ex: AssertionError => implicits.println(s"view $from ==> $to") @@ -525,6 +530,7 @@ trait Implicits { self: Typer => implicits.println(TypeComparer.explained(implicit ctx => from.tpe <:< to)) throw ex } + } } /** Find an implicit argument for parameter `formal`. diff --git a/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala b/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala index 17f13d7c1..b588e3ae5 100644 --- a/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala +++ b/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala @@ -90,12 +90,12 @@ object ProtoTypes { * * [ ].name: proto */ - abstract case class SelectionProto(val name: Name, val memberProto: Type, val compat: Compatibility) + abstract case class SelectionProto(name: Name, memberProto: Type, compat: Compatibility, privateOK: Boolean) extends CachedProxyType with ProtoType with ValueTypeOrProto { override def isMatchedBy(tp1: Type)(implicit ctx: Context) = { name == nme.WILDCARD || { - val mbr = tp1.member(name) + val mbr = if (privateOK) tp1.member(name) else tp1.nonPrivateMember(name) def qualifies(m: SingleDenotation) = memberProto.isRef(defn.UnitClass) || compat.normalizedCompatible(m.info, memberProto) @@ -110,11 +110,11 @@ object ProtoTypes { def derivedSelectionProto(name: Name, memberProto: Type, compat: Compatibility)(implicit ctx: Context) = if ((name eq this.name) && (memberProto eq this.memberProto) && (compat eq this.compat)) this - else SelectionProto(name, memberProto, compat) + else SelectionProto(name, memberProto, compat, privateOK) override def equals(that: Any): Boolean = that match { case that: SelectionProto => - (name eq that.name) && (memberProto == that.memberProto) && (compat eq that.compat) + (name eq that.name) && (memberProto == that.memberProto) && (compat eq that.compat) && (privateOK == that.privateOK) case _ => false } @@ -124,14 +124,18 @@ object ProtoTypes { override def deepenProto(implicit ctx: Context) = derivedSelectionProto(name, memberProto.deepenProto, compat) - override def computeHash = addDelta(doHash(name, memberProto), if (compat eq NoViewsAllowed) 1 else 0) + override def computeHash = { + val delta = (if (compat eq NoViewsAllowed) 1 else 0) | (if (privateOK) 2 else 0) + addDelta(doHash(name, memberProto), delta) + } } - class CachedSelectionProto(name: Name, memberProto: Type, compat: Compatibility) extends SelectionProto(name, memberProto, compat) + class CachedSelectionProto(name: Name, memberProto: Type, compat: Compatibility, privateOK: Boolean) + extends SelectionProto(name, memberProto, compat, privateOK) object SelectionProto { - def apply(name: Name, memberProto: Type, compat: Compatibility)(implicit ctx: Context): SelectionProto = { - val selproto = new CachedSelectionProto(name, memberProto, compat) + def apply(name: Name, memberProto: Type, compat: Compatibility, privateOK: Boolean)(implicit ctx: Context): SelectionProto = { + val selproto = new CachedSelectionProto(name, memberProto, compat, privateOK) if (compat eq NoViewsAllowed) unique(selproto) else selproto } } @@ -143,7 +147,7 @@ object ProtoTypes { if (name.isConstructorName) WildcardType else tp match { case tp: UnapplyFunProto => new UnapplySelectionProto(name) - case tp => SelectionProto(name, IgnoredProto(tp), typer) + case tp => SelectionProto(name, IgnoredProto(tp), typer, privateOK = true) } /** A prototype for expressions [] that are in some unspecified selection operation @@ -154,10 +158,10 @@ object ProtoTypes { * operation is further selection. In this case, the expression need not be a value. * @see checkValue */ - @sharable object AnySelectionProto extends SelectionProto(nme.WILDCARD, WildcardType, NoViewsAllowed) + @sharable object AnySelectionProto extends SelectionProto(nme.WILDCARD, WildcardType, NoViewsAllowed, true) /** A prototype for selections in pattern constructors */ - class UnapplySelectionProto(name: Name) extends SelectionProto(name, WildcardType, NoViewsAllowed) + class UnapplySelectionProto(name: Name) extends SelectionProto(name, WildcardType, NoViewsAllowed, true) trait ApplyingProto extends ProtoType diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index 9a561ec73..ccfe218b3 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -1719,7 +1719,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit def tryInsertImplicitOnQualifier(tree: Tree, pt: Type)(implicit ctx: Context): Option[Tree] = ctx.traceIndented(i"try insert impl on qualifier $tree $pt") { tree match { case Select(qual, name) => - val qualProto = SelectionProto(name, pt, NoViewsAllowed) + val qualProto = SelectionProto(name, pt, NoViewsAllowed, privateOK = false) tryEither { implicit ctx => val qual1 = adaptInterpolated(qual, qualProto, EmptyTree) if ((qual eq qual1) || ctx.reporter.hasErrors) None |