diff options
author | Guillaume Martres <smarter@ubuntu.com> | 2017-04-04 19:17:42 +0200 |
---|---|---|
committer | Guillaume Martres <smarter@ubuntu.com> | 2017-04-04 20:24:35 +0200 |
commit | 6ae376a4544cbf93b94dc0a6ba4a78224e0477df (patch) | |
tree | 444b619989a686f66b74a963d238c318ff847aa2 /compiler/src/dotty/tools/dotc/typer | |
parent | 42c2a6fbbddf73ef2faeb6204c2b7521a76d7345 (diff) | |
download | dotty-6ae376a4544cbf93b94dc0a6ba4a78224e0477df.tar.gz dotty-6ae376a4544cbf93b94dc0a6ba4a78224e0477df.tar.bz2 dotty-6ae376a4544cbf93b94dc0a6ba4a78224e0477df.zip |
checkNoPrivateLeaks: Do not allow types to refer to leaky aliases
`checkNoPrivateLeaks` can force a lot of things, this lead to
hard-to-reproduce issues in unpickling because we called
`checkNoPrivateLeaks` on the type parameters of a class before anything
in the class was indexed. We fix this by making sure that
`checkNoPrivateLeaks` never transforms type symbols, only term symbols,
therefore we can unpickle type parameters without forcing too many
things. tests/neg/leak-type.scala illustrates the new restriction that
this necessitates.
Diffstat (limited to 'compiler/src/dotty/tools/dotc/typer')
-rw-r--r-- | compiler/src/dotty/tools/dotc/typer/Checking.scala | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/compiler/src/dotty/tools/dotc/typer/Checking.scala b/compiler/src/dotty/tools/dotc/typer/Checking.scala index b43391592..1dc35f507 100644 --- a/compiler/src/dotty/tools/dotc/typer/Checking.scala +++ b/compiler/src/dotty/tools/dotc/typer/Checking.scala @@ -348,12 +348,23 @@ object Checking { /** Check the type signature of the symbol `M` defined by `tree` does not refer * to a private type or value which is invisible at a point where `M` is still - * visible. As an exception, we allow references to type aliases if the underlying - * type of the alias is not a leak. So type aliases are transparent as far as - * leak testing is concerned. + * visible. + * + * As an exception, we allow references to type aliases if the underlying + * type of the alias is not a leak, and if `sym` is not a type. The rationale + * for this is that the inferred type of a term symbol might contain leaky + * aliases which should be removed (see leak-inferred.scala for an example), + * but a type symbol definition will not contain leaky aliases unless the + * user wrote them, so we can ask the user to change his definition. The more + * practical reason for not transforming types is that `checkNoPrivateLeaks` + * can force a lot of denotations, and this restriction means that we never + * need to run `TypeAssigner#avoidPrivateLeaks` on type symbols when + * unpickling, which avoids some issues related to forcing order. + * + * See i997.scala for negative tests, and i1130.scala for a case where it + * matters that we transform leaky aliases away. + * * @return The `info` of `sym`, with problematic aliases expanded away. - * See i997.scala for tests, i1130.scala for a case where it matters that we - * transform leaky aliases away. */ def checkNoPrivateLeaks(sym: Symbol, pos: Position)(implicit ctx: Context): Type = { class NotPrivate extends TypeMap { @@ -388,7 +399,7 @@ object Checking { tp } else mapOver(tp) - if ((errors ne prevErrors) && tp.info.isAlias) { + if ((errors ne prevErrors) && !sym.isType && tp.info.isAlias) { // try to dealias to avoid a leak error val savedErrors = errors errors = prevErrors |