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
Scalac crashes when I use @elidable for trait #5215
Comments
Imported From: https://issues.scala-lang.org/browse/SI-5215?orig=1 |
@khernyo said: So, I think it should be fixed by reporting an error if a non-final method is annotated with @elidable. Or maybe a warning for now and turn it into an error in a later release. Any thoughts? |
@Atry said (edited on Feb 18, 2012 3:27:32 AM UTC): |
@khernyo said: val b = new B
b.xx()
(b:A).xx() So, I'm still in favor of "@elidable should be applicable only to final methods". Well, this also has a problem when B.xx() has the annotation and A.xx() does not. I will look into it later. |
@paulp said: |
@som-snytt said: $ spalac -version
Scala compiler version v2.10.0-M1-378-g63d9ae6dc4 -- Copyright 2002-2011, LAMP/EPFL
$ spala elysian.ElysianFields
java.lang.VerifyError: (class: elysian/ElysianFields, method: greeting signature: ()Ljava/lang/String;) Unable to pop operand off an empty stack This is related to #5051. The old transform would turn the expr into a BoxedUnit, which is something. |
@khernyo said: |
@paulp said: |
@khernyo said: |
@som-snytt said: var c: Char = _ This is not a use case, but should this print null or complain? val junk: Nothing = elided()
println("Well, "+ junk) If it doesn't complain, should the inserted code throw an exception? ElidedToNothingException? As an aside (or stage whisper), I had expected elision in these contexts to be an error ("or at least a warning," as we say), but now I agree that the "default value" behavior could be useful, perhaps to supply special default values during development. |
@paulp said: scala> var c: Char = _
c: Char = ?
scala> c == '\0'
res0: Boolean = true |
@khernyo said: I simply don't have a use case in mind where you would want to use the result of an elidable call other than printing it. If you are printing it, then a '\0' somewhere along the way will get treated as the terminator in a null terminated string. So, you might cut off some more important information. Also, it could be harder to find the reason for a shorter-than-usual string than for a '?' (e.g. if the @elidable annotation was left there unintentionally). |
@paulp said: |
@khernyo said: |
@som-snytt said: I think that assigning in the context of Nothing has to result in an error. In particular, eliding the call (and continuing execution) breaks the guarantee that you don't return. Adding this check if (expectedType.isNothingType) unit.error(tree.pos, "Cannot elide where Nothing is required.") results in $ spalac -Xelide-below 1000 elysian.scala
elysian.scala:18: error: Cannot elide where Nothing is required.
val junk: Nothing = elided()
^ Also, I think the isInstanceOf test is covered by the method: //expectedType.isInstanceOf[ValueTypeKind]
generatedType = if (expectedType.isValueType) expectedType else NullReference For a use case for using the result of an elidable: in development, there's often a "mode" flag for testing, that might affect not only logging but feature behavior, perhaps stubbing or mocking expensive operations, or features that aren't implemented yet. var icon: Char = TestDefaults.icon
if (icon == 0) icon = '@'
object TestDefaults {
@elidable(-100) def icon: Char = 't'
} In this scenario, elision level < 0 means features may be stubbed or disabled. A milestone release might require elision at 1000, with logging disabled. I don't work this way, but maybe I would if I could. |
@khernyo said: Paul has already cleaned up the code in commit fbb7865e137e83660257fdc79d19d29ff39c775b. This includes changing expectedType.isInstanceOf[ValueTypeKind] into expectedType.isValueType |
@som-snytt said: I don't have any knowledge of the code base, so I don't know whether more work is needed for the error case. (I'll admit to second thoughts whether the elision should just result in ElidedToNothingException. Or, analogous to NotImplementedError, call it NoLongerImplementedError...) |
@paulp said: |
@paulp said: |
@paulp said: |
@som-snytt said: def ??! : Nothing = throw new NoLongerImplementedError into Predef. And yet there is a certain symmetry: def yagni = ???
def yagni = feature()
@deprecated("Useless","1.0") def yagni = feature()
@deprecated("Useless","1.0") def yagni = ??! |
@paulp said: |
@khernyo said: I opened a pull request (scala/scala#233) to update the docs for @elided to better match the reality. I consider this issue closable when this commit is merged. |
Compile following code with
-Xelide-below OFF
and then Scalac crashed.If I change
trait A
toabstract class A
, it's OK.The text was updated successfully, but these errors were encountered: