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

SI-5353 unsound Array lubs. #2466

Closed
wants to merge 1 commit into from
Closed

SI-5353 unsound Array lubs. #2466

wants to merge 1 commit into from

Conversation

paulp
Copy link
Contributor

@paulp paulp commented Apr 28, 2013

mergePrefixAndArgs tried too hard to finesse the Array lub. When
there is more than one distinct Array element type being lubbed,
abandon the attempt to erase to any common Array type, because the
storage must match all the element types and Nothing will always
break this. Simply erase to AnyRef.

@paulp
Copy link
Contributor Author

paulp commented Apr 28, 2013

Opened against master because I'm not sure about the implications for compatibility. Inferring different lubs can lead to different method descriptors.

@paulp
Copy link
Contributor Author

paulp commented Apr 28, 2013

Review by @xeno-by, @retronym

@xeno-by
Copy link
Contributor

xeno-by commented Apr 28, 2013

Could you please comment on why the fix should target lub, but not Erasure (in unboundedGenericArrayLevel)? It seems useful to have lubs as precise as possible and downgrade to Objects only when necessary. This probably has some implications wrt type inference, which know almost nothing about, so I'm sorry if the question is being stupid.

@paulp
Copy link
Contributor Author

paulp commented Apr 28, 2013

It's possible you're right. I was already writing a mail asking about why Types knows anything about erasure at all. But the primary reason I pursued that location is that mergePrefixAndArgs is already intervening attempting to avoid exactly this problem.

@paulp
Copy link
Contributor Author

paulp commented Apr 28, 2013

But what is the case you have in mind where this commit leads to a less precise lub than is warranted?

@xeno-by
Copy link
Contributor

xeno-by commented Apr 28, 2013

No particular case, just trying to figure out how this should work. I don't know much about advanced type machinery.

@xeno-by
Copy link
Contributor

xeno-by commented Apr 28, 2013

Well, it could matter for macros of all sorts, including type tag materialization, but since the change only affects erasure, it doesn't matter.

@paulp
Copy link
Contributor Author

paulp commented Apr 28, 2013

You're right at least that this is insufficient; I can still induce CCEs.

@xeno-by
Copy link
Contributor

xeno-by commented Apr 28, 2013

Yeah, same here. E.g. see files/run/t5353.scala

@paulp
Copy link
Contributor Author

paulp commented Apr 28, 2013

How about now.

@xeno-by
Copy link
Contributor

xeno-by commented Apr 28, 2013

object Test extends App {
  def f(x: Boolean) = if (x) Array("abc") else Array()
  println(f(false).length)
}
uncaught exception during compilation: RuntimeException("scala.Array.length : Object, Object, Any") @ scala.sys.package$.error(package.scala:27)
error: java.lang.RuntimeException: scala.Array.length : Object, Object, Any
    at scala.sys.package$.error(package.scala:27)
    at scala.tools.nsc.backend.ScalaPrimitives$$anonfun$elementType$1$1$$anonfun$apply$1.apply(ScalaPrimitives.scala:571)
    at scala.tools.nsc.backend.ScalaPrimitives$$anonfun$elementType$1$1$$anonfun$apply$1.apply(ScalaPrimitives.scala:571)
    at scala.Option.getOrElse(Option.scala:120)
    at scala.tools.nsc.backend.ScalaPrimitives$$anonfun$elementType$1$1.apply(ScalaPrimitives.scala:571)
    at scala.tools.nsc.backend.ScalaPrimitives$$anonfun$elementType$1$1.apply(ScalaPrimitives.scala:567)
    at scala.reflect.internal.SymbolTable.enteringPhase(SymbolTable.scala:214)
    at scala.tools.nsc.Global.enteringTyper(Global.scala:1056)
    at scala.tools.nsc.backend.ScalaPrimitives.elementType$1(ScalaPrimitives.scala:567)
    at scala.tools.nsc.backend.ScalaPrimitives.getPrimitive(ScalaPrimitives.scala:607)
    at scala.tools.nsc.backend.icode.GenICode$ICodePhase.genPrimitiveOp(GenICode.scala:428)

@xeno-by
Copy link
Contributor

xeno-by commented Apr 28, 2013

Looks like the change has to be applied to unboundedGenericArrayLevel as that function is used elsewhere.

@paulp
Copy link
Contributor Author

paulp commented Apr 28, 2013

So I am discovering.

Attempt 1 was:

  mergePrefixAndArgs tried too hard to finesse the Array lub. When
  there is more than one distinct Array element type being lubbed,
  abandon the attempt to erase to any common Array type, because the
  storage must match all the element types and Nothing will always
  break this. Simply erase to AnyRef.

Attempt 2 was:

  The previous fix, while possibly still appropriate, did not
  suffice to fight off Nothing-based array lubs. Took eugene's
  advaice and went after them in erasure.

I can maybe remove Attempt 1.
@paulp
Copy link
Contributor Author

paulp commented Apr 28, 2013

Now it's definitely overly broad, but at least maybe it will work. I'll refine it.

case TypeRef(pre, ArrayClass, arg :: Nil) =>
if (unboundedGenericArrayLevel(tp) == 1) ObjectTpe
else if (arg.typeSymbol.isBottomClass) ObjectArray
else typeRef(apply(pre), ArrayClass, applyInArray(arg) :: Nil)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like this change can be dropped now?

@paulp
Copy link
Contributor Author

paulp commented Apr 28, 2013

Well this is interestingly brutal to get right. Closing for now, will have to revisit.

@paulp paulp closed this Apr 28, 2013
retronym pushed a commit to retronym/scala that referenced this pull request Jun 24, 2019
The subsequent fix to SI-5923 unmasks the fact that SI-5353 has not
been fixed - it's just that one of its manifestation got hidden behing
SI-5923. In fact, if in the code snippet from the bug report we change
Array() to Array[Nothing](), things will start crashing as usual.

Therefore in this pull request, which is dedicated to SI-5923,
I have to disable files/neg/t5353.scala, leaving its fix to a
separate patch. See a discussion about a potential fix here:
scala#2466.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants