aboutsummaryrefslogtreecommitdiff
path: root/compiler/src/dotty/tools/dotc/typer/Checking.scala
diff options
context:
space:
mode:
authorGuillaume Martres <smarter@ubuntu.com>2016-11-16 21:57:19 +0100
committerGuillaume Martres <smarter@ubuntu.com>2016-11-22 01:35:08 +0100
commitce23380cbcec633cba63f19bc8f02c1d2b8048bb (patch)
treedf1a365afb9491be4d817c70d80dc7b5cf0e2036 /compiler/src/dotty/tools/dotc/typer/Checking.scala
parent19c4c24f884b8e7245ffdd26fbb573761703496a (diff)
downloaddotty-ce23380cbcec633cba63f19bc8f02c1d2b8048bb.tar.gz
dotty-ce23380cbcec633cba63f19bc8f02c1d2b8048bb.tar.bz2
dotty-ce23380cbcec633cba63f19bc8f02c1d2b8048bb.zip
checkNoPrivateLeaks: handle references to companion members
Previously Outer2#Inner#foo failed to compile with: ``` non-private method foo refers to private value x in its type signature ``` This should compile because the boundary of `foo` is `class Outer2` and the boundary of `x` is `object Outer2`. This commit fixes this by also considering the linked boundary in `checkNoPrivateLeaks`.
Diffstat (limited to 'compiler/src/dotty/tools/dotc/typer/Checking.scala')
-rw-r--r--compiler/src/dotty/tools/dotc/typer/Checking.scala18
1 files changed, 16 insertions, 2 deletions
diff --git a/compiler/src/dotty/tools/dotc/typer/Checking.scala b/compiler/src/dotty/tools/dotc/typer/Checking.scala
index dbfc89f6c..c363ee81e 100644
--- a/compiler/src/dotty/tools/dotc/typer/Checking.scala
+++ b/compiler/src/dotty/tools/dotc/typer/Checking.scala
@@ -353,17 +353,31 @@ object Checking {
class NotPrivate extends TypeMap {
type Errors = List[(String, Position)]
var errors: Errors = Nil
+
def accessBoundary(sym: Symbol): Symbol =
if (sym.is(Private)) sym.owner
else if (sym.privateWithin.exists) sym.privateWithin
else if (sym.is(Package)) sym
else accessBoundary(sym.owner)
+
+ val symBoundary = accessBoundary(sym)
+
+ /** Is `other` leaked outside its access boundary ?
+ * @pre The signature of `sym` refers to `other`
+ */
+ def isLeaked(other: Symbol) =
+ other.is(Private) && {
+ val otherBoundary = other.owner
+ val otherLinkedBoundary = otherBoundary.linkedClass
+ !(symBoundary.isContainedIn(otherBoundary) ||
+ otherLinkedBoundary.exists && symBoundary.isContainedIn(otherLinkedBoundary))
+ }
+
def apply(tp: Type): Type = tp match {
case tp: NamedType =>
val prevErrors = errors
var tp1 =
- if (tp.symbol.is(Private) &&
- !accessBoundary(sym).isContainedIn(tp.symbol.owner)) {
+ if (isLeaked(tp.symbol)) {
errors = (em"non-private $sym refers to private ${tp.symbol}\n in its type signature ${sym.info}",
sym.pos) :: errors
tp