diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/dotty/tools/dotc/core/Types.scala | 7 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Checking.scala | 6 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Typer.scala | 2 |
3 files changed, 8 insertions, 7 deletions
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala index 89facfee5..827e851a9 100644 --- a/src/dotty/tools/dotc/core/Types.scala +++ b/src/dotty/tools/dotc/core/Types.scala @@ -117,14 +117,15 @@ object Types { } /** A type T is a legal prefix in a type selection T#A if - * T is stable or T contains no abstract types + * T is stable or T contains no abstract types except possibly A. * !!! Todo: What about non-final vals that contain abstract types? */ - final def isLegalPrefix(implicit ctx: Context): Boolean = + final def isLegalPrefixFor(selector: Name)(implicit ctx: Context): Boolean = isStable || { val absTypeNames = memberNames(abstractTypeNameFilter) if (absTypeNames.nonEmpty) typr.println(s"abstract type members of ${this.showWithUnderlying()}: $absTypeNames") - absTypeNames.isEmpty + absTypeNames.isEmpty || + absTypeNames.head == selector && absTypeNames.tail.isEmpty } /** Is this type guaranteed not to have `null` as a value? diff --git a/src/dotty/tools/dotc/typer/Checking.scala b/src/dotty/tools/dotc/typer/Checking.scala index 5e52c5d7e..7da00e051 100644 --- a/src/dotty/tools/dotc/typer/Checking.scala +++ b/src/dotty/tools/dotc/typer/Checking.scala @@ -51,8 +51,8 @@ trait Checking { /** Check that type `tp` is a legal prefix for '#'. * @return The type itself */ - def checkLegalPrefix(tp: Type, pos: Position)(implicit ctx: Context): Unit = - if (!tp.isLegalPrefix) ctx.error(d"$tp is not a valid prefix for '#'", pos) + def checkLegalPrefix(tp: Type, selector: Name, pos: Position)(implicit ctx: Context): Unit = + if (!tp.isLegalPrefixFor(selector)) ctx.error(d"$tp is not a valid prefix for '# $selector'", pos) /** Check that `tp` is a class type with a stable prefix. Also, if `isFirst` is * false check that `tp` is a trait. @@ -139,7 +139,7 @@ trait NoChecking extends Checking { override def checkValue(tree: Tree, proto: Type)(implicit ctx: Context): tree.type = tree override def checkBounds(args: List[tpd.Tree], poly: PolyType, pos: Position)(implicit ctx: Context): Unit = () override def checkStable(tp: Type, pos: Position)(implicit ctx: Context): Unit = () - override def checkLegalPrefix(tp: Type, pos: Position)(implicit ctx: Context): Unit = () + override def checkLegalPrefix(tp: Type, selector: Name, pos: Position)(implicit ctx: Context): Unit = () override def checkClassTypeWithStablePrefix(tp: Type, pos: Position, traitReq: Boolean)(implicit ctx: Context): Type = tp override def checkImplicitParamsNotSingletons(vparamss: List[List[ValDef]])(implicit ctx: Context): Unit = () override def checkFeasible(tp: Type, pos: Position, where: => String = "")(implicit ctx: Context): Type = tp diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala index d6b724270..c01cf714f 100644 --- a/src/dotty/tools/dotc/typer/Typer.scala +++ b/src/dotty/tools/dotc/typer/Typer.scala @@ -277,7 +277,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit def typedSelectFromTypeTree(tree: untpd.SelectFromTypeTree, pt: Type)(implicit ctx: Context): SelectFromTypeTree = track("typedSelectFromTypeTree") { val qual1 = typedType(tree.qualifier, selectionProto(tree.name, pt, this)) - checkLegalPrefix(qual1.tpe, qual1.pos) + checkLegalPrefix(qual1.tpe, tree.name, qual1.pos) assignType(cpy.SelectFromTypeTree(tree, qual1, tree.name), qual1) } |