This page is no longer maintained — Please continue to the home page at www.scala-lang.org

private[this] on type declaration hides variance problem

11 replies
Avi Pfeffer
Joined: 2009-02-23,
User offline. Last seen 42 years 45 weeks ago.

While exploring the variance issues in my previous post, I came across
the following variation on the Cell example in the book:

// This compiles, but not without private[this]
scala> class Cell[+A](init: A) {
| private[this] type T = A
| var x: T = init
| def set(y: T) { x = y }
| def get = x
| }
defined class Cell

// But it has the same problem as the original Cell example
scala> val c1 = new Cell[String]("abc")
c1: Cell[String] = Cell@62ad0d

scala> val c2: Cell[Any] = c1
c2: Cell[Any] = Cell@62ad0d

scala> c2.set(1)

scala> val s: String = c1.get
java.lang.ClassCastException: java.lang.Integer cannot be cast to
java.lang.String
at .(:6)
at .()
at RequestResult$.(:3)
at RequestResult$.()
at RequestResult$result()
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.refl...

Should adding private[this] to the type declaration be having this effect?

Avi

Luc Duponcheel
Joined: 2008-12-19,
User offline. Last seen 34 weeks 3 days ago.
Re: private[this] on type declaration hides variance problem
I'm not 100% sure if this is what you're after, but,

The Scala Book explains something about variance and object private data in

19.7 Object private data

......

"It turns out that accesses
to variables from the same object in which they are defined do not
cause problems with variance."

......

On Wed, Feb 25, 2009 at 8:56 PM, Avi Pfeffer <avi@eecs.harvard.edu> wrote:
While exploring the variance issues in my previous post, I came across
the following variation on the Cell example in the book:

// This compiles, but not without private[this]
scala> class Cell[+A](init: A) {
    | private[this] type T = A
    | var x: T = init
    | def set(y: T) { x = y }
    | def get = x
    | }
defined class Cell

// But it has the same problem as the original Cell example
scala> val c1 = new Cell[String]("abc")
c1: Cell[String] = Cell@62ad0d

scala> val c2: Cell[Any] = c1
c2: Cell[Any] = Cell@62ad0d

scala> c2.set(1)

scala> val s: String = c1.get
java.lang.ClassCastException: java.lang.Integer cannot be cast to
java.lang.String
       at .<init>(<console>:6)
       at .<clinit>(<console>)
       at RequestResult$.<init>(<console>:3)
       at RequestResult$.<clinit>(<console>)
       at RequestResult$result(<console>)
       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
       at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
       at sun.refl...

Should adding private[this] to the type declaration be having this effect?

Avi



--
  __~O
 -\ <,
(*)/ (*)

reality goes far beyond imagination

extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: private[this] on type declaration hides variance problem

On Wed, Feb 25, 2009 at 02:56:27PM -0500, Avi Pfeffer wrote:
> scala> val s: String = c1.get
> java.lang.ClassCastException: java.lang.Integer cannot be cast to
> java.lang.String

Oh, I think you've got a good one there. I think someone is supposed to climb a very tall tower and ring a church bell a few
times when you find a type soundness hole like that.

milessabin
Joined: 2008-08-11,
User offline. Last seen 33 weeks 3 days ago.
Re: private[this] on type declaration hides variance problem

On Wed, Feb 25, 2009 at 7:56 PM, Avi Pfeffer wrote:
> Should adding private[this] to the type declaration be having this effect?

Very definitely not ...

Cheers,

Miles

odersky
Joined: 2008-07-29,
User offline. Last seen 45 weeks 6 days ago.
Re: private[this] on type declaration hides variance problem

Yep, that looks like a type soundness hole. Clearly, the private[this]
exception should apply only to term members, not type types.
We'll fix it in the next release.

Cheers

DRMacIver
Joined: 2008-09-02,
User offline. Last seen 42 years 45 weeks ago.
Re: private[this] on type declaration hides variance problem
On Wed, Feb 25, 2009 at 9:53 PM, martin odersky <martin.odersky@epfl.ch> wrote:
Yep, that looks like a type soundness hole. Clearly, the private[this]
exception should apply only to term members,

So, my expectation is that what should happen here is that you'd get a warning "Private type T escapes its scope" in exactly the same way you would if you defined a private class and used it in method signatures.

i.e. the problem is not that the private[this] type T is allowed in this case, but that it can be referred to in signatures which are *not* private[this]. Does this seem reasonable?

I don't have a particular use case for it, but it seems like forbidding the type definition here would be a shame if soundness can be preserved without doing so.

 
not type types.

I thought Scala didn't have type types? ;-)

Landei
Joined: 2008-12-18,
User offline. Last seen 45 weeks 4 days ago.
Re: private[this] on type declaration hides variance problem

David R. MacIver wrote:
> I thought Scala didn't have type types? ;-)

Scala has no type type types, but type types are OK. Well, as long as you
don't use private[this] :-)

Cheers,
Daniel

Avi Pfeffer
Joined: 2009-02-23,
User offline. Last seen 42 years 45 weeks ago.
Re: private[this] on type declaration hides variance problem

I would suggest disallowing private[this] on types. It seems to be
exactly the same as private, but looks different.

Alternatively, make private[this] types not be allowed to be arguments
or return types of non-private[this] methods. The private[this]
exception would then be safe.

Avi

