diff options
author | Martin Odersky <odersky@gmail.com> | 2013-12-24 11:59:34 +0100 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2013-12-24 12:33:35 +0100 |
commit | b23bc744ce9f8275fb6b433e40f14158eefc1abf (patch) | |
tree | cbeea6b180a011f05c169658f062dfc454eebb3f /src/dotty/tools/dotc/typer/Typer.scala | |
parent | 336a1fc56074b58c54951a4a351d258f23999281 (diff) | |
download | dotty-b23bc744ce9f8275fb6b433e40f14158eefc1abf.tar.gz dotty-b23bc744ce9f8275fb6b433e40f14158eefc1abf.tar.bz2 dotty-b23bc744ce9f8275fb6b433e40f14158eefc1abf.zip |
Fixing problems in treatment of private symbols
1) Accessibility check was broken because it looked at symbol's owner, where it should have looked at context owner.
2) Refined treatement if members. Previously, nonPrivate member returned a subset of member, i.e. those denotations returned by member that were not private. This is not correct. In a situation like
class A { def x: Int = 1 }
class B { private def x: String = "" } extends A
(new B).x
the non-private member returned should be A#x. Changed membersNamed and friends as well as checkAccessible to account for that.
Diffstat (limited to 'src/dotty/tools/dotc/typer/Typer.scala')
-rw-r--r-- | src/dotty/tools/dotc/typer/Typer.scala | 40 |
1 files changed, 23 insertions, 17 deletions
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala index 4117b0384..730314bda 100644 --- a/src/dotty/tools/dotc/typer/Typer.scala +++ b/src/dotty/tools/dotc/typer/Typer.scala @@ -89,8 +89,7 @@ class Typer extends Namer with Applications with Implicits { */ def checkedSelectionType(qual1: Tree, tree: untpd.RefTree)(implicit ctx: Context): Type = { val ownType = selectionType(qual1.tpe.widenIfUnstable, tree.name, tree.pos) - if (!ownType.isError) checkAccessible(ownType, qual1.isInstanceOf[Super], tree.pos) - ownType + checkAccessible(ownType, qual1.isInstanceOf[Super], tree.pos) } /** Check that Java statics and packages can only be used in selections. @@ -102,7 +101,8 @@ class Typer extends Namer with Applications with Implicits { } /** If `tpe` is a named type, check that its denotation is accessible in the - * current context. + * current context. Return the type with those alternatives as denotations + * which are accessible. */ def checkAccessible(tpe: Type, superAccess: Boolean, pos: Position)(implicit ctx: Context): Type = tpe match { case tpe: NamedType => @@ -110,21 +110,27 @@ class Typer extends Namer with Applications with Implicits { val name = tpe.name val d = tpe.denot.accessibleFrom(pre, superAccess) if (!d.exists) { - val alts = tpe.denot.alternatives.map(_.symbol).filter(_.exists) - val where = pre.typeSymbol - val what = alts match { - case Nil => - name.toString - case sym :: Nil => - if (sym.owner == where) sym.show else sym.showLocated - case _ => - i"none of the overloaded alternatives named $name" + val d2 = pre.nonPrivateMember(name) + if (reallyExists(d2)) + checkAccessible(pre.select(name, d2), superAccess, pos) + else { + val alts = tpe.denot.alternatives.map(_.symbol).filter(_.exists) + val where = pre.typeSymbol + val what = alts match { + case Nil => + name.toString + case sym :: Nil => + if (sym.owner == where) sym.show else sym.showLocated + case _ => + i"none of the overloaded alternatives named $name" + } + val whyNot = new StringBuffer + val addendum = + alts foreach (_.isAccessibleFrom(pre, superAccess, whyNot)) + if (!tpe.isError) + ctx.error(i"$what cannot be accessed from $pre.$whyNot", pos) + ErrorType } - val whyNot = new StringBuffer - val addendum = - alts foreach (_.isAccessibleFrom(pre, superAccess, whyNot)) - ctx.error(i"$what cannot be accessed from $pre.$whyNot", pos) - ErrorType } else if (d.symbol is TypeParamAccessor) // always dereference type param accessors checkAccessible(d.info.bounds.hi, superAccess, pos) |