new warning in scala 2.10.1-RC[12]

1,858 views
Skip to first unread message

Jeff Olson

unread,
Mar 1, 2013, 6:51:19 PM3/1/13
to scala-i...@googlegroups.com
This code compiled fine on 2.10.0 without warning:

class Outer {
  final case class Inner(n: Int)
}

With 2.10.1-RC[12] it complains that "The outer reference in this type test cannot be checked at run time." What does that even mean? Is the warning something I should pay attention to and fix, or is it a regression?

I note that the spurious warning is mentioned in https://issues.scala-lang.org/browse/SI-7195, but I don't see it specifically addressed. I get about 50 of these in one project, and I'd like to know what to do about them.

Thanks, Jeff

Paul Phillips

unread,
Mar 1, 2013, 7:55:12 PM3/1/13
to scala-i...@googlegroups.com

On Fri, Mar 1, 2013 at 3:51 PM, Jeff Olson <jeff.d...@gmail.com> wrote:
class Outer {
  final case class Inner(n: Int)
}

With 2.10.1-RC[12] it complains that "The outer reference in this type test cannot be checked at run time." What does that even mean? Is the warning something I should pay attention to and fix, or is it a regression?

It means this you might think this program will print "5 -1" but it will print "5 5".

class Outer { final case class Inner(n: Int) }
object Test {
  val x1 = new Outer
  val x2 = new Outer

  def f(x: Any) = x match {
    case x1.Inner(p) => p
    case _           => -1
  }

  def main(args: Array[String]): Unit = {
    println(f(x1.Inner(5)) + " " + f(x2.Inner(5)))
  }
}

Paul Phillips

unread,
Mar 1, 2013, 7:57:08 PM3/1/13
to scala-i...@googlegroups.com
Also, 2.10 has the warning as well, as soon as you try to match on it. What has changed apparently is that the warning is issued at the point of the class definition.

Adriaan Moors

unread,
Mar 1, 2013, 8:27:54 PM3/1/13
to scala-i...@googlegroups.com
The warning refers to the synthesized equals method, which cannot test the outer pointer for Inner (as we don't an outer accessor for final nested classes for reasons unknown to me).

scala> class Outer {
     |   final case class Inner(n: Int)
     | }
warning: there were 1 unchecked warning(s); re-run with -unchecked for details
defined class Outer

scala> val o1 = new Outer
o1: Outer = Outer@52c54b3b

scala> val o2 = new Outer
o2: Outer = Outer@7cef7efe

scala> (new o1.Inner(1)) == (new o2.Inner(1))
res0: Boolean = true

When an outer accessor is available, you'll get the correct result:

scala> class Outer {
  case class Inner(n: Int) // look ma, no final!
}
defined class Outer

scala> val o1 = new Outer
o1: Outer = Outer@2a29a451

scala> val o2 = new Outer
o2: Outer = Outer@6cb8daa7

scala> (new o1.Inner(1)) == (new o2.Inner(1))
res1: Boolean = false



On Fri, Mar 1, 2013 at 4:57 PM, Paul Phillips <pa...@improving.org> wrote:
Also, 2.10 has the warning as well, as soon as you try to match on it. What has changed apparently is that the warning is issued at the point of the class definition.

--
You received this message because you are subscribed to the Google Groups "scala-internals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-interna...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Paul Phillips

unread,
Mar 1, 2013, 8:39:07 PM3/1/13
to scala-i...@googlegroups.com
On Fri, Mar 1, 2013 at 5:27 PM, Adriaan Moors <adriaa...@typesafe.com> wrote:
as we don't an outer accessor for final nested classes for reasons unknown to me

Wait, YOU don't know why? Does anyone?

Actually it looks to me like it's intended to suppress the field when it's not referenced. Since it can always be referenced by appearing in a prefix, that whole plan was flawed.

Adriaan Moors

unread,
Mar 1, 2013, 8:48:09 PM3/1/13
to scala-i...@googlegroups.com
Well I know the immediate reason: memory consumption. I don't know why we chose the *final* modifier to suppress this.

I tried always emitting the outer pointer: https://github.com/scala/scala/pull/951, but Martin didn't like that.


--

Grzegorz Kossakowski

unread,
Mar 1, 2013, 8:53:57 PM3/1/13
to scala-i...@googlegroups.com
On 1 March 2013 17:48, Adriaan Moors <adriaa...@typesafe.com> wrote:
Well I know the immediate reason: memory consumption. I don't know why we chose the *final* modifier to suppress this.

If you care about outer pointers why do you have inner class in the first place?

--
Grzegorz Kossakowski
Scalac hacker at Typesafe
twitter: @gkossakowski

Paul Phillips

unread,
Mar 1, 2013, 9:03:38 PM3/1/13
to scala-i...@googlegroups.com
These are semantics out of a nightmare. "I made my class final and everything went haywire." If we aren't going to emit the outer pointer always, then we should emit it never (where "never" could be adjusted to "when programmer say so.")

Adriaan Moors

unread,
Mar 1, 2013, 10:32:42 PM3/1/13
to scala-i...@googlegroups.com
Absolutely agree. Reopened SI-4440.

Paolo G. Giarrusso

unread,
Apr 19, 2013, 6:49:51 PM4/19/13
to scala-i...@googlegroups.com
I just ran into this warning, and even though I read this thread a month ago, I had no idea on Earth what the warning could mean.

On Saturday, March 2, 2013 2:27:54 AM UTC+1, Adriaan Moors wrote:
The warning refers to the synthesized equals method, which cannot test the outer pointer for Inner (as we don't an outer accessor for final nested classes for reasons unknown to me).

But what about showing the user the code the warning is talking about? I know about -Xprint:typer, but that doesn't sound like a good solution.

In general, if a warning/error position refers to a synthetic code fragment, shouldn't we tell the user that the warning/error is in generated code, and at least point to -Xprint:typer if not show the generated code directly (which is not trivial to get right)?

Best,
Paolo

Lukas Rytz

unread,
Apr 20, 2013, 4:21:37 AM4/20/13
to scala-i...@googlegroups.com
On Sat, Apr 20, 2013 at 12:49 AM, Paolo G. Giarrusso <p.gia...@gmail.com> wrote:
I just ran into this warning, and even though I read this thread a month ago, I had no idea on Earth what the warning could mean.

On Saturday, March 2, 2013 2:27:54 AM UTC+1, Adriaan Moors wrote:
The warning refers to the synthesized equals method, which cannot test the outer pointer for Inner (as we don't an outer accessor for final nested classes for reasons unknown to me).

But what about showing the user the code the warning is talking about? I know about -Xprint:typer, but that doesn't sound like a good solution.

In general, if a warning/error position refers to a synthetic code fragment, shouldn't we tell the user that the warning/error is in generated code, and at least point to -Xprint:typer if not show the generated code directly (which is not trivial to get right)?

we do sth along those lines for default arguments

scala> def f[T](x: T = 1) = x

scala> f[String]()
<console>:9: error: type mismatch;
 found   : Int
 required: String
Error occurred in an application involving default arguments.
              f[String]()
               ^
Reply all
Reply to author
Forward
0 new messages