On Wed, Feb 25, 2009 at 5:12 PM, David MacIver wrote:
> On Wed, Feb 25, 2009 at 9:53 PM, martin odersky
> wrote:
>>
>> Yep, that looks like a type soundness hole. Clearly, the private[this]
>> exception should apply only to term members,
>
> So, my expectation is that what should happen here is that you'd get a
> warning "Private type T escapes its scope" in exactly the same way you would
> if you defined a private class and used it in method signatures.
>
> i.e. the problem is not that the private[this] type T is allowed in this
> case, but that it can be referred to in signatures which are *not*
> private[this]. Does this seem reasonable?
>
> I don't have a particular use case for it, but it seems like forbidding the
> type definition here would be a shame if soundness can be preserved without
> doing so.
>
>
>>
>> not type types.
>
> I thought Scala didn't have type types? ;-)
>
>

DRMacIver
Joined: 2008-09-02,
User offline. Last seen 42 years 45 weeks ago.
Re: private[this] on type declaration hides variance problem
On Thu, Feb 26, 2009 at 12:50 AM, Avi Pfeffer <avi@eecs.harvard.edu> wrote:
I would suggest disallowing private[this] on types. It seems to be
exactly the same as private, but looks different.

Indeed. Exactly the same as private, but looks different and behaves different.
 

Alternatively, make private[this] types not be allowed to be arguments
or return types of non-private[this] methods. The private[this]
exception would then be safe.

Isn't that what I just said?
odersky
Joined: 2008-07-29,
User offline. Last seen 45 weeks 6 days ago.
Re: private[this] on type declaration hides variance problem

On Wed, Feb 25, 2009 at 11:12 PM, David MacIver wrote:
> On Wed, Feb 25, 2009 at 9:53 PM, martin odersky
> wrote:
>>
>> Yep, that looks like a type soundness hole. Clearly, the private[this]
>> exception should apply only to term members,
>
> So, my expectation is that what should happen here is that you'd get a
> warning "Private type T escapes its scope" in exactly the same way you would
> if you defined a private class and used it in method signatures.
>
> i.e. the problem is not that the private[this] type T is allowed in this
> case, but that it can be referred to in signatures which are *not*
> private[this]. Does this seem reasonable?
>
That would also be reasonable. It looks like it's higher overhead to
specify and implement this, but it would be a tad more general. I
think either of the three proposed solutions would do really.

Cheers

DRMacIver
Joined: 2008-09-02,
User offline. Last seen 42 years 45 weeks ago.
Re: private[this] on type declaration hides variance problem
On Thu, Feb 26, 2009 at 8:48 AM, martin odersky <martin.odersky@epfl.ch> wrote:
On Wed, Feb 25, 2009 at 11:12 PM, David MacIver <david.maciver@gmail.com> wrote:
> On Wed, Feb 25, 2009 at 9:53 PM, martin odersky <martin.odersky@epfl.ch>
> wrote:
>>
>> Yep, that looks like a type soundness hole. Clearly, the private[this]
>> exception should apply only to term members,
>
> So, my expectation is that what should happen here is that you'd get a
> warning "Private type T escapes its scope" in exactly the same way you would
> if you defined a private class and used it in method signatures.
>
> i.e. the problem is not that the private[this] type T is allowed in this
> case, but that it can be referred to in signatures which are *not*
> private[this]. Does this seem reasonable?
>
That would also be reasonable. It looks like it's higher overhead to
specify and implement this, but it would be a tad more general. I

My assumption was that it could just inherit the following behaviour:

 scala> class Foo{
     | private class Bar;
     | def bar = new Bar;
     | }
<console>:6: error: private class Bar escapes its defining scope as part of type Foo.this.Bar
       def bar = new Bar;

But actually I can't find where in the spec this behaviour is defined!


think either of the three proposed solutions would do really.

Agreed. It doesn't matter that much. This just seems mildly the more pleasant of the alternatives.
odersky
Joined: 2008-07-29,
User offline. Last seen 45 weeks 6 days ago.
Re: private[this] on type declaration hides variance problem

On Thu, Feb 26, 2009 at 11:14 AM, David MacIver wrote:
> On Thu, Feb 26, 2009 at 8:48 AM, martin odersky
> wrote:
>>
>> On Wed, Feb 25, 2009 at 11:12 PM, David MacIver
>> wrote:
>> > On Wed, Feb 25, 2009 at 9:53 PM, martin odersky
>> > wrote:
>> >>
>> >> Yep, that looks like a type soundness hole. Clearly, the private[this]
>> >> exception should apply only to term members,
>> >
>> > So, my expectation is that what should happen here is that you'd get a
>> > warning "Private type T escapes its scope" in exactly the same way you
>> > would
>> > if you defined a private class and used it in method signatures.
>> >
>> > i.e. the problem is not that the private[this] type T is allowed in this
>> > case, but that it can be referred to in signatures which are *not*
>> > private[this]. Does this seem reasonable?
>> >
>> That would also be reasonable. It looks like it's higher overhead to
>> specify and implement this, but it would be a tad more general. I
>
> My assumption was that it could just inherit the following behaviour:
>
>  scala> class Foo{
>      | private class Bar;
>      | def bar = new Bar;
>      | }
> :6: error: private class Bar escapes its defining scope as part of
> type Foo.this.Bar
>        def bar = new Bar;
>
> But actually I can't find where in the spec this behaviour is defined!
>
I think you are right. This is missing. However, the variance check
for private[this] members is specified correctly. It reads:

References to the type parameters in object-private values, variables,
or methods of the class are not checked for their variance position.
In these members the type parameter may appear anywhere without
restricting its legal variance annotations.

So Avi's discovery is a compiler bug, not a spec hole.
I have fixed it in my private version and will check this in if there
are no objections.

Cheers

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland