aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2014-03-04 13:49:45 +0100
committerMartin Odersky <odersky@gmail.com>2014-03-04 13:49:50 +0100
commitf196e074c41f7ccde118dcf6764898a2c26fda3a (patch)
tree7427249f21c5879dff53d9dbaf1f17736944e9fb /src/dotty/tools
parent340ec6150b205287e1c0f5a0422d2186c29bc086 (diff)
downloaddotty-f196e074c41f7ccde118dcf6764898a2c26fda3a.tar.gz
dotty-f196e074c41f7ccde118dcf6764898a2c26fda3a.tar.bz2
dotty-f196e074c41f7ccde118dcf6764898a2c26fda3a.zip
Fix of #39
Two fixes: 1) Avoid the infinite recursion in checkAccessible if the accessibility check fails. 2) Make accessibility succeed for the test, and in general if the target denotation does not have a symbol. Added original test in pos and a negative test which makes accessibility fail.
Diffstat (limited to 'src/dotty/tools')
-rw-r--r--src/dotty/tools/dotc/core/Denotations.scala2
-rw-r--r--src/dotty/tools/dotc/typer/Typer.scala69
2 files changed, 37 insertions, 34 deletions
diff --git a/src/dotty/tools/dotc/core/Denotations.scala b/src/dotty/tools/dotc/core/Denotations.scala
index 9c8de3829..00b6815e7 100644
--- a/src/dotty/tools/dotc/core/Denotations.scala
+++ b/src/dotty/tools/dotc/core/Denotations.scala
@@ -393,7 +393,7 @@ object Denotations {
exists && p(this)
def accessibleFrom(pre: Type, superAccess: Boolean)(implicit ctx: Context): Denotation =
- if (symbol isAccessibleFrom (pre, superAccess)) this else NoDenotation
+ if (!symbol.exists || symbol.isAccessibleFrom(pre, superAccess)) this else NoDenotation
def atSignature(sig: Signature)(implicit ctx: Context): SingleDenotation =
if (sig matches signature) this else NoDenotation
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala
index 96fe73e7d..6cc3a226e 100644
--- a/src/dotty/tools/dotc/typer/Typer.scala
+++ b/src/dotty/tools/dotc/typer/Typer.scala
@@ -116,40 +116,43 @@ class Typer extends Namer with Applications with Implicits {
* 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 =>
- val pre = tpe.prefix
- val name = tpe.name
- val d = tpe.denot.accessibleFrom(pre, superAccess)
- if (!d.exists) {
- val d2 = pre.nonPrivateMember(name)
- if (reallyExists(d2) && (d2 ne tpe.denot))
- checkAccessible(pre.select(name, d2), superAccess, pos)
- else {
- val alts = tpe.denot.alternatives.map(_.symbol).filter(_.exists)
- val what = alts match {
- case Nil =>
- name.toString
- case sym :: Nil =>
- if (sym.owner == pre.typeSymbol) sym.show else sym.showLocated
- case _ =>
- i"none of the overloaded alternatives named $name"
+ def checkAccessible(tpe: Type, superAccess: Boolean, pos: Position)(implicit ctx: Context): Type = {
+ def test(tpe: Type, firstTry: Boolean): Type = tpe match {
+ case tpe: NamedType =>
+ val pre = tpe.prefix
+ val name = tpe.name
+ val d = tpe.denot.accessibleFrom(pre, superAccess)
+ if (!d.exists) {
+ // it could be that we found an inaccessbile private member, but there is
+ // an inherited non-private member with the same name and signature.
+ val d2 = pre.nonPrivateMember(name)
+ if (reallyExists(d2) && firstTry) test(pre.select(name, d2), false)
+ else {
+ val alts = tpe.denot.alternatives.map(_.symbol).filter(_.exists)
+ val what = alts match {
+ case Nil =>
+ name.toString
+ case sym :: Nil =>
+ if (sym.owner == pre.typeSymbol) sym.show else sym.showLocated
+ case _ =>
+ i"none of the overloaded alternatives named $name"
+ }
+ val where = if (ctx.owner.exists) s" from ${ctx.owner.enclosingClass}" else ""
+ val whyNot = new StringBuffer
+ val addendum =
+ alts foreach (_.isAccessibleFrom(pre, superAccess, whyNot))
+ if (!tpe.isError)
+ ctx.error(i"$what cannot be accessed as a member of $pre$where.$whyNot", pos)
+ ErrorType
}
- val where = if (ctx.owner.exists) s" from ${ctx.owner.enclosingClass}" else ""
- val whyNot = new StringBuffer
- val addendum =
- alts foreach (_.isAccessibleFrom(pre, superAccess, whyNot))
- if (!tpe.isError)
- ctx.error(i"$what cannot be accessed as a member of $pre$where.$whyNot", pos)
- ErrorType
- }
- }
- else if (d.symbol is TypeParamAccessor) // always dereference type param accessors
- checkAccessible(d.info.bounds.hi, superAccess, pos)
- else
- tpe withDenot d
- case _ =>
- tpe
+ } else if (d.symbol is TypeParamAccessor) // always dereference type param accessors
+ checkAccessible(d.info.bounds.hi, superAccess, pos)
+ else
+ tpe withDenot d
+ case _ =>
+ tpe
+ }
+ test(tpe, true)
}
/** The enclosing class, except if we are in a super call, in which case