aboutsummaryrefslogtreecommitdiff
path: root/compiler/src/dotty/tools/dotc/core/Types.scala
diff options
context:
space:
mode:
authorGuillaume Martres <smarter@ubuntu.com>2017-03-15 18:21:02 +0100
committerGuillaume Martres <smarter@ubuntu.com>2017-03-16 01:00:34 +0100
commit90c1a5f97db02d4af1a6e05f79285c5229f74702 (patch)
tree9f0653ae570572788cca2ddc1ee096465bc9938b /compiler/src/dotty/tools/dotc/core/Types.scala
parentc321653cee9f4596b046efdbb8c1913509fec5ef (diff)
downloaddotty-90c1a5f97db02d4af1a6e05f79285c5229f74702.tar.gz
dotty-90c1a5f97db02d4af1a6e05f79285c5229f74702.tar.bz2
dotty-90c1a5f97db02d4af1a6e05f79285c5229f74702.zip
Fix #2099: avoid loading a private member when recomputing a NamedType denot
ParamForwarding creates the following forwarder in B: private[this] def member: Int = super.member Where the type for `super.member` is `TermRef(SubA, member)` and the symbol is the `val member` in `A`. So far this is correct, but in later phases we might call `loadDenot` on this `TermRef` which will end up calling `asMemberOf`, which before this commit just did: prefix.member(name) This is incorrect in our case because `SubA` also happens to have a private `def member`, which means that our forwarder in B now forwards to a private method in a superclass, this subsequently crashes in `ExpandPrivate`. (Note: in the bytecode, a private method cannot have the same name as an overriden method, but this is already worked around in EnsurePrivate.) The fix is simple: when we recompute a member, we should only look at private members if the previous denotation was private.
Diffstat (limited to 'compiler/src/dotty/tools/dotc/core/Types.scala')
-rw-r--r--compiler/src/dotty/tools/dotc/core/Types.scala8
1 files changed, 6 insertions, 2 deletions
diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala
index abc496ec0..c88342e12 100644
--- a/compiler/src/dotty/tools/dotc/core/Types.scala
+++ b/compiler/src/dotty/tools/dotc/core/Types.scala
@@ -1585,8 +1585,12 @@ object Types {
protected def asMemberOf(prefix: Type)(implicit ctx: Context): Denotation =
if (name.isShadowedName) prefix.nonPrivateMember(name.revertShadowed)
- else prefix.member(name)
-
+ else {
+ val d = lastDenotation
+ // Never go from a non-private denotation to a private one
+ if (d == null || d.symbol.is(Private)) prefix.member(name)
+ else prefix.nonPrivateMember(name)
+ }
/** (1) Reduce a type-ref `W # X` or `W { ... } # U`, where `W` is a wildcard type
* to an (unbounded) wildcard type.