-
Notifications
You must be signed in to change notification settings - Fork 21
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
Another for-comprehension refutability regression #6968
Comments
Imported From: https://issues.scala-lang.org/browse/SI-6968?orig=1 |
@retronym said: |
@retronym said: |
Robert Gibson (rgibson) said: |
@retronym said: It suffers from two problems: case Apply(
Select(qual, nme.filter | nme.withFilter),
List(Function(
List(ValDef(_, pname, tpt, _)),
Match(_, CaseDef(pat1, _, _) :: _))))
if ((pname startsWith nme.CHECK_IF_REFUTABLE_STRING) &&
isIrrefutable(pat1, tpt.tpe) && (qual.tpe <:< tree.tpe)) =>
transform(qual) It doesn't handle TypeApply, the sort of problem that is now easily solved with treeInfo.Applied. |
@retronym said: |
@retronym said:
class Option[+A] { self =>
class WithFilter(p: A => Boolean) {
private val isConstant = p.isInstanceOf[ConstantFunction]
def map[B](f: A => B): Option[B] = if (isConstant) self map f else self filter p map f
...
}
}
for ((x, y) <- null: Option[(Int, Int)]) yield x
scala> val n = Some(null): Option[(Int, Int)]
n: Option[(Int, Int)] = Some(null)
scala> for (Tuple2(x, y) <- n) yield x
scala.MatchError: null
at $anonfun$1.apply(<console>:9)
at $anonfun$1.apply(<console>:9)
at scala.Option.map(Option.scala:145)
scala> n withFilter { case (x, y) => true; case _ => false } map { case (x, y) => x }
res4: Option[Int] = None
// if refutability checking worked as originally intended, and the `withFilter` was elided.
// will throw a NPE
scala> n map { case (x, y) => x }
scala.MatchError: null
// Tentative proposal: the predicate should admit null.
scala> n withFilter { case (x, y) => true; case null =>; case _ => false } map { case (x, y) => x } |
@paulp said: At the time I was pursuing unnecessary allocations of Function1 (especially for _ => true and _ => false) but there are more uses, as you see. final class Predicate[@specialized T](val f: T => Boolean, val isFlipped: Boolean) extends (T => Boolean)
...
fun match {
// Rewrite _ => true and _ => false to reuse preallocated constant predicates
case Function(vparam :: Nil, Literal(Constant(v: Boolean))) =>
enterSym(context, vparam)
if (context.retyping) context.scope enter vparam.symbol
val formal = typedValDef(vparam).symbol.tpe
val funtpe = appliedType(clazz, formal, BooleanClass.tpe)
val predicate = termMember(FunctionModule, "Predicate" + v.toString.capitalize)
typed(gen.mkNullaryCall(predicate, formal :: Nil), funtpe) |
@odersky said: for (x <- xs) yield x * x requires more code than xs map (x => x * x) An alternative would be to embed redundancy checking and elimination in the pattern matcher. Also agreed that null needs to be speced to be part of the filter. |
@adriaanm said: |
@retronym said: |
No call to
withFilter
is generated.The text was updated successfully, but these errors were encountered: