(new Iterator[List[Int]] {
def hasNext: Boolean = ???
def next(): List[Int] = ???
}).flatten
gives error:
value flatten is not a member of Iterator[List[Int]]
[error] possible cause: maybe a semicolon is missing before `value flatten'?
[error] }.flatten
[error] ^
[error] one error found
But
(new Iterator[List[Int]] {
def hasNext: Boolean = ???
def next(): List[Int] = ???
}: Iterator[List[Int]]).flatten
works. Also storing the iterator in a val works.
Scala version: 2.11.8
I believe this issue was addressed by Include the parts of a compound/refinement type in implicit scope. #5867. The problem was companion to anonymous classes used to not qualify for implicit search
I think aaf9198#diff-7c03397456d3b987549fd039d6b639c6R516 was the first to exclude refinement/anon classes from contributing to companion implicits. @odersky Can you remember the motivation?
Here is a minimal reproduction
trait A {
def foo(): Int
}
class B {
def bar(): String = "woohoo"
}
object A {
implicit def aToB(a: A): B = new B
}
(new A {
override def foo(): Int = 42
}).bar()
// Error:
// value bar is not a member of A$A12.this.A
// possible cause: maybe a semicolon is missing before `value bar'? }).bar();
Therefore since in 2.11 and 2.12 flatten
on Iterator
was provided as an extension method via flattenTraversableOnce the issue would manifest for anonymous Iterator
class.
The following is my answer prior to the edit above:
It seems to have something to do with implicit resolution in both 2.11 and 2.12. If you explicitly import flatten
as an extension method via
import scala.collection.TraversableOnce.flattenTraversableOnce
then it seems to work. The issue seems to be fixed since 2.13.0-M3 where typer phase gives
collection.this.TraversableOnce.flattenTraversableOnce[Int, List]({
final class $anon extends AnyRef with Iterator[List[Int]] {
def <init>(): <$anon: Iterator[List[Int]]> = {
$anon.super.<init>();
()
};
def hasNext: Boolean = scala.Predef.???;
def next(): List[Int] = scala.Predef.???
};
new $anon()
})(scala.Predef.$conforms[List[Int]]).flatten
whilst in 2.13.0 release flatten
no longer seem to be provided via extension method
{
final class $anon extends AnyRef with Iterator[List[Int]] {
def <init>(): <$anon: Iterator[List[Int]]> = {
$anon.super.<init>();
()
};
def hasNext: Boolean = scala.Predef.???;
def next(): List[Int] = scala.Predef.???
};
new $anon()
}.flatten[Int](scala.Predef.$conforms[List[Int]])
The above expansion seems to be explained by SLS 6.4 Designators
𝑒.𝑥 is typed as if it was { val 𝑦 = 𝑒; 𝑦.𝑥 }
I think it tries to parse this:
new Iterator[List[Int]] {
def hasNext: Boolean = ???
def next(): List[Int] = ???
}.flatten
as this
new Iterator[List[Int]] ( {
def hasNext: Boolean = ???
def next(): List[Int] = ???
}.flatten )
Notice where I added the parentheses ()
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With