Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

report error when using wildcard for top-level type parameter name #5606

Closed
scabug opened this issue Mar 23, 2012 · 10 comments · Fixed by scala/scala#9712
Closed

report error when using wildcard for top-level type parameter name #5606

scabug opened this issue Mar 23, 2012 · 10 comments · Fixed by scala/scala#9712

Comments

@scabug
Copy link

scabug commented Mar 23, 2012

I am able to crash the compiler with the following code:

object TestModel {
}

case class CaseTest[_](someData:String)

The error is the following:

 java.lang.AssertionError: assertion failed: transformCaseApply: name = _! tree = _ / class scala.reflect.generic.Trees$Ident
at scala.tools.nsc.typechecker.RefChecks$RefCheckTransformer$$anonfun$2.apply$mcV$sp(RefChecks.scala:1493)
at scala.tools.nsc.typechecker.RefChecks$RefCheckTransformer.transformCaseApply(RefChecks.scala:1309)
etc..

(I really hope I was supposed to issue this as a bug, first time ever I do this kind of thing. If I shouldnt, I am very sorry for the inconvenience)

@scabug
Copy link
Author

scabug commented Mar 23, 2012

Imported From: https://issues.scala-lang.org/browse/SI-5606?orig=1
Reporter: Jonas Ohlsson (whiteancient)
Affected Versions: 2.9.1

@scabug
Copy link
Author

scabug commented Mar 27, 2012

@adriaanm said:
thanks for reporting! yes, that should give a clean error instead of crashing

@scabug
Copy link
Author

scabug commented Mar 27, 2012

@adriaanm said:
this should give a parse error

@scabug
Copy link
Author

scabug commented Mar 27, 2012

@paulp said:
Interesting what happens when one tries to disallow it. (It's clearly a bug it was allowed - try using a second "wildcard" and it fails.)

[scalacfork] /scratch/trunk1/src/library/scala/collection/immutable/RedBlackTree.scala:88: error: identifier expected but '_' found.
[scalacfork]   def keysIterator[A, _](tree: Tree[A, _]): Iterator[A] = new KeysIterator(tree)
[scalacfork]                       ^
[scalacfork] /scratch/trunk1/src/library/scala/collection/immutable/RedBlackTree.scala:89: error: ']' expected but ';' found.
[scalacfork]   def valuesIterator[_, B](tree: Tree[_, B]): Iterator[B] = new ValuesIterator(tree)
[scalacfork] ^
[scalacfork] /scratch/trunk1/src/library/scala/collection/immutable/RedBlackTree.scala:89: error: identifier expected but '_' found.
[scalacfork]   def valuesIterator[_, B](tree: Tree[_, B]): Iterator[B] = new ValuesIterator(tree)
[scalacfork]                      ^

@scabug
Copy link
Author

scabug commented Mar 29, 2012

@som-snytt said:
This is degenerate, but ought it to be illegal?

In the real world, there are many behaviors that are degenerate but not illegal, or no longer illegal, except in certain states of the Union where they frown on that sort of thing. (For instance, buying beer on Sunday.)

I took a quick look, and the example CaseTest[_] fails in the "copy" method but not in the companion module factory method, which are not exactly the same for some reason. The error is the wildcard in the new expr. (-Xprint:typer shows new pkg.this.CaseTest[_](data) versus new pkg.CaseTest[Any](data).) So this comes close to passing under the radar.

The spec says that the motivation for the shorthand A[_] is visibility and relevance.

One use case for top-level _, in quick test code, is to stub some UserKlass[This, That, Other] as class UserKlass[_,_,_].

I have to come up with symbols? Couldn't the compiler just make me a symbol? So I don't have to remember if we prefer A, B, C or T, U, V? This goes to relevance. And it depletes my decision-making budget.

Another use case is where a type param is deprecated because improvements in type inference make it superfluous.

trait T[@deprecated("I'm free","2.11") _, B <: S[_]]

Then, hypothetically, one could warn on usage of T[X, Y] but not T[_, Y].

Just thinking aloud.

@scabug
Copy link
Author

scabug commented Mar 30, 2012

@paulp said:
It could be allowed to work; my point is that it would be better for it not to work at all than for it to accidentally work for the one-type-parameter case only.

@scabug
Copy link
Author

scabug commented Jan 19, 2013

@retronym said:
The failure mode changed in 2.10.0. In scala/scala#826, the return type of the synthetic copy method was inferred, rather than explicitly provided. If the type parameter is named _, it is inferred as CaseClass[Any].

~/code/scala2 scala210
Welcome to Scala version 2.10.0-20121024-085118-2c554249fd (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_27).
Type in expressions to have them evaluated.
Type :help for more information.

scala> case class CaseTest[_](someData:String)
defined class CaseTest

scala> new CaseTest[Int]("").copy()
res0: CaseTest[Any] = CaseTest()

scala> case class CaseTest[A](someData:String)
defined class CaseTest

scala> new CaseTest[Int]("").copy()
res1: CaseTest[Nothing] = CaseTest()

scala> case class CaseTest[_](someData:String)
defined class CaseTest

scala> new CaseTest[Int]("").copy[Int]()
res2: CaseTest[Any] = CaseTest()

scala> case class CaseTest[A](someData:String)
defined class CaseTest

scala> new CaseTest[Int]("").copy[Int]()
res3: CaseTest[Int] = CaseTest()

scala> case class CaseTest[_](someData:String)
defined class CaseTest

scala> val x = CaseTest[Int]("")
x: CaseTest[Any] = CaseTest()

scala> x.copy
                                               def copy[_](someData: String): CaseTest[Any]  

I figured I'd be able to trip up Value Classes with this, but while we can generate some funny looking signatures, they seem to go unnoticed.

scala> class CCC[_](val value: String) extends AnyVal { def foo[_]: Option[`_`] = None }
...
          final def foo$extension[_ >: Nothing <: Any, _ >: Nothing <: Any]($this: CCC[_]): Option[Any] = scala.None;

That sort of signature comes up without the _, of course, but seems to be innocuous as everything is symful by that stage.

scala> class C[A](val value: String) extends AnyVal { def foo[A] = this }
...
          final def foo$extension[A >: Nothing <: Any, A >: Nothing <: Any]($this: C[A]): C[A] = $this;

@scabug scabug added this to the Backlog milestone Apr 7, 2017
@scala scala deleted a comment from scabug Nov 18, 2018
@scala scala deleted a comment from scabug Nov 18, 2018
@diesalbla
Copy link

diesalbla commented Dec 31, 2018

@SethTisue Since the code in the original example already compiles (so there is no longer a compiler crash) and there already is a pos test case in the compiler, should this still be an open bug?

@som-snytt
Copy link

It doesn't crash, but retronym's copy example is still wrong. Also C[_,_].

@som-snytt
Copy link

The PR emits fresh names for underscore but with deprecation, and error under -Xsource:3 as per Scala 3.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants