-
Notifications
You must be signed in to change notification settings - Fork 3.1k
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
Conversation
Opened against master because I'm not sure about the implications for compatibility. Inferring different lubs can lead to different method descriptors. |
Could you please comment on why the fix should target |
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. |
But what is the case you have in mind where this commit leads to a less precise lub than is warranted? |
No particular case, just trying to figure out how this should work. I don't know much about advanced type machinery. |
Well, it could matter for macros of all sorts, including type tag materialization, but since the change only affects erasure, it doesn't matter. |
You're right at least that this is insufficient; I can still induce CCEs. |
Yeah, same here. E.g. see |
How about now. |
|
Looks like the change has to be applied to |
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.
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) |
There was a problem hiding this comment.
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?
Well this is interestingly brutal to get right. Closing for now, will have to revisit. |
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.
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.