diff options
author | Guillaume Martres <smarter@ubuntu.com> | 2016-11-16 21:57:19 +0100 |
---|---|---|
committer | Guillaume Martres <smarter@ubuntu.com> | 2016-11-22 01:35:08 +0100 |
commit | ce23380cbcec633cba63f19bc8f02c1d2b8048bb (patch) | |
tree | df1a365afb9491be4d817c70d80dc7b5cf0e2036 /compiler/src/dotty/tools/dotc/typer | |
parent | 19c4c24f884b8e7245ffdd26fbb573761703496a (diff) | |
download | dotty-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')
-rw-r--r-- | compiler/src/dotty/tools/dotc/typer/Checking.scala | 18 |
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 |