asInstanceOf in rewrite rule: exception lost

11 views
Skip to first unread message

Miguel Branco

unread,
Apr 21, 2016, 1:34:08 AM4/21/16
to kiama
Hi all,

I noticed that if one writes a rule whose body contains asInstanceOf, and the call fails - e.g. the asInstanceOf is to a bad/incompatible type - then the rule "fails to apply" but we don't see the program crashing with the exception.

My bet is that the rewrite/rule mechanism is itself catching the same Java exception for some internal use, which means the user code exceptions also get "accidentally" caught. Would be best for this to be re-done, and at least exceptions in the body be thrown up... or it can get very misleading!

Is this an issue anyone else ever faced?

Matt Roberts

unread,
Apr 24, 2016, 2:03:39 AM4/24/16
to ki...@googlegroups.com
Rewrite rules are, in a sense, "built to fail” but “failure” here is quite different to “throw an exception”.

Normally many (possibly failing) rewrite rules are combined to create an overall rule that actually does something.

I suppose the heart of your query is whether a particular exception in a rewrite rule should map to rewrite rule failure or to exception chucking.

Can you provide more detail on this case?  

`asInstanceOf` is the way that pattern matching is implemented in scala, so any pattern match will capture such internal exceptions.  This gives an indication that rules (since they are like pattern matching in some ways) might want to do the same but ….

Well, you at least have me thinking.  Its a long weekend in my part of the world, sit tight while my brain spins up and I will see if I can give you a more useful answer :)

Matt

--
You received this message because you are subscribed to the Google Groups "kiama" group.
To unsubscribe from this group and stop receiving emails from it, send an email to kiama+un...@googlegroups.com.
To post to this group, send email to ki...@googlegroups.com.
Visit this group at https://groups.google.com/group/kiama.
For more options, visit https://groups.google.com/d/optout.

Miguel Branco

unread,
Apr 24, 2016, 1:34:36 PM4/24/16
to ki...@googlegroups.com
Thanks for the reply :)

Here's the scenario: In the rewrite rule I was reading an attribute of
the node I was rewriting, and I knew its output had to be of a certain
type. (To follow the terminology in some of the library examples,
let's say the rewrite rule is doing "analyzer.tipe(n)" where "n" is
the node being rewritten; I was doing
"analyzer.tipe(n).asInstanceOf[CollectionType]" since I knew the type
had to be a collection type and wanted to get that specific object
out.) Or I thought I knew :-) So instead of building a typical scala
pattern match, I just called the attribute and did "asInstanceOf" to
the more specific output type that I was expecting. Turns out I made a
mistake, and instead of seeing an exception being thrown at me in the
middle of the rule executng, the rewrite rule was simply not applying.
This was... well... long to debug, because for the life of me I
couldn't understand why the rule didn't seem to apply; I expected it
to apply then just crash the code.

Tony Sloane

unread,
Apr 25, 2016, 7:53:42 PM4/25/16
to ki...@googlegroups.com
Hi Miguel,

I can confirm that the ClassCastException is being caught by Kiama in this case. The reason that we do this is to trap cases where a rewrite rule defined on a type T is applied to something that isn’t a T. As Matt mentioned, the rewrite rule semantics turn this situation into a rule failure. E..g, if you have

val r = rule[T] { case … }
val v : V = …

where V is not a sub-type of T, then calling r(v) fails (returns None). This kind of failure is important in generic traversals because it allows rules that operate at different types to be combined in a flexible way since the failure of one can cause the execution of another one.

As you’ve observed, this approach causes all ClassCastExceptions in rules to get caught by Kiama. As far as I can see, there is no way to tell a “rule was applied to the wrong type” exception from one that occurs due to another reason. Both exceptions occur in user code so we can’t distinguish them by location. If you have any suggestions for reliably making this distinction it would be great to hear them.

Note that ClassCastExceptions are the only exceptions that are currently trapped by Kiama. Converting the other exceptions to rule failure would also be possible but would be unexpected by Scala programmers, I think.

To consider your situation more explicitly, I would be pattern matching on the return value of “analyser.tipe(n)” to make sure that I am getting the collection type I expect. In my view, it’s best to code defensively and raise a custom error if something goes wrong rather than to rely on raising a generic error via a failing cast.

cheers,
Tony
Reply all
Reply to author
Forward
0 new messages