@@ -122,33 +122,40 @@ object SeqView {
122122 }
123123
124124 @ SerialVersionUID (3L )
125- class Sorted [A , B >: A ](private [this ] var underlying : SomeSeqOps [A ], ord : Ordering [B ]) extends SeqView [A ] {
125+ class Sorted [A , B >: A ] private (private [this ] var underlying : SomeSeqOps [A ],
126+ private [this ] val len : Int ,
127+ ord : Ordering [B ])
128+ extends SeqView [A ] {
126129 outer =>
127130
131+ // force evaluation immediately by calling `length` so infinite collections
132+ // hang on `sorted`/`sortWith`/`sortBy` rather than on arbitrary method calls
133+ def this (underlying : SomeSeqOps [A ], ord : Ordering [B ]) = this (underlying, underlying.length, ord)
134+
128135 @ SerialVersionUID (3L )
129136 private [this ] class ReverseSorted extends SeqView [A ] {
130137 private [this ] lazy val _reversed = new SeqView .Reverse (_sorted)
131138
132139 def apply (i : Int ): A = _reversed.apply(i)
133- def length : Int = elems.length
140+ def length : Int = len
134141 def iterator : Iterator [A ] = Iterator .empty ++ _reversed.iterator // very lazy
135- override def knownSize : Int = elems.knownSize
136- override def isEmpty : Boolean = elems.isEmpty
142+ override def knownSize : Int = len
143+ override def isEmpty : Boolean = len == 0
137144 override def to [C1 ](factory : Factory [A , C1 ]): C1 = _reversed.to(factory)
138145 override def reverse : SeqView [A ] = outer
139146 override protected def reversed : Iterable [A ] = outer
140147
141148 override def sorted [B1 >: A ](implicit ord1 : Ordering [B1 ]): SeqView [A ] =
142149 if (ord1 == Sorted .this .ord) outer
143150 else if (ord1.isReverseOf(Sorted .this .ord)) this
144- else new Sorted (elems, ord1)
151+ else new Sorted (elems, len, ord1)
145152 }
146153
147154 @ volatile private [this ] var evaluated = false
148155
149156 private [this ] lazy val _sorted : Seq [A ] = {
150157 val res = {
151- val len = underlying.length
158+ val len = this .len
152159 if (len == 0 ) Nil
153160 else if (len == 1 ) List (underlying.head)
154161 else {
@@ -177,10 +184,10 @@ object SeqView {
177184 }
178185
179186 def apply (i : Int ): A = _sorted.apply(i)
180- def length : Int = elems.length
187+ def length : Int = len
181188 def iterator : Iterator [A ] = Iterator .empty ++ _sorted.iterator // very lazy
182- override def knownSize : Int = elems.knownSize
183- override def isEmpty : Boolean = elems.isEmpty
189+ override def knownSize : Int = len
190+ override def isEmpty : Boolean = len == 0
184191 override def to [C1 ](factory : Factory [A , C1 ]): C1 = _sorted.to(factory)
185192 override def reverse : SeqView [A ] = new ReverseSorted
186193 // we know `_sorted` is either tiny or has efficient random access,
@@ -190,7 +197,7 @@ object SeqView {
190197 override def sorted [B1 >: A ](implicit ord1 : Ordering [B1 ]): SeqView [A ] =
191198 if (ord1 == this .ord) this
192199 else if (ord1.isReverseOf(this .ord)) reverse
193- else new Sorted (elems, ord1)
200+ else new Sorted (elems, len, ord1)
194201 }
195202}
196203
0 commit comments